makefile:
会不会写makefile,从一个侧面说明一个人是否具备完成大型工程的能力。因为makefile关系到整个工程的编译规则。一个工程中的文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,那些文件需要先编译,那些文件需要后编译,那些文件需要重新编译,甚至一些更复杂的功能操作,因为makefile就像一个shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处是----自动化编译,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发效率。make是以个命令工具,是一个解释makefile中指令的明林工具。
1、关于程序的编译和链接
首先要把源文件编译成中间代码文件,在window下是.obj文件,在linux下是.o文件,即object file这个动作叫做编译compile。然后大量的object file合成执行文件,这个动作叫做链接link。
编译时,编译器需要的是语法的正确,函数与变量的声明的正确。
链接时,主要是链接函数和全局变量。
总结下:
源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。在编译时,编译器只检测程序语法,和函数、变量是否被声明。在链接程序时,链接器会在所有的obj文件中寻找函数的实现。
2、make是如何工作的:
执行make后,make会在当前目录下找名字为"Makefile"或"makefile"的文件,如果找不到,它会找文件中第一个目标文件target。make会一层层的取找文件的依赖关系,直到最终编译出第一个目标文件。make不管所定义的命令的错误或者是编译不成功,make只管文件的依赖性。
像make clean中,clean在makefile文件中,没有被第一个目标文件直接或间接关联,那么它后面定义的命令将不会被自动执行,但可以通过加上make 执行。
3、makefile中使用变量:
makefile的变量也就是一个字符串,理解成C语言中的宏,差不多。
例:OBJ=main.o 1.o 2.o 3.o
main:$(OBJ)
gcc -o main $(OBJ)
4、让make自动推导:
GNNU的make很强大,它可以自动推导文件及文件依赖关系后面的命令。称为 隐晦规则。
5、清空目标文件的规则:
每个makefile中都应该写一个清空目标文件(.o和可执行文件)的规则,这个不仅便于重编译,也很利于保持文件的清洁。
.PHONY:clean
clean:
rm $(OBJ) MAIN
makefile总述:
一、makefile里主要包含了5个东西:显示规则、隐晦规则、变量定义、文件指示和注释。
1、显示规则。显示规则说明了,如何生成一个或多个目标文件。
2、隐晦规则。由make自动推导的功能。
3、变量的定义。变量一般都是字符串。
4、文件指示。
5、注释。makefile中只有行注释,和UNIX和Shell脚本一样,其注释是用"#"字符
最后,还值得一提的是,在makefile中的命令,必须要以Tab键开始。
二、makefile的文件名:
三、make的工作方式:
GNU的make工作时,执行步骤:
1、读入所有的Makefile。
2、读入被include的其它Makefile
3、初始化文件中的变量。
4、推导隐晦规则,并分析所有规则。
5、为所有的目标文件创建依赖关系链。
6、根据依赖关系,决定哪些目标要重新生成。
7、执行生成命令。
书写规则:
规则包含两个部分,一个是依赖关系,一个是生成目标的方法。
一般说来,make会以UNIX的标准Shell,也就是/bin/sh来执行命令。
在规则中使用通配符:
make支持3种通配符:"*", "?" 和 "[...]"。
波浪号~字符在文件名中有比较特殊的用途。例如"~/zrh",表示当前用户的$HOME目录下的zrh目录。而"~zrh/test"表示用户zrh的宿主目录下的test目录。
文件搜索:
在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。当make需要去寻找文件的依赖关系时,可以在文件前加上路径,但是最好的办法是把一个路径告诉make,让make在自动去找。
makefile文件中的特殊变量"VPATH"就是完成这个功能的。例:VPATH=src:../headers,指定了2个目录,"src"和"../headers"make会按顺序进行搜索。目录由"冒号"分隔。
多目标:
"$@"自动变量。表示目标的集合,就像一个数组,依次取出目标,并执行命令。
"$<"表示所有的依赖目标集
"$@"表示目标集