本文系统性拆解 Makefile 隐含规则所有知识点,从概念、分类、内置规则、默认变量、执行流程、禁用方法,一次性讲透,看完就能直接用到实际项目开发中。
Makefile核心教程总览,可查看文章Makefile核心教程总览(最通俗易懂完整版)。基础篇(11 篇)已全部免费发布;后续进阶篇(12 篇)为付费内容,可通过公众号「付费阅读」单篇购买,或加入知识星球一次性解锁全部 + 专属答疑。
鉴于源码篇幅稍长,故所有篇章的完整示例源码均打包上传在知识星球,源码均原创,可下载直接编译运行,注释讲解。结合完整源码阅读文章,理解更透彻。
一、基础概念
1. 什么是隐含规则
隐含规则是 Make 程序内置预设好的一套编译推导规则,不需要开发者手动书写命令和依赖关系,Make 会根据文件后缀、文件名格式,自动识别文件类型并执行对应的编译、汇编、链接动作。
2. 隐含规则的核心作用
- 省去手写重复编译命令,精简 Makefile 代码量。
- 自动推导文件依赖关系,无需逐个写依赖。
- 统一编译规范,适配 C、C++、汇编等多类源码。
- 小型工程甚至可以零配置,不用写任何规则就能编译。
3. 隐含规则生效前提
- 工程文件命名遵循标准后缀规范(.c/.cpp/.s/.o 等)。
- 没有自定义显式规则、模式规则覆盖同名推导逻辑。
- 不主动禁用后缀规则和内置隐含规则。
4. 隐含规则 vs 显式规则区别
显式规则:开发者手动写目标、依赖、执行命令,优先级最高。 隐含规则:Make 内置自动推导,无显式规则时才会触发。
示例 demo1:
# 1. 显式规则(手写所有命令)
main: main.o
$(CC) main.o -o main
main.o: main.c
$(CC) $(CFLAGS) -c main.c -o main.o
# 2. 隐含规则(极简写法,自动编译)
main: main.o
二、隐含规则两大核心分类
1. 传统后缀隐含规则(了解即可)
这是老式 Make 规则写法,依靠文件后缀映射实现编译推导。
核心关键字:.SUFFIXES 后缀列表。
默认内置后缀:.c .cpp .cc .h .o .s .asm等。
原理:通过后缀1后缀2的格式,定义从一种文件编译成另一种文件的规则。例如.c.o 表示 .c 生成 .o。
特点:写法老旧、灵活性差、无通配能力,现代工程已完全被模式规则(%.o:%.c)替代。
内置规则:
# 老式后缀规则(了解即可,实际开发中不推荐)
.SUFFIXES: .c .o
.c.o:
gcc -c $< -o $@
2. 新式模式隐含规则(重点必学)
采用%通配符匹配,是现在主流的隐含规则形式,兼容性强、可读性高。
基础语法:%.o : %.c
%作用:匹配任意文件名前缀,实现批量文件统一规则。
内置规则:
# 系统自带的模式规则,你不用写,直接能用
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
关于模式规则的详细内容,可查看该核心教程文章 Makefile核心教程(七) --- 一文吃透 Makefile 模式规则。
三、系统内置高频隐含规则
1、C 语言编译规则:.c → .o 自动把 C 语言源码文件编译生成目标文件,无需手写 gcc 编译命令。
内置模式规则:
%.o : %.c
自动执行:
$(CC) $(CFLAGS) -c $< -o $@
无需手写命令。详见示例 demo2。
2、C++ 编译规则:.cpp/.cc/.cxx → .o 识别多种 C++ 后缀文件,自动调用 C++ 编译器生成.o 目标文件。
内置模式规则:
%.o : %.cpp
%.o : %.cc
%.o : %.cxx
自动调用:
$(CXX) $(CXXFLAGS) -c $< -o $@
详见示例demo3。
3、汇编编译规则:.s/.asm → .o 自动汇编处理汇编源码,生成目标文件,适配底层驱动、汇编开发场景。
内置规则:
%.o : %.s
自动执行汇编命令。详见demo4。
4、目标文件链接规则:.o → 可执行文件
单个.o 目标文件自动链接,生成无后缀的可执行程序,不用手动写链接命令。 多 个.o目标文件不会自动链接,生成无后缀的可执行程序,不触发隐含链接规则,需要手动写链接命令。
内置规则:
% : %.o
自动把 .o 链接成可执行文件,无需写链接命令。详见示例 demo5。
5、单源码直接生成可执行文件:.c / .cpp 只需 main.c,Makefile 啥都不用写,空着也行。
直接执行:
make main
原理:Make 内置隐含规则:% : %.c。自动一步完成:编译 + 链接,直接生成可执行文件 main。
详见示例demo6。
四、隐含规则内置默认变量
隐含规则能自动生效,全靠一套默认 内置自动变量 + 内置宏变量 工作。内置自动变量详看 Makefile核心教程(三) --- 一文讲透Makefile 变量 一文。常用内置宏变量如下:
-
编译器相关变量 CC:默认 C 语言编译器,一般默认为 gcc。 CXX:默认 C++ 编译器,一般默认为 g++。 AS:默认汇编编译器。
-
编译参数相关变量 CFLAGS:C 语言编译选项(宏定义、优化等级、警告参数)。 CXXFLAGS:C++ 专属编译选项。 ASFLAGS:汇编编译选项。
-
链接相关变量 LDFLAGS:链接库路径参数。 LDLIBS:需要链接的库文件(如 -lpthread -lm)。
-
自定义覆盖方式 可在 Makefile 中直接重新赋值内置变量,就能修改隐含规则的默认编译行为,不用改写规则本身。
五、隐含规则执行流程与匹配优先级
-
Make 规则查找顺序 优先匹配开发者手写的显式规则,其次匹配自定义模式规则,最后才触发系统内置隐含规则。
-
多规则冲突优先级 显式规则 > 自定义模式规则 > 系统隐含规则
六、工程级别示例源码
demo7:隐含规则示例(c/c++混合编译)
demo7
├── add.c
├── main.c
├── Makefile
└── utils.cpp
详见示例 demo7。
七、写在最后
公众号发送消息 星球,获取加入知识星球方式。