来自https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html#Automatic-Variables 的
$?所有比目标更新的先决条件的名称,它们之间有空格。
现在,给出一个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**),的并行执行的值的扩展与对 non-parallel-execution*的扩展不同
让我们首先分析第一种情况,即non-parallel的执行。
all和old的修改时间如下:
old比all更“老”。这是不言而喻的。对吗?old之后,old通过”获取“名为:older的文件的修改时间而”变老“。这基本上是shell命令cp -p older old的净结果。现在,不难看出,older是way“老”于all。现在,Make最终构建了目标all,因为是其他的先决条件,即:phony。
但是,根据文档,$?应该只扩展到“所有先决条件的名称,这些先决条件都是比目标更新的更新的”。这是一个精确的引语。
我们是否可以同意,old是,从来没有比all新。而且,如果不是phony的话,Make甚至不会重建all。
那么,对于Make来说,将$?扩展到old phony是多么的错误。
我明白了phony。但是old呢?真的?!
但是,现在让我们将注意力转向并行执行,其中Make将$?扩展为phony。
在此:
phony 才是,该文件触发了all的重新构建。如果没有它,Make根本不会费心重新构建all。$?的扩展有任何关系。总之,看起来一个“随机”的变化(即对执行模式的修改,从并行到非并行)影响着一个看似不相关的实体,即自动变量的扩展。为什么?
发布于 2015-08-20 10:26:40
在使用规则构建了old之后,Make now认为它是依赖关系图中的最新文件。在制作old后,不检查。
对于虚假目标来说,这显然是正确的,而且对于文件目标来说,这通常也是正确的。
发布于 2015-08-20 10:24:36
任何由make构建或更新的文件都已被更新,因此它将隐式地假设它是更新的,即使您黑进了一个使其更老的命令。
理论上,Make应该处理文件的内容,而不是日期。如果内容不同,则应运行依赖构建。考虑到我们没有文件系统提供简单的内容派生(散列之类的),它使用最后修改的日期来完成这个任务。因为这也不是100%可靠的--例如,看看那些日期没有足够准确性的系统,或者只是在将来--它也将使用它作为一个信息源。如果它只是建造它,它必须被修改,因此它是正确的认为它“更新”或“重建”。
https://stackoverflow.com/questions/32114743
复制相似问题