gpt4 book ai didi

makefile - 带有 .INTERMEDIATE 的 makefile 中不可靠的并行构建?

转载 作者:行者123 更新时间:2023-12-01 09:50:55 25 4
gpt4 key购买 nike

我有一个生成多个输出文件的工具,众所周知,它很难在 make 中建模。我正在使用 GNU Makefile rule generating a few targets from a single source file 的配方,它看起来简单可靠。它几乎有效。

不幸的是,我在并行构建方面看到了一些非常奇怪的行为,有时似乎会丢弃依赖项;我不明白为什么。

这是我的测试用例:

out3: out1 out2
touch out3

.INTERMEDIATE: out.intermediate
out1 out2: out.intermediate
out.intermediate: in
touch out1 out2

如果我构建一次,它就可以工作:
$ touch in
$ make -f test.mk out3 -j4
touch out1 out2
touch out3
out1out2 一起构建,一次,好;然后根据结果构建 out3

现在我触摸输入文件,模拟增量构建,然后再试一次:
$ touch in
$ make -f test.mk out3 -j4
touch out1 out2

那是重建 out1out2 ,正确......但它没有重建 out3 ,它应该有。然后,如果我再进行一次构建:
$ make -f test.mk out3 -j4
touch out3

...它 catch 了。

这仅适用于并行构建。 -j1 构建工作正常。

这很糟糕——我需要能够依赖正确的构建。有没有人知道发生了什么?

这是 GNU Make 4.1。

最佳答案

您链接到的 SO 答案有错误;令人惊讶的是,这么多人显然成功地使用了它。

发生的事情(您可以将 -rRd 选项添加到您的 make 调用中以查看更多详细信息)是 GNU make 目录缓存的结果。 GNU make 不希望文件系统状态以您的 makefile 描述的方式以外的任何方式改变,因此它缓存目录的内容以提供显着的性能提升(对于大型 makefiles/目录)。

基本上,当 make 运行规则时:

out.intermediate: in
touch out1 out2

除了规则中列出的目标 out.intermediate 之外,它不期望此配方会更新任何目标。如果其他文件 out1out2 已经在目录缓存中被内部化(因为它们存在并且我们已经检查它们作为 out3 的先决条件),那么 make 将不会返回到文件系统并查看它们是否“是否已更新:根据makefile,使“知道”它们无法更改,因为它运行的任何规则都无法更改它们。

有一个简单的单一字符修复程序可以使所有这些工作正常进行。改变这一行:
out1 out2: out.intermediate

对此:
out1 out2: out.intermediate ;

如果你想更明确,你也可以使用这个:
out1 out2: out.intermediate
@:

甚至这个,用于调试:
out1 out2: out.intermediate
@echo Do nothing

所有这些的共同点是,您现在不仅定义了目标和先决条件之间的依赖关系,而且还给出了 make 应该为该规则调用的配方。即使配方是空的(如第一个例子),所以 make 实际上并没有运行任何命令,make 仍然会推断 out1 和/或 out2 上的时间戳可能已经改变,并且它会使缓存的修改无效这些目标的时间并从文件系统中重新检索它们。

关于makefile - 带有 .INTERMEDIATE 的 makefile 中不可靠的并行构建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37873522/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com