Make:具有依赖关系的意外行为并包含语句

Make: Unexpected Behavior with Dependencies and include Statement

我有以下 Makefile:

a.d:
    gcc -m32 -MM -o $@ a.c
    sed 's!a.o!$@ a.o!' --in-place $@

a.o:
    gcc -c -m32 -o $@ a.c

all: a.d a.o

-include a.d

a.d的内容是:

a.d a.o: a.c a.h

我有 2 个问题。 1、在运行ning "make all" if I 运行:

之后
touch a.h
make a.d

我看到了这个:

gcc -m32 -MM -o a.d a.c
sed 's!a.o!a.d a.o!' --in-place a.d
make: 'a.d' is up to date.

明明a.d规则运行,为什么我看到"make: 'a.d' is up to date."?

2、运行宁"make all"之后我运行这个:

touch a.h
make a.o

我看到了这个:

gcc -m32 -MM -o a.d a.c
sed 's!a.o!a.d a.o!' --in-place a.d
gcc -c -m32 -o a.o a.c

为什么它也 运行 a.d 规则?没有依赖关系。

真正不明白的是,当我在make文件中将“-include a.d”替换为a.d的内容时,例如:

#-include a.d
a.d a.o: a.c a.h

我没有发现任何问题。 include 语句不应该使包含文件直接包含在同一个 make 文件中吗?

这是我的 a.h 的样子:

#define FOO 0

这是a.c:

#include <stdio.h>
#include "a.h"

void foo(void)
{
    printf("foo %d", FOO);
}

我使用的是 Cygwin 64 位。这是 make -v:

的输出
$ make -v
GNU Make 4.1
Built for x86_64-unknown-cygwin
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

GNU make 尝试重建包含的 makefile 可以解释您的两种行为;参见 How Makefiles are Remade。因此,在您的第一个问题中,第一个输出来自 make 尝试重建 a.d 文件,第二个输出来自 make re-execs 本身;它看到目标 a.d 是最新的。

在你的第二个问题中,它运行 a.d 规则,因为 a.d 依赖于 a.h 并且由于你包含 a.d,make 会尝试重建它。

关于你的最后一个问题,如果你直接嵌入内容,它不会发生的原因是你没有使用 include

其他值得阅读的有趣内容是:Generating Prerequisites Automatically and Advanced Auto-Dependency Generation. Also maybe Constructed Include Files 了解更多背景知识。