Make为何优先使用隐式规则而非Makefile自定义规则?如何解决?
规则优先级问题原因
Make内置了大量默认隐式规则,规则匹配优先级逻辑如下:
- 内置的后缀规则(比如直接从
.c源文件生成可执行文件的规则)优先级高于用户自定义的通用通配模式规则 - Make会优先选择依赖链更短的规则:内置的
%: %.c规则仅需要对应.c源文件即可直接生成可执行目标,你定义的%: %.o $(obj_lib)规则需要先生成对应目标的.o文件、依赖库的.o文件,依赖链更长,因此Make默认优先选择了内置的短链隐式规则,导致没有链接add.o就直接生成可执行文件,报错未定义符号。
解决方法
推荐使用优先级更高、副作用更小的静态模式规则替换原有通用通配规则,只需修改你定义的链接规则行即可:
# 替换原来的 %: %.o $(obj_lib) 行 $(targets): %: %.o $(obj_lib) $(CC) $(CFLAGS) -static -o $@ $^
静态模式规则仅对你指定的main1、main2目标生效,优先级高于内置隐式规则,Make会严格按照你定义的依赖和命令执行编译链接流程,不会触发默认的.c直接生成可执行的逻辑。
如果需要彻底禁用所有内置隐式规则,也可以在Makefile开头添加:
MAKEFLAGS += --no-builtin-rules
该方案会清除所有Make内置规则,仅使用你显式定义的规则,适合对编译流程完全自定义的场景。
修改后重新执行make即可正常完成编译:先编译生成main1.o、add.o后链接生成main1,再编译生成main2.o复用已经编译好的add.o链接生成main2。
内容的提问来源于stack exchange,提问作者Cooper Harasyn
相关产品推荐
相关产品推荐

