>假设我有一个简单的Makefile。
a1: some_script b
some_command $< b
a2: some_other_script b
some_command $< b
b: c
touch $@
c:
touch $@
其中b
是制作a1
和a2
所需的类似数据库的文件。但是,每次访问b
(即使未更改(时,修改日期都会更改。因此,无论何时执行a2
规则,Make 都会认为需要重新制作a1
,因为使用了数据库b
(即使c
没有更改并且b
保持不变(。我只想更新a1
并a2
c
是否较新(因此b
需要实际重新编译(。
我可以简单地a1
,a2
直接依赖 c,但这歪曲了真正的工作流程。
我不想删除b
,因此将其作为中间文件将不起作用。
我也尝试将b
作为仅订单依赖项包含在内,但除非被迫,否则a1
和a2
永远不会重新制作。
注意:Makefile旨在自动执行脚本并跟踪研究项目(而不是软件项目(的依赖关系。也许Make不是正确的工具。类似数据库的文件是GeoPackages。
如果您不能依赖b
的时间戳是准确的,那么您不需要在 makefile 中使用它。 你可以做这样的事情:
a1: some_script .buildc
some_command $< b
a2: some_other_script .buildc
some_command $< b
.buildc: c
command to update b
touch $@
c:
touch $@
仅当c
比每次调用此命令时设置的.buildc
新时,而不是在使用b
时,才会运行command to update b
。
也许你可以阻止b
时间戳的无用更改:
a1: some_script b
touch -r b .b.a1
some_command $< b
touch -r .b.a1 b && rm .b.a1
a2: some_other_script b
touch -r b .b.a2
some_command $< b
touch -r .b.a2 b && rm .b.a2
但要小心:如果你在并行模式下运行 make (make -j
(,a1
和a2
配方可能会与潜在的竞争条件并行运行。因此,最好使用.NOTPARALLEL:
或在配方中使用flock
来序列化它们。
我认为"仅订单先决条件"可能会解决问题:
a1: some_script | b
some_command $< b
a2: some_other_script | b
some_command $< b
b: c
touch $@
c:
touch $@