为什么“ make”仅在隐式的情况下删除目标文件

时间:2019-01-24 00:55:37

标签: makefile gnu-make

假设我有一个这样的Makefile

B1.txt: A1.txt
    python big_long_program.py A1.txt > $@

correct1.txt: B1.txt reference.txt
    diff -q B1.txt reference.txt
    touch $@

然后,当我输入correct1.txt时,输出将达到我的期望:

python big_long_program.py A1.txt > B1.txt
diff -q B1.txt reference.txt
touch correct1.txt

现在,如果我有很多文件,例如B1.txt,B2.txt,B3.txt等,那么请创建一个隐式规则:

B%.txt: A%.txt
    python big_long_program.py A$*.txt > $@

correct%.txt: B%.txt reference.txt
    diff -q B$*.txt reference.txt
    touch $@

相反,当我输入correct1.txt时会发生这种情况:

python big_long_program.py A1.txt > B1.txt
diff -q B1.txt reference.txt
touch correct1.txt
rm B1.txt

即所不同的是,现在文件B1.txt已被删除,这在许多情况下确实很糟糕。

那么隐式规则为何不同?还是我做错了什么?

1 个答案:

答案 0 :(得分:2)

您没有做错任何事情。您观察和分析的行为记录在10.4 Chains of Implicit Rules中。它指出,中间文件的处理方式确实有所不同。

  

第二个区别是,如果make确实创建b以便更新   其他,它将在不再需要后删除b。   因此,make之前不存在的中间文件也   make后不存在。 make通过以下方式向您报告删除   打印rm -f命令,显示要删除的文件。

文档没有明确说明为什么的行为。在文件ChangeLog.1中,可以追溯到1988年的remove_intermediates函数引用。当时,磁盘空间既昂贵又昂贵。

如果您不希望出现这种情况,请提及要保留在makefile中某个位置的目标,作为明确的先决条件或目标,或为此使用the .PRECIOUS or the .SECONDARY special built-in targets

感谢MadScientist的其他评论,请参见下文。