什么是Makefile
- 一个工程中的源文件不计其数.其按类型、功能、模块分别放在若干个目录中,Makefile文件定义了一系列的规则来指定哪些文件要生编扁i译.哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 Makefile文件就像一个Shell 脚本一样,也可以执行操作系统的命
- Makefile带来的好处就是“自动化编译”,一旦写好只需要一个make命令,整个工程完全自动编译.极大的提高了软件开发的效率。make 是一个命令工具,是一个解释Makefile文件中指令的命令工具,一般来说,大多数的IDE都有这个命令.比如Delphi 的 make,Visual C++的nmake,Linux 下GNU的make。
Makefile文件命名和规则
文件命名
makefile 或者 Makefile
Makefile 规则
一个Makefile文件中可以有一个或者多个规则
目标 …:依赖 … (… 表示多个依赖)
(Tab)命令(Shell 命令)
…
- 目标 : 最终要生成的文件(伪目标除外)
- 依赖 :生成目标所需要的文件或者是目标
- 命令 :通过执行命令对依赖操作生成目标(命令前必须 Tab 缩进)
make安装
sudo apt install make
make 使用 - 第一版 Makefile
1 | app:sub.c add.c mult.c div.c main.c |
sub.c
1 |
|
mult.c
1 |
|
div.c
1 |
|
main.c
1 |
|
head.h
1 |
|
工作原理
- 命令在执行前,需要检查规则中的依赖是否u才能在
- 如果存在,执行命令
- 如果不存在,向下检查其它命令规则,检查有没有一个规则用来生成这个依赖的,如果找到则执行该规则中的命令
- 检测更新,在执行规则的命令时,会比较目标和依赖的文件的时间(直接输入 make)
- 如果依赖的时间比目标时间晚,需要重新生成目标
- 如果依赖的时间比目标时间早,目标不需要更新,对应规则中的命令不需要执行
第二版 Makefile
1 | app:sub.o add.o mult.o div.o main.o |
变量
自定义变量
变量名 = 变量值 var = hello $(var)
预定义变量
AR : 归档维护程序的名称,默认值 ar
CC : C 编译器的名称,默认值为 cc
CXX : C++ 编译器的名称。默认值为 g++
$@ : 目标的完整名称
$< : 第一个依赖文件名称
$^ : 所有依赖文件
获取变量的值
$(变量名)
1 | app:main.c a.c b.c |
第三版 Makefile
1 | # 定义变量 |
模式匹配
1 | # %.o:%.c |
第四版 Makefile
1 | # 定义变量 |
函数
$(wildcard PATTERN…)
功能:获取指定目录下指定类型的文件列表
参数:PATTERN指的是某个或多个目录下的对应的某种类型的文件,如果有多个目录,一般使用空格间隔
返回:得到的若干个文件的文件列表,文件之间使用空格间隔
示例
$(wildcard *.c ./sub/*.c)
(第一个*.获取当前目录下的所有.c文件 第二个是./sub 下的所有文件 多个目录可以用空格隔开)返回值格式:a.c b.c c.c d.c f.c
$(patsubst <pattern>, <replacement>, <text>)
功能:查找<text>中的单词(单词以”空格”、”Tab”或”回车””换行”分割)是否符合模式<pattern>,如果匹配的话,则可以<replacemnt>替换。
<sattern>可以包括通配符
$
,表示任意长度的字串。如果<replacement>中包含$
,那么,<replacemnt>中的这个$
将是<pattern>中的那个$所代表的字串。(可以用’\‘来转义,以’\%’来表示真实含义的’%’字符)返回:函数返回被替换过的字符串
示例:
$(patsubst %.c, %.o, x.c bar.c)
返回值格式:x.o bar.o
第五版 Makefile
1 | # 定义变量 |
第五版 Makefile
1 | # 定义变量 |
第六版 Makefile
1 | # 定义变量 |