文章目录
一、概述
二、编写
1)文件的命名规则
- makefile
- Makefile
2)用途
- 项目代码编译管理
- 节省编译项目的时间
- 一次编写终身受益
3)基本规则
目标:依赖
(tab)命令
- 目标 -->要生成的目标文件
- 依赖 -->生成目标文件需要的一些文件
- 命令 -->借助依赖文件生成目标文件的手段
- tab -->缩进,有且只有一个
Makefile会把规则中的第一个目标作为终极目标
- all:app -->all指定生成的最终目标为app
4)工作原理
- 若想生成目标,检查规则中的依赖条件是否存在,如果不存在,寻找是否有规则用来生成该依赖文件
- 检查规则中的目标是否需要更新,必须检查它的所有依赖,依赖中有任意一个被更新,则目标必须更新
- 依赖文件比目标文件时间晚,则需要更新
5)执行
- make -->通过 makefile 生成目标文件
- 直接 make(使用 makefile 文件)
- make -f mm(指定一个名字不为 makefile 的文件)
- make clean -->清除编译生成的中间 .o 文件和最终目标文件
- 如果当前目录下有同名 clean 文件,则不执行 clean 对应的命令
- 解决方案 -->伪目标声明。如:
.PHONY:clean
- 解决方案 -->伪目标声明。如:
- 特殊符号
- -:表示此条命令出错,make 也会继续执行后续的命令。如:
-rm a.o b.o
- -:表示此条命令出错,make 也会继续执行后续的命令。如:
- 如果当前目录下有同名 clean 文件,则不执行 clean 对应的命令
6)变量
- 普通变量
- 变量定义及赋值:
obj=a.o b.o c.o
- 变量取值:
foo=$(obj)
- 由 Makefile 维护的一些变量
- 通常格式都是大写
- CC:默认值cc
- 有些有默认值,有些没有
- CPPFLAGS:预处理器需要的选项 如:-I
- CFLAGS:编译的时候使用的参数 -Wall -g -c
- LDFLAGS:链接库使用的选项 -L -I
- 用户可以修改这些变量的默认值
- CC=gcc
- 通常格式都是大写
- 变量定义及赋值:
- 自动变量
- 变量
- $@ -->规则中的目标
- $< -->规则中的第一个依赖条件
- $^ -->规则中的所有依赖条件
- 模式规则
- 在规则的目标定义中使用%
- 在规则的依赖条件中使用%
- 实例:(%表示一个或多个)
-
%.o:%.c $(CC) -c $< -o $@
- $< -->表示依次取出依赖条件
- $@ -->表示依次取出目标值
-
- 变量
7)函数
- makefile中所有的函数必须都有返回值
- wildcard
- 查找指定目录下指定类型的文件,一个参数
-
src=$(wildcard ./src/*.c)
- 找到 ./src 目录下所有后缀为 .c 的文件,赋给变量 src
- patsubst
- 匹配替换,从 sec 中找到所有 .c 结尾的文件,并将其替换为 .o
-
obj=$(patsubst %.c,%.o,%(src))
- 把 src 变量中所有后缀为 .c 的文件替换成 .o
-
ob=$(patsubst ./src/%.c,./obj/%.o,%(src))
- 指定 .o 文件存放的路径 ./obj/%.o
三、实操
第一版makefile
第二版makefile
可以考虑编译过程分解,先生成 .o 文件,然后使用 .o 文件变成结果
第三版makefile
定义变量
Makefile隐含规则:默认处理第一个目标
第四版makefile
函数
- wildcard:可以进行文件匹配
- patsubst:内容的替换
makefile变量
- $@: 代表目标
- $^ : 代表全部依赖
- $< : 第一个依赖
- $? : 第一个变化的依赖
第五版makefile
- 添加清理功能(@在规则前作用)
- “-”的作用就是,即使该条规则报错,仍然继续执行
- 防止有歧义, 定义伪目标
Final版makefile
# get all .c file
SrcFiles=$(wildcard *.c)
# all .c files ---> .o files
ObjFiles1=$(patsubst %.c,%.o,$(SrcFiles))
all:app.out
# 目标文件用法 $@: 目标;$<: 依赖
app.out:$(ObjFiles1)
gcc -o $@ -I./include $(ObjFiles1)
# 模式匹配规则, $@,$<这样的变量,只能在规则中出现
%.o:%.c
gcc -c $< -I ./include -o $@
test:
@echo $(SrcFiles)
@echo $(ObjFiles1)
# 定义伪目标,防止有歧义
.PHONY:clean all
# 添加清理功能
clean:
-@rm -f *.o # 加 @表示指令不输出
-@rm -f app.out