示例:假设我有bar.c
和baz.c
,我想生成foo.a
。所以:
foo.a: bar.o baz.o
ar -rc $@ $?
现在我决定总是希望bar.o
更新。我决定把它作为一个假的目标。这也需要明确的配方,因为隐式规则不会被搜索到Phony目标。所以:
.PHONY: bar.o
bar.o: bar.c
cc -c -o $@ $<
foo.a: bar.o baz.o
ar -rc $@ $?
现在,当我运行make foo.a
时,bar.c
总是被编译。自bar.o
更新后,foo.a
的配方始终会运行。
但是:$?
的值为空,因此foo.a
不会被修改。为什么呢?
答案 0 :(得分:1)
好问题。我不确定,但我怀疑这是因为虚假的目标恰恰是那个&#34;假的&#34; as-in明确期望不来表示文件,因此将它们放在比目标更新的先决条件列表中并没有真正有意义。
如果你想保持这种行为但是要正确处理事情你想要避免一个.PHONY
目标,而是使用forced target。
如果规则没有先决条件或配方,并且规则的目标是不存在的文件,那么无论何时运行规则,都要想象该目标已经更新。这意味着所有依赖于此目标的目标将始终运行其配方。
一个例子将说明这一点:
clean: FORCE rm $(objects) FORCE:
这里目标'FORCE'满足特殊条件,因此依赖于它的目标清理被强制运行其配方。 “FORCE”这个名称并没有什么特别之处,但这是一种常用的名称。
正如您所看到的,使用'FORCE'这种方式与使用'.PHONY:clean'的结果相同。
使用'.PHONY'更明确,更有效。但是,其他版本的make不支持'.PHONY';因此'FORCE'出现在许多makefile中。参见Phony Targets。