1、为什么要使用makefile
- 在编译项目时,gcc相关参数非常多,如gcc *.c -I include -Wall -g -03 -D DEBUG -…..
- 这是一个代码管理工具,外部编译时只需要执行makefile即可
- 屏蔽编译的复杂过程,源代码以最简单的方式生成可执行程序
2、makefile的规则
- 三要素:目标、依赖、命令
- 第一条规则是用来生成终极目标的规则
- 如果规则中的依赖不存在,向下寻找其他的规则;
- 更新机制:比较的是目标文件和依赖文件的时间;
- 两个函数:
- 查找指定目录下,指定类型的文件:
src=$(wildcard ./*.c)
- 匹配替换函数
obj=$(patsubst %.c, %.o, $(src))
// 将.c文件重命名为.o文件
- 三个自动变量
- $<:规则中的第一个依赖
- $^:规则中的所有依赖
- $@:规则中的目标
- 模式规则
- %.o:%.c
- gcc -c %< -o $@
3、几个示例版本
- 版本一、最简单的makefile
#冒号前为目标,后面为依赖 app:main.c add.c sub.c #加tab缩进后面写的内容为命令 gcc *.c -g -o main.out
- 使用make命令执行makefile中的内容
-
版本二、最简单的makefile等价于:
app:main.o add.o sub.o gcc main.o add.o sub.o -g -o main.out main.o:main.c gcc -c main.c add.o:add.c gcc -c add.c sub.o:sub.c gcc -c sub.c
- 分依赖的好处在没有修改过的地方不会重复编译
-
第一条为终级目标,向下寻找依赖,向上执行命令
-
版本三、使用变量继续优化,使用变量
obj=main.o add.o sub.o target=app $(target):$(obj) gcc $(obj) -o $(target) %.o:%.c gcc -c $< -o $@ #makefile中的自动变量,只能在命令中使用 #$<:第一个依赖 #$@:规则中的目标 #$^:规则中的所有依赖 #gcc $(obj) -o $(target)还可以写成gcc $^ -o $@
- 版本四、使用函数来动态编译
#目标变量 target = app #依赖变量 #obj = main.o add.o sub.o #依赖变量可通过函数wildcard实现获取,函数名后面直接跟参数 #1、获取所有.c文件 src = $(wildcard ./*.c) #2、将所有的.c替换成.o,使用函数patsubst obj = $(patsubst %.c, %.o, $(src)) #终极目标,生成app $(target):$(obj) gcc $(obj) -o $(target) #中间目标通用公式 %.o:$.c #$< 表示第一个依赖 #$@ 表示规则中的目标 gcc -c $< -o $@ #添加一个伪目标(不比较生成文件的新旧),清理旧文件 .PHONY:clean clean: #命令前面加个“-”表示如果执行失败直接忽略,否则将在当前停止 -rm -f $(target) $(obj)