类似数据库的文件作为生成文件中的目标和先决条件



>假设我有一个简单的Makefile。

a1: some_script b
some_command $< b
a2: some_other_script b
some_command $< b
b: c
touch $@
c:
touch $@

其中b是制作a1a2所需的类似数据库的文件。但是,每次访问b(即使未更改(时,修改日期都会更改。因此,无论何时执行a2规则,Make 都会认为需要重新制作a1,因为使用了数据库b(即使c没有更改并且b保持不变(。我只想更新a1a2c是否较新(因此b需要实际重新编译(。

我可以简单地a1a2直接依赖 c,但这歪曲了真正的工作流程。

我不想删除b,因此将其作为中间文件将不起作用。

我也尝试将b作为仅订单依赖项包含在内,但除非被迫,否则a1a2永远不会重新制作。

注意: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(,a1a2配方可能会与潜在的竞争条件并行运行。因此,最好使用.NOTPARALLEL:或在配方中使用flock来序列化它们。

我认为"仅订单先决条件"可能会解决问题:

a1: some_script | b
some_command $< b
a2: some_other_script | b
some_command $< b
b: c
touch $@
c:
touch $@

相关内容

  • 没有找到相关文章

最新更新