makefile - 具有多个输出规则的 Makefile 在并行运行时不会重建嵌套依赖项
问题描述
我有一个生成多个输出的规则的生成文件。为了解决这个规则在并行运行时经常运行多次的问题,我使用了一个虚拟的“时间戳文件”。我还有一个规则,它取决于这个“多输出”规则的输出之一。
当所有这些都从干净的状态运行时,一切正常。但是,如果更新了多输出规则的源,则不会运行其他规则,直到再次运行 Make。
我查看了调试输出,但未能取得太大进展。似乎 Make 可能正在缓存先前版本的多输出文件的旧时间戳?
希望下面的内容充分说明了这个问题。
$ cat Makefile
all: data.txt
multioutput.stamp: sourcefile.txt
touch multioutput1.txt
touch multioutput2.txt
touch $@
FILES=multioutput1.txt multioutput2.txt
$(FILES): multioutput.stamp
data.txt: multioutput1.txt
touch data.txt
$ touch sourcefile.txt
$ make
touch multioutput1.txt
touch multioutput2.txt
touch multioutput.stamp
touch data.txt
$ touch sourcefile.txt # update
$ make # data.txt is not updated!!
touch multioutput1.txt
touch multioutput2.txt
touch multioutput.stamp
$ make # except when it's run again??
touch data.txt
我在这里做错了什么,我应该怎么做?
解决方案
你是在撒谎。不要那样做。
运行规则的配方后,请检查文件是否已被配方实际更新。如果它没有改变,您不必重新制作任何将文件列为依赖项的目标。
在这里,您没有给出任何方法multioutput1.txt
,只是一个依赖行:
multioutput1.txt: multioutput.stamp
Make知道没有办法更新multioutput1.txt
。
廉价修复
通过为multioutput1.txt
. _ 即使是空的也可以:
${FILES}: multioutput.stamp ;
是的,这就是它的;
含义——食谱的第一行在同一行。
更好的修复
说“这个配方创建两个文件”的唯一方法是使用模式规则。那么就不需要multioutput.stamp
.
.PHONY: all
all: data.txt
%1.txt %2.txt:
touch $*1.txt
touch $*2.txt
data.txt: multioutput1.txt multioutput2.txt
touch data.txt
这里$*
的配方扩展为%
依赖行中匹配的任何内容。
为什么我要data.txt
依赖这两个多输出文件?在这里,我认为如果其中一个multioutput1
或multioutput2
丢失,我们可能应该运行配方来创建两者。YMMV。
最佳修复
YMMV,但我不喜欢模式规则。它们对我的口味来说太随意了。
我们观察到其中一个multioutput1.txt
永远multioutput2.txt
比另一个年轻。假设现代文件系统,它们将永远不会具有相同的时间戳。
.PHONY: all
all: data.txt
multioutput2.txt: start.stamp
touch $@
touch multioutput2.txt
multioutput1.txt: multioutput2.txt ;
data.txt: multioutput1.txt
touch data.txt
推荐阅读
- image - 如何在离子设备上显示图像
- c++ - 显式实例化模板类的显式实例化模板方法
- python - 如何通过将所有内容放入df中来过滤数据框,减去另一个df?
- maven - 解决不推荐使用的 sonar.analysis.mode 参数
- python - keras在拟合模型时是否深度复制数据?
- jsp - response.setHeader("X-Content-Type-Options", "nosniff"); 没有在 Jsp 中设置
- extract - Splunk:如何直接在搜索栏中提取字段而无需使用正则表达式?
- salesforce - 具有相同操作的多个按钮
- node.js - npm 错误!使用 husky 和 lint-staged 编码 EJSONPARSE npm install
- reactjs - 用 Jest 测试 React API