当PHONY依赖项更新时,为什么make不考虑没有过期配方的目标


.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"更改是否正确?

Make无法分析命令的效果,因此正确组织规则是用户的责任。

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

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

这与您的示例具有相同的行为;Make不可能知道CCD_ 1"真的"依赖于CCD_ 2。makefile的作者有错。

现在应该这样写:

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

a规则修改文件a(而PHONY只是为了强制运行a规则)。这是告诉make@date ...命令修改a的方法。此生成文件工作正常。

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

最新更新