程序的生成可分为预处理 编译 汇编 链接这几个阶段,各个阶段的功能不再赘述。对于平时写的各种小程序,并不需要很精细的管理。如果某一处发生了改动,直接把所有文件把的所有阶段全都执行一遍。当工程比较小的时候怎么做没有问题,但一旦工程比较大,就需要选择性的进行编译、链接等操作,否则会消耗很多时间。当源码有改动时,只对改动所能影响到的文件进行重构,这就是增量编译的概念。 Makefile 可以简单的认为是一个工程文件的编译规则,描述了整个工程的编译和链接等规则。其中包含了那些文件需要编译,那些文件不需要编译,那些文件需要先编译,那些文件需要后编译,那些文件需要重建等等。编译整个工程需要涉及到的,在 Makefile 中都可以进行描述。换句话说,Makefile 可以使得我们的项目工程的编译变得自动化,不需要每次都手动输入一堆源文件和参数。 Makefile是Linux下进行多文件编程的必备技能。本篇博客给出了一种比较方便的Makefile方案,由于本人也是初学者,如果方案有任何不合理或者可改进之处,可进行指正,请大家多多支持。
在编写程序的时候,所做的改动无非就是源文件和头文件的改动。如果改动了源文件,则对应的目标文件和可执行程序就需要重新生成。比较麻烦的是头文件的改动,一旦头文件改动,那么任何包含它的源文件亦需要重新生成。 那么如何知道头文件会影响哪些源文件,或者说源文件依赖于哪些头文件呢?很幸运的是,gcc编译器有-MM选项,可以自动的得出源文件的依赖文件。 在本博客的Makefile里,就是利用了该功能,把依赖关系写进文件中,在通过读取文件的方式读入Makefile里。 本案例的Makefile包含以下相关知识:
Makefile的运行原理Makefile变量和函数的使用Makefile通配符 * %Makefile自动化变量 $@ $<Makefile搜索路径 vpathMakefile文件包含 -includeMakefile伪目标 .PHONYGCC编译器的 -c -MM功能以源码分享中的Makefile为例,其文件目录结构为 Makefile 就是含有源码的Makefile文件 obj文件夹 用于存放 目标文件.o 和 依赖文件 .d src文件夹 用于存放C语言源文件.c inc文件夹 用于存放C语言头文件.h bin文件夹 用于存放生成的可执行文件
当然,文件目录 可执行文件名 编译器 等等都可以进行修改,把所有文件存放在一个目录 或者 用多个文件夹存放源文件等也可以,只要在Makefile文件里修改对应参数即可。
由于本人的学识、时间和精力所限,对于静态库和动态库的支持还有待完善。在后续的改善中,可着手于对库文件使用和生成进行优化。