$的make不一致的扩展多变的 [英] Inconsistent expansion by make for the '$?' variable
问题描述
来自文档:
$?
比目标更新的所有先决条件的名称, 它们之间有空格.
$?
The names of all the prerequisites that are newer than the target, with spaces between them.
因此,给了一个makefile:
So, given a 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
运行,我得到:
And running, I get:
$ 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
在这里,我们有2个严重的问题:
Here, we have 2 serious issues:
- 给出简单且显式的配方来触摸" make明确执行的先决条件
foo
-因此将保证保证foo
将是较新的"比all
-使不仍然将$?
扩展为D/foo
,至少在上述第二种情况下(即对于 parallel 执行()模式).为什么? - 如果您对上述内容有一个解释,它是否也应该解释一下,为什么在第一种情况下( non-parallel 执行),
$?
-可以做到实际上-扩展到D/foo
.
我猜,我有一个假设,除了 parallel 与 non-parallel ,Make在执行目标之前会始终暂停,然后首先检查其所有先决条件是否已经完成各自的构建.
- Given the simple and explicit recipe to "touch" the prerequisite
foo
, which Make clearly executes - hence will guarantee thatfoo
will be "newer" thanall
- Make still does not expand$?
toD/foo
, at-least in the 2nd case above (i.e. for the parallel-execution (-j
) mode). Why? - If you come up with an explanation for the above, shouldn't it also explain, why in the 1st case (non-parallel execution),
$?
- does indeed - get expanded toD/foo
.
I guess, I had an assumption, that parallel vs. non-parallel aside, Make will always pause before executing a target, and first check if all of its prerequisites had already finished their respective builds.
因此,在两种情况下$?
变量是否都应扩展相同?
So, shouldn't the $?
variable be identically expanded for both cases?
推荐答案
我认为这里有两个问题.
I think there are two issues going on here.
首先,双冒号规则看起来像假冒目标,因为它们强迫使目标视为较新的",而不管实际的修改时间如何. (这就是为什么非并行版本的行为方式如此的原因.从foo ::
更改为foo :
,并且在$?
输出中根本没有得到foo
.)
The first is that double-colon rules appear to act like phony targets in that they force make to consider the target as "newer" regardless of actual modification time. (This is why the non-parallel version behaves the way it does. Change from foo ::
to foo :
and you don't get foo
in the $?
output at all.)
第二件事是,尽管如此,使用并行模式似乎迫使人们重新考虑其先决条件的修改时间(因此避免了先前的行为).
The second thing is that, despite that, using parallel mode seems to force make back into considering modification times of its prerequisites (so the previous behavior is avoided).
这是推测,而不是确定的,因为我没有仔细研究代码来查看这是否真的发生,但是它解释了这里的结果(它也解释了另一个几乎相同的问题
This is conjecture and not definitive since I haven't dug through the code to see if this is actually happening but it explains the results here (it also explains the results on the other, nearly identical, question here).
这篇关于$的make不一致的扩展多变的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!