1. 前言·
本文并不会介绍Makefile
的基础使用方法,不过对于初次接触Makefile
的同学们,这里推荐阅读《跟我一起写Makefile》,全书一共80来页,从Makefile的基础用法到进阶使用都讲解得比较通透。
Makefile
简介:一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,Makefile
定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。--------------摘自百度百科
2. C/C++项目Makefile模板·
结合《跟我一起写Makefile》,我常用的Makefile模板如下:
1 | CC := gcc |
这里讲解一下这个模板的几个变量:
CC
:使用的编译器,gcc/g++/arm-linux-gcc
等等CFLAGS
: 编译器参数LIB
: 项目中所使用到的各个库INCLUDE
: 项目头文件
再看看几个代码片段,大多数都是生成中间文件,.o文件
。这中间有一串很难看的代码— %.d : %.o
下面这一块,但是其实不用管它具体是怎么运行的,你只用知道它是用于生成各个文件之间的依赖关系的就行了 (其实关键在于 -MM 参数),用于辅助编译的。对于爱学习想深究的那些同学们,可以阅读《跟我一起学Makefile》,查看一下生成出来的.d文件,应该也就懂了。
另外,给一个建议:
其实很多时候并不需要我们书写Makefile
,反而是需要书写gcc
编译规则,比如添加的头文件在哪儿?代码所需要的库文件在哪儿?又需要链接那些库? 搞懂gcc
编译中常用的参数,直到能够回答上面三个问题,再来书写Makefile
就会容易很多了。
简单回答一下上面三个问题,具体的实施,需要自己去实际敲代码,用命令编译一下才知道。
-
找到头文件:
gcc
编译器中有-I
参数,后面跟的路径就是头文件路径。 -
找到库文件:
gcc
编译器中有-L
参数,后面跟的路径就是库文件路径的,当然linux
环境下,gcc
也会自动到根目录和usr
目录下的lib
下找库文件。 (库文件包括静态库后缀为.a
,动态库后缀为.so
,两者的区别在于,前者在编译过程中就一起链接到可运行程序中,造成最终的程序过大,但便于移植。后者则不链接到可运行程序中,而是在运行时到环境中去寻找该库,所以可运行程序较小,但是不便于移植,使用这样的程序就需要自己要安装一些动态库) -
链接库:光是找到库文件所在地还不够,需要指明需要链接哪些库,gcc编译器中有
-l
参数,后面跟你要链接的库。需要注意的一点是,linux下的库文件有命名规则,文件开头必须是lib
,例如我有一个字体库,那么文件可为libfont.a
或libfont.so
,另外我们还可能看见动态文件名后面带数字,如libfont.so.2
,这里最后一个数字代表了这个库的版本。
最后再来看一下上文给的模板的上半段:
1 | CC := gcc |
这段的意思是,本项目使用gcc编译,编译后的结果可调试(-g
),并且打印编译过程中的所有警告(-Wall
),项目的头文件放在./lib
(别忘了gcc
还会到根目录和/usr
的lib
去寻找哦),在这些库文件中我要链接xml2,jpeg
库,头文件放在了./include和./
下。