来自docs:
$?
比目标更新的所有先决条件的名称, 它们之间有空格。
所以,给定一个makefile:
# Force make to search for 'foo' in the VPATH directory
$(shell rm -rf foo)
# If 'D' is a "regular" file, we remove it first.
$(shell rm -rf D)
$(shell mkdir D)
# Suggest a VPATH-file, for Make to "associate" with 'foo'.
$(shell touch D/foo)
$(shell sleep 1)
# Target 'all' is newer than prerequisite 'D/foo'
$(shell touch all)
VPATH = D
all : foo phony
echo '$?'
foo ::
touch '$@'
.PHONY: phony
.PRECIOUS : D/foo
然后跑步,我得到:
$ make -r
touch 'D/foo'
echo 'D/foo phony'
D/foo phony
# Try again, but this time, with parallel-execution mode.
$ make -r -j
touch 'D/foo'
echo 'phony'
phony
在这里,我们有两个严重的问题:
foo
,明确执行 - 因此保证 foo
将是"更新"比all
- 仍然不将$?
扩展为D/foo
,至少在上面的第二种情况下(即 parallel - 执行(-j
)模式)。为什么?$?
- 确实 - 扩展到D/foo
。
那么,对于这两种情况,$?
变量是否应该相同地扩展?
答案 0 :(得分:0)
我认为这里有两个问题。
首先,双冒号规则似乎像虚假的目标,因为它们迫使make将目标视为“更新”而不管实际的修改时间。 (这就是非并行版本的行为方式。从foo ::
更改为foo :
并且foo
输出中根本没有$?
。 )
第二件事是,尽管如此,使用并行模式似乎迫使重新考虑其先决条件的修改时间(因此避免了先前的行为)。
这是猜想而不是决定因素,因为我没有挖掘代码来查看这是否真的发生了但是它解释了这里的结果(它也解释了另一个结果,几乎相同,问题here )。