make如何解析Makefile中百分比匹配模式规则与显式规则
Makefile显式规则与模式规则的解析逻辑
核心规则前提
首先澄清两个常见认知误区:
- 模式规则(%开头的规则)不等于预先生成所有匹配目标的显式规则:模式规则是Make的「后备候选规则」,仅当目标没有显式定义的构建命令时,才会被检索匹配
- 同目标的多规则处理逻辑分两类:
- 仅声明依赖、没有构建命令的显式规则:只会给目标追加依赖,不会覆盖已有构建命令
- 带构建命令的显式规则:后定义的规则会覆盖前序同目标的构建命令
- 模式规则的优先级永远低于显式规则:只要目标有显式定义的构建命令,就不会匹配任何模式规则
测试用例解析
针对你给出的测试Makefile:
foo : bar bar : #bar % : %.c #%
两种场景的执行逻辑如下:
场景1:目录下仅存在bar.c/无任何.c文件
Make默认取第一个目标foo作为最终构建目标:
foo的规则仅声明依赖bar,没有定义构建命令- 依赖
bar存在带构建命令的显式规则,Make直接执行该规则的命令输出#bar - 因
bar已有显式构建命令,Make不会检索匹配通配模式规则,因此不会触发#%的输出
场景2:目录下仅存在foo、foo.c、Makefile
- 最终目标
foo仅声明依赖bar,无显式构建命令 - 先构建依赖
bar,执行显式规则输出#bar - 回到
foo的构建逻辑:因无显式构建命令,Make检索匹配到% : %.c模式规则,且依赖foo.c存在,因此执行模式规则的命令输出#%
头文件自动依赖原理解析
你提到的自动依赖写法的核心逻辑恰好匹配上述规则:
a.out: main.o g++ main.o %.o: %.cpp g++ $< -c main.o: main.cpp foo.h # *.d文件生成的仅依赖规则
main.o的构建命令由%.o: %.cpp模式规则提供- 后续
main.o: main.cpp foo.h是仅声明依赖、无构建命令的显式规则,只会给main.o追加foo.h作为依赖,不会覆盖已有构建命令 - 最终等效于合并后的规则,实现修改头文件也会触发对应源文件重编译的效果
内容的提问来源于stack exchange,提问作者Elliott
相关产品推荐
相关产品推荐

