为什么在PHONY依赖项更新时不考虑没有配方过时的目标?

时间:2012-10-04 09:22:54

标签: makefile gnu-make

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

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

将带有“a”作为目标的规则更改为空配方会导致每次运行时都会打印“已更改”(正如您所期望的那样 - 虚假目标始终被视为“过时”)。 E.g。

a: b ;

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

1 个答案:

答案 0 :(得分: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是那种偏执狂,那就不会很有效率了。