为什么 "make" 仅在隐式时才删除目标文件
why does "make" delete target files only if implicit
假设我有一个这样的 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 已经被删除了,这在很多情况下是非常糟糕的。
那么为什么隐式规则不同呢?还是我做错了什么?
你没有做错任何事。您观察和分析的行为记录在 10.4 Chains of Implicit Rules 中。它指出中间文件确实被区别对待。
The second difference is that if make does create b in order to update
something else, it deletes b later on after it is no longer needed.
Therefore, an intermediate file which did not exist before make also
does not exist after make. make
reports the deletion to you by
printing a rm -f
command showing which file it is deleting.
文档没有明确解释为什么它的行为是这样的。查看文件 ChangeLog.1,早在 1988 年就有对 remove_intermediates
功能的引用。当时,磁盘 space 价格昂贵且溢价。
如果您不希望出现这种情况,请在 makefile 的某个位置提及您希望保留的目标作为明确的先决条件或目标,或者为此使用 the .PRECIOUS
or the .SECONDARY
special built-in targets。
感谢 MadScientist 的补充评论,请参阅下文。
假设我有一个这样的 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 已经被删除了,这在很多情况下是非常糟糕的。
那么为什么隐式规则不同呢?还是我做错了什么?
你没有做错任何事。您观察和分析的行为记录在 10.4 Chains of Implicit Rules 中。它指出中间文件确实被区别对待。
The second difference is that if make does create b in order to update something else, it deletes b later on after it is no longer needed. Therefore, an intermediate file which did not exist before make also does not exist after make.
make
reports the deletion to you by printing arm -f
command showing which file it is deleting.
文档没有明确解释为什么它的行为是这样的。查看文件 ChangeLog.1,早在 1988 年就有对 remove_intermediates
功能的引用。当时,磁盘 space 价格昂贵且溢价。
如果您不希望出现这种情况,请在 makefile 的某个位置提及您希望保留的目标作为明确的先决条件或目标,或者为此使用 the .PRECIOUS
or the .SECONDARY
special built-in targets。
感谢 MadScientist 的补充评论,请参阅下文。