【发布时间】:2015-08-20 09:37:50
【问题描述】:
来自docs:
$?
比目标更新的所有先决条件的名称, 它们之间有空格。
现在,给定一个 makefile:
# Create target 'all', that is created later than 'old', which was created after 'older'.
$(shell touch older)
$(shell sleep 1)
$(shell touch old)
$(shell sleep 1)
$(shell touch all)
all : old phony;
@echo '"$$?" is: "$?"'
# A command to turn the file 'old' even "older", by acquiring the modification-time of 'older'.
old ::
cp -p 'older' 'old'
.PHONY: phony
跑步,我明白了:
$ make
cp -p 'older' 'old'
"$?" is: "old phony"
# Trying again, but this time, with a *parallel-execution*.
$ make -j
cp -p 'older' 'old'
"$?" is: "phony"
*你看,对于 并行执行 (-j),Make 扩展 $? 的值与 em>非并行执行?*
我们先分析第一种情况,即非并行执行。
all和old的修改时间为:
-
在构建之前,
old比all“旧”。这是不言而喻的。对吧? -
Make 构建完前提条件后,即 Make "builds"
old,oldgot "older" 之后,可以说是通过“获取”修改时间一个名为:older的文件。这基本上是 shell 命令的最终结果:cp -p older old。现在,不难看出,older比all“老”方式。
现在,由于 other 先决条件,Make 最终构建了目标 all,即:phony。
但是,根据文档,$? 应该只扩展为“比目标更新的所有先决条件的名称”。这是一个准确的引用。
我们是否可以同意,old从未更新比all。而且,如果不是 phony,Make 甚至不会重新构建 all。
那么,对于 Make 来说,将 $? 扩展为 old phony 是多么错误。
phony 我明白了。但是old?真的吗?!
但是,现在让我们将注意力转向并行执行,其中 Make 将 $? 扩展为 phony。
这里:
当然,可以说这个扩展是正确的(与非并行执行中的扩展相比)。 原因是,只有
phony是触发all重新构建的文件。没有它,Make 根本不会费心重新构建all。仍然有人想知道,对于这两种执行模式,如何以不同方式扩展变量。 我什至无法想到,这与
$?的扩展有何关系。
总之,看起来“随机”变化(即执行模式的修改,从并行到非并行)影响了看似无关的实体,即自动变量的扩展。为什么?
【问题讨论】:
-
我刚刚发布了对链接问题here 的回答,我相信它也回答了这个问题。