如果执行 Make 配方没有更改目标文件会发生什么?

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

我们有一个 Makefile,其中包含调用脚本来生成 C 标头的配方,然后将其包含到许多其他源文件中:

gen-header.h: $(INPUT)
    script.py $(INPUT) -o gen-header.h

# GMake and GCC rules to produce and include .d files for .c files 
# to track header/source dependencies follow

最近,script.py 中添加了优化,以便避免覆盖输出文件(如果存在)并且其内容不会更改(例如,如果仅更新

$(INPUT)
中的非功能性注释)。在这种情况下,输出
gen-header.h
的访问时间和创建时间都不会更新。

优化的预期目标当然是避免在

$(INPUT)
中的更改未传播到标头时重新编译依赖于 gen-header.h 的所有文件(还有其他生成过程使用
$(INPUT)
的不同部分来生成与 gen-header.h 无关的不同源文件)

问题是:这种情况会让 Make 感到困惑吗?或者对于配方来说这是可以接受的行为吗?

makefile recipe
2个回答
0
投票

问题是:这种情况会让 Make 感到困惑吗?或者对于配方来说这是可以接受的行为吗?

会不会混淆

make
?不会。如果目标的配方没有构建该目标,或者没有在每次运行时构建它,那么
make
本质上不会失败。它可能会或可能不会给您的构建带来问题,具体取决于您的 makefile 的细节和其他细节,但您描述的情况听起来是良性的。


0
投票

它不会混淆 make,因此,在这种特殊情况下是无害的,因为唯一的结果是每次运行 Make 时都会重复运行

script.py $(INPUT) -o gen-header.h
操作。

但是,您通常希望避免这种情况。

类似的规则

target: source
    action
从某种意义上说,

是一个“承诺”,运行

action
将导致
target
source
更新。当我发现在某些情况下(可能涉及该操作的副作用?)这确实导致了问题时,我会感到零惊讶。

幸运的是,这很容易避免。在这种情况下我会写

# Note: `script.py` doesn't rewrite `gen-header.h` if it wouldn't change
gen-header.h: $(INPUT)
    script.py $(INPUT) -o gen-header.h && touch $@

...只是为了提醒自己,在将来调试 Makefile 时会发生这种情况。这会迫使目标文件

$@
更新,从而保持对 Make 的隐含承诺。

© www.soinside.com 2019 - 2024. All rights reserved.