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

时间:2018-10-25 16:38:01

标签: makefile gnu-make

说我有一个简单的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未被更改并且{ {1}}保持不变。我只想更新ba1(如果a2是较新的(因此c需要实际重新编译)。

我可以简单地让ba1直接依赖于c,但这会歪曲真实的工作流程。

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

我也尝试过将b包含为仅订购的依赖项,但是除非强制执行,否则ba1永远不会被重新制作。

注意:Makefile旨在自动执行脚本并跟踪研究项目(而不是软件项目)的依赖性。也许Make不是正确的工具。类似数据库的文件是GeoPackages。

3 个答案:

答案 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 bc更新时才运行.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,则a1a2配方可能会与潜在的竞争条件并行运行。因此,最好使用.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 $@