C++程序员必会知识
什么是makefile??
- 一个工程中的源文件不计其数,其按类型,功能,模块分别放在若干个目录中。
- Makefile文件定义了一系列的规则来指定哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为Makefile文件镜像一个shell脚本一样,也可以执行操作系统的命令。
- Makefile带来的好处就是"自动化编译",一旦写好只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
- make是一个命令工具,是一个解释Makefile文件中指令的工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make vc++的nmake Linux的GNU的make
下载安装make
sudo apt install make
makefile文件命名规则
- makefile
- Makefile
makefile的规则
规则中的三要素:目标、依赖、命令
- 目标:最终要生成的文件(伪目标除外 .PHONY:目标名)
- 依赖:生成目标所需要的文件或目标
- 命令:通过执行命令对所依赖文件操作生成目标(命令前必须Tab缩进)
格式
目标:依赖文件
命令
使用
make
编写一个简单的Makefile
案例1:
案例2:
注1:如果说下面的规则与终极规则没有关系,默认是不会执行的
注2:案例1和案例2相比,当某一个 .c 文件发生了改变,案例1所有的 .c文件都要重新编译
Makefile的工作原理
- 命令执行之前,需要检查规则中的依赖是否存在
- 如果存在,执行命令
- 如果不存在,向下检查其它的规则(规则由目标、依赖、命令组成),检查有没有一个规则是用来生成这个依赖的,如果有,则执行该规则中的命令
- 检查更新,在执行规则中的命令时,会比较目标文件和依赖文件的时间
- 如果依赖文件的时间比目标文件的时间晚,需要重新生成目标
- 如果依赖文件的时间比目标文件的时间早,目标不需要更新,规则中的命令不被执行
- 关系依赖树
- 执行流程图
- 更新流程图(有一个依赖文件保存时间比目标的后面,就执行命令进行目标更新)
Makefile中的变量
- 自定义变量
- 变量名 = 变量值
- 预定义变量(只能在命令中使用)
AR | 归档维护程序的名称,默认值为 ar(做静态库的时候用到了这个工具吧) |
CC | C编译器的名称,默认值为cc (gcc) |
CXX | c++编译器的名称,默认为g++ |
@ | 目标的完整名称 |
< | 第一个依赖文件按的名称 |
^ | 所有的依赖文件 |
- 获取变量的值
- $(变量名)
- 事例
app:main.c a.c b.c gcc main.c a.c b.c -o app 等价 app:main.c a.c b.c gcc $^ -o $@
- 模式匹配
- %.o:%.c
- %:通配符,匹配一个字符串,两个%匹配的是同一个字符串
Makefile中的函数
$(wildcard PATTERN...)
- 功能:获取指定目录下指定参数的文件列表
- 参数:PATTERN指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格隔开
- 返回:得到的若干个文件的文件列表,文件名直接使用空格隔开
- 示例:$(wildcard ../library/*.c ./*c)
$(patsubst <pattern>,<replacement>,<text>)
- 功能:查找<text>中的单词,是否符合pattern,如果匹配的话,则以<replacement>中的%将是<pattern>中的%
- 返回:函数返回被替换之后的字符串
- 示例:$(patsubst %.c,%.o,x.c b.c)
其它(清除不必要的临时文件)
声明伪目标 .PHONY:目标名
make 目标 ==》执行目标文件中特定的目标所对应的命令