Makefile “为什么?”;制造;仅在隐式的情况下删除目标文件

Makefile “为什么?”;制造;仅在隐式的情况下删除目标文件,makefile,gnu-make,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 B

假设我有一个这样的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
i、 e.不同之处在于,现在B1.txt文件已被删除,这在许多情况下非常糟糕


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

你没有做错什么。您观察和分析的行为记录在中。它指出,中间文件的处理方式确实有所不同

第二个区别是,如果make创建b是为了更新 另外,在不再需要b之后,它会删除b。 因此,在生成之前不存在的中间文件 制造后不存在<代码>生成通过以下方式向您报告删除 打印显示要删除的文件的
rm-f
命令

文档没有明确解释它为什么会这样做。查看该文件,可以追溯到1988年的
remove\u intermediates
函数。当时,磁盘空间非常昂贵,而且价格昂贵

如果您不希望出现这种行为,请提及您希望保留在makefile中某处的目标,作为显式的先决条件或目标,或用于此目的


感谢您的补充意见,请参见下文。

您不必使用
.PRECIOUS
.SECONDARY
。您所要做的就是在makefile的某个地方提到您想要保留的目标,作为显式的先决条件或目标。例如,你可以说
alltxt:B1.txt B2.txt B3.txt
等等@madscitist你是对的,当然,有多种选择可以避免这种删除。既然你提到了另一种选择,你会有理由选择一种机制而不是另一种吗?就我个人而言,我总是喜欢任何“正常”的制造行为而不是任何“特殊”的目标
.PRECIOUS
具有您可能不想要的其他效果。如果你想一想,通常情况下,如果出于某种原因确实需要这些文件,那么不管怎样,把它们作为某个目标的先决条件是很方便的。@madscitist这是有道理的。我已经更新了我的答案,感谢您帮助我改进它。至于为什么会发生这种情况,这是历史悠久的,当时磁盘空间非常昂贵,而且价格昂贵。它主要用于静态库,在静态库中,您可以通过替换单个对象文件而不是从头开始重建来更新库。由于您不需要所有其他的.o,只需要过期的,因此可以删除它们并节省磁盘空间,而不会增加构建时间。