《跟我一起写makefile》笔记1~3章
第一章 概述
1、makefile关系整个工程的编译规则,实现“自动化编译”。
2、跟Shell脚本一样,也可执行操作系统的命令。
3、make:是一个解释makefile指令的命令工具
一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
不同产商的make各不相同,也有不同的语法,但其本质都是在“文件依赖性”。
这里,仅对GNU的make进行讲述(应用最为广泛,且最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。)
环境是RedHat Linux 8.0,make的版本是3.80。
默认的编译器是UNIX下的GCC和CC。
第二章 关于程序的编译和链接
1、首先(.c/.h) 经过预编译/编译,生成(.obj/.o)
2、然后通过链接(Link),将.obj(.o)和.lib(.a)/.dll(.so)链接成可执行文件
(Windows .exe,Linux/unix下随意)。
3、其它:.obj/.o可以生成库文件.lib/.a,多个库文件还可以进行合并。
源文件(.c/.h)
目标文件(.obj/.o)
静态链接库(.lib/.a)
动态链接库(.dll/.so)
可执行文件(.exe/…)
4、扩展:
内核驱动模块文件(.ko: kernel object)
(如何生成.ko----https://blog.****.net/qq_38880380/article/details/79227760)
第三章 Makefile 介绍
一、Makefile的规则
Target:目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label),对于标签这种特性,在后续的“伪目标”章节中会有叙述。
Prerequisites(预备材料,先决条件):生成target所需要的文件或是目标。
Command:make需要执行的命令(任意的Shell命令)。
规则:如果Target不存在,或者prerequisites中有文件比target文件新,则command所定义的命令就会被执行。
二、一个示例
写一个Makefile来告诉make命令如何编译和链接这几个文件。规则如下:
1)如果工程未编译,那么所有C文件都要编译并被链接。
2)如果工程的某几个C文件被修改,那么只编译被修改的C文件,并链接目标程序。
3)如果工程的头文件被修改,那么引用了这几个头文件的C文件需要编译,并链接目标程序。
- 创建文件并命名为“Makefile”或“makefile”
- 内容如上图,命令行要以一个Tab键开头
- 在该目录下直接输入命令“make”,就可以生成执行文件edit
- Clean:不是一个文件,它只不过是一个动作名字,像C语言中的lable,冒号后什么也没有,make不会自动去找文件的依赖性,也不会自动执行后面的命令。
只有在make命令后面指出这个lable,make才会去执行这个命令。
这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。
三、make是如何工作的
在默认的方式下,也就是我们只输入make命令。那么,
1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
3、如果edit文件不存在,或是edit所依赖的后面的[.o]文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
4、如果edit所依赖的.o文件也存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。(这有点像一个堆栈的过程)
5、当然,你的C文件和H文件是存在的啦,于是make会生成 .o 文件,然后再用 .o 文件生成make的终极任务,也就是执行文件edit了。
这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
四、makefile中使用变量
变量的声明和使用如下:
五、让make自动推导
GNU的make可以根据Target,自动推导所需要的依赖文件和执行命令。
只要make识别到[.o]文件,就会自动的把[.c]文件加在依赖关系中,
如:make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件,并且命令 cc -c whatever.c 也会被推导出来。
这种方法,也就是make的“隐晦规则”。
上面文件内容中,“.PHONY”表示clean是个伪目标文件。
六、另类风格的makefile
使用make的“隐晦规则”,将重复使用的依赖文件.h收拢:
缺点:
(1)文件的依赖关系看不清楚
(2)加入新的.o文件时,.h依赖关系要重新修改。
七、清空目标文件的规则
每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。
一般的风格都是:
clean:
rm edit $(objects)
更为稳健的做法是:
.PHONY : clean
clean :
-rm edit $(objects)
前面说过,.PHONY意思表示clean是一个“伪目标”。而在rm命令前面加了一个小减号的意思就是,也许某些文件出现问题,但不要管,继续做后面的事。
clean的规则不要放在文件的开头,不然就会变成make的默认目标,相信谁也不愿意这样。不成文的规矩是——“clean从来都是放在文件的最后”。