1

我有一个 Makefile 我目前用于编译以外的目的。我不想删除中间文件,而是保留它们,但 gzip 它们,然后让 Makefile 检测到中间文件存在,而不是重新计算它,只需解压缩它。

假设我的目标target.txt依赖于名为intermediate.txt的中间文件,该文件本身依赖于prereq.txt。所以像:

target.txt: intermediate.txt
intermediate.txt: prereq.txt

现在默认情况下 Make 会删除中间文件,但我们可以禁用它。但是假设计算middle.txt都需要很长时间,所以我将禁用自动删除它。但是如果文件intermediate.txt也很大怎么办,所以我想将它(gzip)压缩到intermediate.txt.gz。我不想重新计算文件,而是希望 Make 解压缩现有的压缩文件,所以gunzip intermediate.txt.gz

我想我要问的更大的问题是我有两种方法来制作目标,基于两种不同的依赖关系。我希望 Make 执行具有存在先决条件的规则,并忽略其他规则,但可能会删除压缩版本并仅在中间体的先决条件具有较新时间戳时才重新计算它。有没有人有什么建议?

4

2 回答 2

1

如果您使用的是 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版本。这不适用于显式规则,因为后面的规则只是替换了前面的规则。

于 2012-12-06T20:15:33.917 回答
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 创建 middle.txt 的命令

于 2012-12-06T21:20:35.357 回答