前言:
大家在Windows上使用VS构建C/C++程序时,不需要自己编辑略显晦涩的Makefile文件,而对于初学者而言, 他们甚至没意识到它的存在。VS是自动生成Makefile文件, 并构建工程项目的。不可否认Visual Studio做为一款全能的IDE,它帮开发者做了很多工作,也降低了C/C++的门槛,意义非常的重大。
但作为进阶的C/C++开发者, 你是有必须了解底层编译和链接原理的。 让我们来梳理下C/C++的编译链接过程,并回顾Makefile的编写规则,最后让我们来尝试实现自动构建工程Makefile文件的机制。本文侧重讲解C/C++的编译过程和Makefile的规则,后文讲述如何实现Makefile的生成器。
编译C/C++程序
C/C++程序的生成, 分为如下几个步骤
1). 预处理: 引入头文件,解析并展开宏定义
2). 编译: 简单一点就是把源代码转化为汇编码(机器指令)
3). 链接: 组装各个子模块和相应的库,并生成最终的可执行程序
评注: 参数-E用于生成预处理后的c/c++文件, 参数-c用于生成编译后的二进制文件,参数-o则只是用于制定某个阶段的产出物名称
Makefile的基础规则
基本规则很简单:
<target> : <prerequisites> <command>
评注: <target>是目标名称, <prerequisites>是依赖的列表项, <command>则是对应的执行命令
当然有些注意项:
1). Makefile第一项执行规则为默认的最终目标
2). 命令必须"\t"作为开头
Makefile常见的宏定义:
$^ 依赖项列表 [email protected] 目标对象 $< 依赖列表中的第一个对象
Makefile的变量定义和使用, 如下所示:
CC = g++ CFLAG = -g -WALL app: main.cpp $(CC) $(CFLAG) -o [email protected] $^
评注:变量CC/CFLAG展示了Makefile的定义和引用语法
伪目标对象的引入, 对于make clean特别有用
.PHONY : clean clean: -rm $(OBJECTS)
其实PHONY的引入, 是针对文件系统中,刚好有名为"clean"文件的特殊情形。各位看官, 你还记得大明湖畔的夏雨荷吗? 就是这种感觉
Makefile的小实战
对于如下工程:
include包含工程的头文件,src包含工程的C/C++文件
其具体的Makefile文件,可以编辑如下所示:
CC = g++ CFLAG = -g -Wall OBJECTS := $(wildcard *.o) app : app.o cache.o g++ $(CFLAG) -o [email protected] $^ app.o : src/app.cpp include/cache.h g++ -c -o [email protected] src/app.cpp -Iinclude cache.o : src/cache.cpp include/cache.h g++ -c -o [email protected] src/cache.cpp -Iinclude .PHONY : clean clean: -rm $(OBJECTS)
这个实战项目就算完成了, Makefile文件具备了它所需要的功能:生成/清理。
挑战
实战的工程还是比较小,手动维护Makefile还是相对简单的,那如果工程有上百个头文件/C文件呢?还有相关的依赖库?是不是很麻烦
如果说,增量去编写还能接受的话,那么时间一长,回过头来回顾,或者移交给他人,都是件麻烦的事, 是不是?
那能不能自动生成和维护该Makefile文件,它的核心思想是什么?又该如何去实现? 请期待下文......