makefile - 为什么“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 $@
相反,当我制作正确的 1.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 隐式规则链中。它指出中间文件确实被区别对待。
第二个区别是,如果 make 确实创建 b 是为了更新其他内容,它会在不再需要 b 后删除它。因此,在 make 之前不存在的中间文件在 make 之后也不存在。
make
通过打印rm -f
显示正在删除的文件的命令向您报告删除。
该文档没有明确解释为什么它会这样。查看文件ChangeLog.1,可以remove_intermediates
追溯到 1988 年的函数。当时,磁盘空间非常昂贵且非常宝贵。
如果您不希望这种行为,请提及您要保留在 makefile 中某处的目标作为明确的先决条件或目标,或者为此使用或.PRECIOUS
特殊的.SECONDARY
内置目标。
感谢MadScientist的其他评论,见下文。
推荐阅读
- ruby-on-rails - 如何在 Rails 中查看活动会话
- python - SQLAlchemy 操作错误:尝试创建新数据库行时没有这样的表列 user_id
- powerbi - 创建度量以计算列中不同值的百分比变化
- java - 当我注释两次时,我使用 @Repeatable 的自定义注释不起作用
- c# - 为什么我无法将 GetProp(ptr, "OleDropTargetInterface") 返回的值转换为 IDropTarget?
- jackson-dataformat-xml - 如何将元素类型名称的多态列表序列化为 Jackson 中的 xml 元素名称
- ms-access - 我在一行中有多个 ID(最多 20 个)。每个 ID 指向该行中的每个其他 ID。我需要 2 列所有 ID 之间的所有关系
- apache-kafka-streams - Spring @StreamListener 进程(KStream流)分区
- python - 代码是理解 Vae 与标准自动编码器的正确方式吗?
- json - Swift Tableview 数据加载使索引超出范围