5
.PHONY: b
c: a
    @touch c
    @echo "Changed"
a: b
b:
    @date +%s > a

使用示例 make 文件运行 make 会导致在第一次运行时打印“Changed”;但“已更改”仅在第 3 次、第 5 次等执行时打印。这是因为 make 似乎没有认识到执行目标“b”的配方会更新 a。

将“a”作为目标的规则更改为空配方会导致每次运行 make 时都会打印“Changed”(如您所料 - 虚假目标始终被视为“过时”)。例如

a: b ;

Make 应该跳过 PHONY 目标的隐式规则搜索,但“a”不是 PHONY。如果没有为“a”找到隐含规则,是否正确不考虑“a”可能已被其 PHONY 依赖项“b”更改?

4

1 回答 1

2

Make不能分析命令的效果,所以正确组织规则是用户的责任。

考虑一个稍微不同的情况:

d: c b
c: a
    @touch c
    @echo "Changed"
a:
b:
    @date +%s > a

这与您的示例具有相同的行为;不可能期望 Make 知道c“真的”取决于b. makefile 的作者有错。

现在应该这样写:

c: a
        @touch c
        @echo "Changed"

.PHONY: a
a:
        @date +%s > a

a规则修改文件a(并且PHONY只是为了强制a规则运行)。这是告诉 make@date ...命令修改的方法a。这个 makefile 可以正常工作。

您的示例介于这两者之间。如果一条规则修改了另一个规则的目标文件,则 makefile 组织不良,而 Make 没有错。是的,Make 可以假设依赖于PHONY规则的目标可能在该规则运行时已更新,但它也可以假设任何目标可能在任何规则运行时已更新。如果 Make 是那种偏执狂,那它的效率就不会很高。

于 2012-10-04T13:29:31.860 回答