我有像这样的Makefile
all: *.foo
./finalstep *.foo > $@
%.foo: %.bar
./secondstep < $< > $@
%.bar: %.baz
./firststep < $< > $@
事情是,.baz
文件中的经常更改是次要的,因为更改后生成的.bar
文件是相同的(内容方面,或者如同diff
)一样,在变化之前。
由于secondstep
和finalstep
(以及可能更多的中间步骤)昂贵,如果可以检测到.bar
文件中缺少更改并且因此,secondstep
(甚至可能finalstep
)的调用得以幸免。有没有办法实现这个目标?
我尝试做这样的事情如下:
%.bar: %.baz
touch $@; cp $@ $@.backup; ./firststep < $< > $@
%.foo: %.bar
diff -q $< $<.backup || ./secondstep < $< > $@
但这有很多缺点(如果用参数调用make
,则无法正常工作)。
有没有更好的方法?基本上,make
应考虑.bar
个文件的两个不同文件时间:每次运行firststep
时都会更新一个文件,并用于确定.bar
本身是否需要重新制作。另一个仅在firststep
运行导致文件的内容净更改时更新,并用于确定需要重新生成.foo
...
答案 0 :(得分:0)
我认为您应该尝试使用类似(未经测试)的:
all: %.foo
./finalstep %.foo > $@
%.foo: %.bar
@if [[ -f $< && -f $<.backup ]]; then \
if diff -q $< $<.backup; then \
echo "IDENTICAL => do nothing"; \
else \
echo "DIFFERENT => proceed"; \
./secondstep < $< > $@; \
fi; \
else \
echo "NOT FOUND => proceed"; \
./secondstep < $< > $@; \
fi; \
cp $< $<.backup
%.bar: %.baz
./firststep < $< > $@;
基本上,大配方的目的是处理$<
和$<.backup
的所有相关组合(在相同的子shell中!):
diff
返回0
)=>
什么都不做diff
返回1
)=>
执行=>
执行无论上述选择是什么,最后都要backup
。