说我有一个这样的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 < $< > $@
尽管如此,我想知道是否有更明智的方法来实现我的目标?
答案 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
是原子的,因此避免了重新引入相同的潜在损坏。