如何编写makefile,使其忽略“无关的”更改?

时间:2019-03-06 18:29:10

标签: makefile

说我有一个这样的Makefile

B: A
    quick-custom-script < $< > $@

C: B
    slow-custom-script < $< > $@

还假设A中的更改很可能会产生相同的B。我想在这种情况下省去C的复杂制作,因为 that 在输入不变的情况下肯定是不必要的工作。

我的想法是将quick-custom-script的输出放入一个临时文件,将其与当前B进行比较,并仅在发现差异时才覆盖B。 在这种情况下,C规则仍然会看到旧的B而什么也不做。不幸的是,这产生了另一个我看到的问题(也许还有更多?):在任何后续运行中,即使没有进行任何更改,A也会比未覆盖的B更新,因此(即使很快)第一个脚本将运行-不必要。

我认为可以将其最小化如下

Btemp: A
    quick-custom-script < $< > $@

B: Btemp
    diff -q $< $@ || cp $< $@

C: B
    slow-custom-script < $< > $@

尽管如此,我想知道是否有更明智的方法来实现我的目标?

1 个答案:

答案 0 :(得分:2)

这与通常的约定非常接近。它将比较结果放入相同的配方中,如下所示:

B: A
    quick-custom-script < $< > $@T
    $(move-if-change)

具有以下定义:

move-if-change = @if cmp -s $@ $@T ; then rm $@T ; else mv $@T $@; fi

这种组合成一条规则的优点是,如果quick-custom-script异常终止并且再次运行makefile,则配方将从头开始,并且部分写入的输出文件将被丢弃。

使用cmp通常比diff更快,并且mv是原子的,因此避免了重新引入相同的潜在损坏。