说我有一个简单的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
未被更改并且{ {1}}保持不变。我只想更新b
和a1
(如果a2
是较新的(因此c
需要实际重新编译)。
我可以简单地让b
和a1
直接依赖于c,但这会歪曲真实的工作流程。
我不想删除a2
,因此将其作为中间文件将不起作用。
我也尝试过将b
包含为仅订购的依赖项,但是除非强制执行,否则b
和a1
永远不会被重新制作。
注意:Makefile旨在自动执行脚本并跟踪研究项目(而不是软件项目)的依赖性。也许Make不是正确的工具。类似数据库的文件是GeoPackages。
答案 0 :(得分:0)
如果您不能准确地依靠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 $@
仅当command to update b
比c
更新时才运行.buildc
,而每次使用此命令时都会设置b
,而不是使用print
时。
答案 1 :(得分:0)
您也许可以防止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 -j
)运行make,则a1
和a2
配方可能会与潜在的竞争条件并行运行。因此,最好使用.NOTPARALLEL:
或在配方中使用flock
来序列化它们。
答案 2 :(得分:0)
我认为“ order-only prerequisite”可能会达到目的:
a1: some_script | b
some_command $< b
a2: some_other_script | b
some_command $< b
b: c
touch $@
c:
touch $@