目录
- 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力;
- 一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作;
- makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率;
- make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建;
当执行make命令时,需要一个Makefile文件,makefile文件告知make命令需要如何编译和链接程序,makefile文件的基本语法如下:
目标文件:依赖文件列表
Tab键 shell指令
用户在当前工作目录下新建文件名为makefile/Makefile的文件,makefile文件第一行指明依赖关系(目标文件test的形成所依赖的文件为test.c)第二行指明依赖方法(生成目标文件test所需要进行的指令);
注意:
- 目标文件可以具有多个依赖文件,也可以没有依赖文件;
- 依赖方法中的shell指令可以没有,也可以有多条指令,如果写多条指令,每条指令写一行; ??
1. make指令首先在当前工作目录下查找文件名为"Makefile"或"makefile"的文件;2. 找到makefile/Makefile文件后,会将makefile/Makefile文件中的第一个目标文件作为最终的目标文件;3. 如果目标文件不存在或者依赖文件的文件内容的修改时间(Modify time)要比目标文件的文件内容的修改时间(Modify time)新,那么,make会执行后面所定义的指令来生成目标文件;
makfile具有两个目标文件,分别为test与tmp,当使用make指令形成目标文件时,到底形成哪一个目标文件?可以形成多个目标文件吗?
总结:使用make指令形成目标文件时,默认是从上到下扫描makefile文件,默认形成的是第一个目标文件,默认形成的目标文件只有1个即最终的目标文件;
若想形成makefile文件中除第一个目标文件外的其余的目标文件,使用make 目标文件名
目标文件test的形成依赖于test.s文件,而test.s文件的形成依赖于test.c文件,当使用make指令形成最终的目标文件 test 时,会先执行哪种依赖方法?
?先执行依赖文件作为目标文件的的依赖方法,再执行目标文件本身的依赖方法;
Makefile文件中应该写一个清空目标文件(.o和执行文件)的指令,有利于重新编译文件;
clean:
rm -f 目标文件名
clean只是一个动作的名字,其冒号后没有依赖文件,那么,make指令不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令,要执行其后的命令,使用make clean;
在当前工作目录下新建一个文件名为clean的文件,使用make clean这条指令执行makefile文件的clean的动作,会发生什么?
当makefile文件中存在clean这个动作名,当在当前路径下创建文件名为clean的文件即touch clean,生成clean文件之后,这时如果使用 make clean 指令,无法执行 makefile文件中的 clean动作;
为了避免makefile文件中的动作名和文件名冲突的这种情形,使用关键字".PHONY"来显示地指明一个目标是"伪目标",向make说明,无论该文件是否存在,这个目标就是"伪目标";
.PHONY:clean
clean:
rm -f 目标文件名
当使用关键字".PHONY"修饰目标文件时,该目标文件总是可以被执行,想执行多少次便可以执行多少次;
注:clean的规则置于makefile文件末尾;
makefile中的定义的变量,与C/C++的宏类似,代表了一个文本字符串,在makefile中执行的时候其会自动展开在所使用的地方,但是变量可以在makefile中改变其值;
变量的名字可以包含字符、数字,下划线(可以数字开头),但不应该含有":"、"#"、"="或空字符(空格、回车等),变量命名通常采用大小写搭配的形式;
变量的定义规则:变量名=变量值
变量的使用规则:$(变量名)
$@ #目标文件
$^ #所有依赖文件
$< #第一个依赖文件
makefile自动推导是指在makefile中,当make命令看到一个目标文件(.o文件)时,它会自动将对应的源文件(.c文件)作为依赖文件加入到依赖关系中,这种规则被称为makefile的隐晦规则;
用户在当前工作目录下实现test.c文件,用户在makefile中只写出目标文件和编译命令,而不需要显式地列出依赖关系,make命令会自动推导出test.o的依赖文件是test.c,并根据编译命令生成目标文件;