防止过时的仅保留先决条件的重建

问题描述 投票:4回答:2

一个同事刚遇到这个问题,我想问一下以下问题是否有任何巧妙的解决方案:我有一个GNU makefile:

a: | b
    touch $@
b:c
    touch $@
c:
    touch $@

然后我跑步:

~/tmp> make a
touch c
touch b
touch a
~/tmp> make a
make: `a' is up to date.
~/tmp> touch b
~/tmp> make a
make: `a' is up to date.
~/tmp> touch c
~/tmp> make a
touch b

如果我触摸b,它将重建a,而不重建c。如果仅订单先决条件正在调用b,是否可以不重建它? (在实际情况下,b是一个具有数百个依赖项的文件,当调用make a时可能不会存在。我不能使b的先决条件成为仅顺序的,因为这会破坏[ C0])

makefile
2个回答
2
投票

该行为是完全正确的。您指示make b忽略makea之间的紧密依赖性,并且仅取决于b存在。而ba共享日期依赖性

这是ca: b之间的区别。


如果要调查此案(或其他a: | b 魔术 :)):

[尝试以下操作,您会发现make很热衷,并告诉您它对make目标的作用:

b

现在,添加一个严格的依赖项:

% touch b
% LANG=C make -rd | awk '/^Considering/,/^$/ {print}'
Considering target file `a'.
  Considering target file `b'.
    Considering target file `c'.
     Finished prerequisites of target file `c'.
    No need to remake target `c'.
   Finished prerequisites of target file `b'.
   Prerequisite `c' is older than target `b'.
  No need to remake target `b'.
 Finished prerequisites of target file `a'.
 Prerequisite `b' is order-only for target `a'.      <--- "order-only"
No need to remake target `a'.

并比较结果:

% echo "a:b" >> Makefile 

我使用了% touch b % LANG=C make -rd | awk '/^Considering/,/^$/ {print}' Considering target file 'a'. Considering target file 'b'. Considering target file 'c'. Finished prerequisites of target file 'c'. No need to remake target 'c'. Finished prerequisites of target file 'b'. Prerequisite 'c' is older than target 'b'. No need to remake target 'b'. Pruning file 'b'. Finished prerequisites of target file 'a'. Prerequisite 'b' is order-only for target 'a'. Prerequisite 'b' is newer than target 'a'. <--- additional "date dependency" Must remake target 'a'. touch a <--- 'a' is rebuilt Putting child 0x1b09ec0 (a) PID 5940 on the chain. Live child 0x1b09ec0 (a) PID 5940 Reaping winning child 0x1b09ec0 PID 5940 Removing child 0x1b09ec0 PID 5940 from chain. Successfully remade target file 'a'. (没有隐式规则),因为此示例不使用它们,并且它是无聊读取。


0
投票

除了注释,您的问题陈述是非常通用的,与描述实际用例相距甚远。这使得它非常简短,易于阅读和理解。另一方面,理解和解决或解决您的specific问题更加不确定。

我已经看到您的完全相同的通用问题陈述适用于此其他用例:

make -r

此代码的意思是:“在没有nimble_exe的情况下构建big_lib,但不在乎它何时过期”,这表面上与“仅订购的依赖项”甚至nimble_exe: nimble_srcs | big_lib touch $@ big_lib: biglib_many_sources_and_headers touch $@ sleep 1 # simulate a long [no-op] build time biglib_many_sources_and_headers touch $@ 的定义相匹配。

不幸的是,如果有人更改了used to match ninja's behavior until 2011中的任何内容,则biglib_many_sources_and_headers会重建make nimble_exe,但不是

big_lib!这表明“仅订购依赖项”根本不是针对该用例设计的。因此,我建议改为:
nimble_exe
© www.soinside.com 2019 - 2024. All rights reserved.