Makefile
1. 简介
Makefile文件定义了一系列规则来指定文件的编译规则,比如先编译哪些文件后编译哪些文件/哪些文件需要重新编译等。实际工程中,单个项目中会含有多个源文件,如果手动进行编译过于麻烦,而Makefile则实现了编译自动化,通过编写/修改Makefile文件,从而只需要一个指令即可实现文件的自动编译。
命名规则:
makefile
/Makefile
.书写规则
单个makefile文件可以有若干个规则
目标 ...: 依赖 ... 命令 (shell命令) ...
- 目标:最终要生成的文件
- 依赖:生成目标所需要的文件或目标
- 命令:通过执行命令对依赖操作生成目标(命令前必须要有Tab缩进.)
实例
app: main.o minus.o plus.o multi.o divi.o gcc main.o minus.o plus.o multi.o divi.o -o app minus.o: minus.c gcc -c minus.c -o minus.o plus.o: plus.c gcc -c plus.c -o plus.o multi.o: multi.c gcc -c multi.c -o multi.o divi.o: divi.c gcc -c divi.c -o divi.o main.o: main.c gcc -c main.c -o main.o
2. 工作原理
执行命令前,先检查规则中的依赖是否存在:
- 若存在,则执行命令
- 若不存在则向下查找是否有命令用于生成该依赖,若存在则运行该命令
- 其他规则一般是为第一条规则服务,即默认执行第一条规则,如果其下的命令与第一条规则无关,则不会执行该命令。
检测更新:减少对其他未修改的文件的编译,提高编译效率
- 如果规则的依赖比目标生成时间更晚,则需要重新生成目标。
- 如果规则的依赖比目标生成时间更早,则无需运行该规则。
3. 变量
自定义变量
变量名=变量值:
var=hello
预定义变量
AR
: 归档维护程序的名称,默认值为arCC
:c编译器的名称,默认为ccCXX
: C++编译器的名称,默认为g++$@
:目标的完整名称$<
:第一个依赖文件的名称$^
:所有依赖文件
如:
app: main.c a.c b.c c.c gcc -c main.c a.c b.c c.c
等价于app: main.c a.c b.c c.c $(CC) -c $^ -o $@
获取变量值:
$(变量名)
实例
# 定义变量 src=main.o minus.o plus.o multi.o divi.o target=app $(target): $(src) $(CC) $(src) -o $(target) %.o:%.c $(CC) -c $< -o $@
4. 函数
$(wildcard PATTERN ...)
- 功能:获取指定目录下指定类型的文件列表
- 参数:PATTERN为某个或多个目录下的对应某种类型的文件,如果有多个文件则用空格间隔
- 返回:得到若干个文件的文件列表,其中文件名之间用空格间隔
$(patsubst <pattern>, <replacement>,<text>)
- 功能:查找
<text>
中的单词(以空格、Tab、回车、换行为间隔)是否符合<pattern>
,如果匹配,则以<replacement>
替换。 <pattern>
可以包括%
通配符,表示任意长度的字符串- 返回:函数返回替代后的字符串
- 功能:查找
clean
:无需任何依赖实例
# 定义变量 src=$(wildcard./*.c) objs=$(patsubst %.c, %.o,$(src)) target=app $(target): $(objs) $(CC) $(objs) -o $(target) # 编译生成依赖 %.o:%.c $(CC) -c $< -o $@ # 清除依赖文件 .PHONY:clean # 伪目标 clean: rm $(objs) -f