我有一个Makefile,我目前正用于编译以外的目的。我想保留它们,而不是删除中间文件,而是gzip它们,然后让Makefile检测到存在一个中间文件,而不是重新计算它,只需将其解压缩即可。
假设我的目标 target.txt 取决于名为 intermediate.txt 的中间文件,该文件本身依赖于 prereq.txt 。如下所示:
target.txt: intermediate.txt
intermediate.txt: prereq.txt
现在默认情况下Make删除中间文件,但我们可以禁用它。但是,假设计算 intermediate.txt 需要很长时间,所以我将禁用自动删除它。但是如果文件 intermediate.txt 也非常大,那么我想将它(gzip)压缩为 intermediate.txt.gz 。我想让Make解压缩现有的压缩文件,而不是重新计算文件,所以 gunzip intermediate.txt.gz 。
我想我要问的一个更大的问题是我有两种制作目标的方法,基于两种不同的依赖关系。我希望Make执行具有先决条件的规则,并忽略其他规则,但也许删除压缩版本并仅在中间件的先决条件具有较新时间戳时重新计算它。有没有人有任何建议?
答案 0 :(得分:0)
如果您正在使用GNU Make,您可以使用模式规则(tac用于表示您正在进行的任何处理):
%.txt: %.i.txt
tac $^ > $@ #make .txt file the normal way
gzip $^ #gzip the intermediate file
%.txt: %.i.txt.gz
gunzip < $^ | tac > $@ #make .txt by streaming in the gzipped intermediate
%.i.txt: %.p.txt
tac $^ > $@ #make the intermediate file from the prereq
这适用于模式规则,因为如果找不到.i.txt
文件,Make会进入下一个模式并查找.i.txt.gz
版本。这对于显式规则不起作用,因为后面的规则只是替换了之前的规则。
答案 1 :(得分:0)
如果prereq.txt比gzip文件新,我猜你不想只解压缩.gz版本。在这种情况下,我倾向于使用shell测试来存储和恢复gzip压缩文件,而不是让make直接参与:
target.txt: intermediate.txt
...same as it ever was ....
intermediate.txt: prereq.txt
if [ $@.gz -nt $< ]; then \
gunzip <$@.gz >$@; \
else \
whatever >$@ <$<; \
gzip <$@ >$@.gz; \
fi
其中'whatever'是从prereq.txt创建intermediate.txt的命令