通过引入不存在的文件触发Makefile目标执行的原理与文档咨询
关于Makefile中
-include触发目标构建的问题解答 1. 为什么引入不存在的文件会执行对应目标?
这其实是GNU Make的核心设计逻辑之一:当遇到include(或-include)指令时,Make不仅会尝试读取指定文件,还会自动尝试构建不存在的包含文件——只要Makefile中存在能生成该文件的规则。
具体到你的例子,完整执行流程是这样的:
- Make启动后,先解析变量
TEMP_DIR,接着遇到-include $(TEMP_DIR)/myfile.txt指令。 - 它检查目标文件是否存在,发现文件不存在,但
-include只是让它不抛出“文件未找到”的错误,并不会跳过构建尝试。 - 随后Make会在当前Makefile中查找有没有规则能生成
$(TEMP_DIR)/myfile.txt——刚好你定义了这个目标,所以它会优先执行这个目标下的命令(也就是$(info "running temp_dir target"))。 - 完成这个目标的执行后,Make才会继续处理Makefile的剩余部分,找到默认目标
default,执行它的$(info)命令,最后因为default没有依赖项,所以提示make:default' is up to date.`
这里要注意:哪怕你的$(TEMP_DIR)/myfile.txt目标没有实际生成文件的命令(比如touch $@),Make依然会执行该目标下的所有命令——因为它默认认为你定义这个规则就是用来生成缺失的包含文件的。
2. 相关文档说明
GNU Make的官方文档中,include指令的章节明确覆盖了这个行为:
- 当Make处理
include指令时,会将指定的文件视为需要被构建的目标。如果文件不存在,但存在对应的生成规则,Make会优先执行这些规则来创建文件,再继续处理Makefile的后续内容。 -include(也可写成sinclude)的特殊作用是:如果文件最终还是无法被构建(比如没有对应规则),Make不会抛出错误,而是继续执行后续逻辑——但只要有可用规则,构建过程依然会正常触发。
这个技巧在实际开发中非常常用,比如C/C++项目里,会用它自动生成头文件依赖(通过gcc -MM生成.d依赖文件,再-include这些文件),这样Make就能自动感知头文件的变化,无需手动维护依赖关系。
内容的提问来源于stack exchange,提问作者cDreamer
相关产品推荐
相关产品推荐

