Makefile 为什么不';虚假的先决条件是否出现在“$?”中?

Makefile 为什么不';虚假的先决条件是否出现在“$?”中?,makefile,gnu-make,toolchain,unix-ar,Makefile,Gnu Make,Toolchain,Unix Ar,例如:假设我有一个bar.c和baz.c,我想生产foo.a。因此: foo.a: bar.o baz.o ar -rc $@ $? 现在我决定我总是想更新bar.o。我决定把它变成一个虚假的目标。这也需要一个明确的方法,因为隐式规则不会被搜索到虚假的目标。因此: .PHONY: bar.o bar.o: bar.c cc -c -o $@ $< foo.a: bar.o baz.o ar -rc $@ $? .PHONY:bar.o 酒吧o:bar.c cc

例如:假设我有一个
bar.c
baz.c
,我想生产
foo.a
。因此:

foo.a: bar.o baz.o
    ar -rc $@ $?
现在我决定我总是想更新
bar.o
。我决定把它变成一个虚假的目标。这也需要一个明确的方法,因为隐式规则不会被搜索到虚假的目标。因此:

.PHONY: bar.o
bar.o: bar.c
    cc -c -o $@ $<

foo.a: bar.o baz.o
    ar -rc $@ $?
.PHONY:bar.o
酒吧o:bar.c
cc-c-o$@$<
foo.a:酒吧,baz.o
ar-rc$@$?
现在,当我运行
makefoo.a
时,
bar.c
总是被编译。由于
bar.o
得到更新,
foo.a
的配方始终得到运行


但是
$?
有一个空值,因此不会修改
foo.a
。为什么?好问题。我不确定是否准确,但我怀疑这是因为虚假目标正是“虚假”的,因为它们被明确期望而不是来表示文件,因此将它们放在比目标更新的先决条件列表中并没有多大意义

这就是说,如果你想保持这种行为,但正确地处理事情,你要避免一个
.PHONY
目标,而是使用一个

如果规则没有先决条件或配方,并且规则的目标是不存在的文件,则make会想象该目标在其规则运行时已更新。这意味着依赖于此目标的所有目标将始终运行其配方

举例说明:

clean: FORCE
    rm $(objects)
FORCE:
在这里,目标“力”满足特殊条件,因此依赖于它的目标清洁被强制运行其配方。“FORCE”这个名字没有什么特别之处,但这是一个常用的名字

如您所见,以这种方式使用“FORCE”与使用“.PHONY:clean”具有相同的结果

使用“.PHONY”更明确、更有效。但是,make的其他版本不支持“.PHONY”;因此,“FORCE”出现在许多makefile中。见假目标


好的,谢谢。值得注意的是,虚假目标确实出现在
$^
中,这让我觉得不一致。是和否。它们是先决条件,但它们(实际上)并不比目标更新。所以它确实有一些道理,但我同意这有点奇怪。make显然不允许这样做,但手册确实说“虚假目标不应该是真实目标文件的先决条件”。因为总是执行虚假目标,所以在内部它们被认为总是比其他任何东西都旧,这是有道理的。@user657267 always executed会比older更容易映射到更新的,因为配方通常会在运行时更新其目标。也就是说,“不应该”是因为列出虚假先决条件的目标本身将始终运行,因为虚假目标将被视为较新的目标。@EtanReisner你说得对,我的时代被搞糊涂了。也许内部虚假文件有一个特殊的日期值,既不新也不旧。