为什么不要将假的先决条件出现在`$?`中?

时间:2015-11-25 17:15:22

标签: makefile gnu-make toolchain ar

示例:假设我有bar.cbaz.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不会被修改。为什么呢?

1 个答案:

答案 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。