makefile
规则
变量
函数
条件执行
文件,文件名处理函数
文件包含
注释
解析阶段:
- 解析makefile,建立依赖关系树
- 控制解析过程:引入makefile,变量展开,条件执行
- 生成关系树
编译阶段:根据依赖关系树和时间戳编译
- 载入关系树
- 根据关系树和时间戳,执行操作
规则
作用:
目的:生成依赖关系树
目标:依赖
- 规则可以无依赖,仅仅实现某种操作
- 规则可以无命令,仅仅描述依赖关系
- 规则必须有一个目标,可以有多个目标
隐式规则
make预定义了一些规则,如将.c编译成.o
hello:hello.o
gcc -o hello hello.o
上面没有定义 hello.o的规则,但是可以生成make,
因为make以定义了%.o的规则,
所以上面的makefile相当于
hello:hello.o
gcc -o hello hello.o
hello.o:hello.c
gcc -o hello.o -c hello.c
目标
默认目标
第一个目标为默认目标
合并目标
多个目标,具有相同规则,相同依赖,会被合并为一个目标
all:a1 a2
a1:a3
echo "1111"
a2:a3
echo "1111"
被合并为
all:a1 a2
a1 a2:a3
echo "1111"
合并依赖
目标相同,依赖不同,合并依赖,注意,目标不能有规则
all:a1
all:a2
a1:
echo "1111"
a2:
echo "2222"
合并为
all:a1 a2
a1:
echo "1111"
a2:
echo "2222"
伪目标
不比较是否重新执行,可无条件执行
依赖
更新
非伪目标时,依赖文件时间戳新于目标文件时间戳,执行操作
隐式依赖
%.o:%.c
模式匹配
命令
shell命令组成,tab开头
每条命令,make开一个进程
进程执行完,make检查返回码,
成功则继续执行,失败则退出
变量
定义
CC=gcc
赋值
追加赋值 +=
条件赋值 ?= ,若没有赋值,则赋值
引用
$(CC) ${CC}
立即展开变量
使用:=,在解析阶段直接赋值常量字符串
延迟展开
使用=,在运行阶段 使用 运行时值赋值
注意:
通常,目标,依赖 使用立即展开变量,命令 中使用延迟展开
作用域
一般变量:全局变量
目标变量:规则作用域
N=0
all:a1 a2
a1:N=1
a1:
echo "a1 N=${N}"
a2:
echo "a2 N=${N}"
模式变量
N=0
all:a1 a2
a%:N=1
b%:N=2
%:
echo "$@ N=${N}"
自动变量
为局部变量
目标:$@
所有依赖:$^
第一个依赖 : $<
环境变量
所有makefile可以直接引用,
若makefile定义了同名变量,则覆盖
变量传递
- 递归make
make -C subdir
相当于
cd subdir && make - 通过export传递变量
- 通过命令行传递变量
条件执行
- 关键字
ifeq else endif ifneq
ifeq($(DEBUG), true)
CC=gcc -g
else
CC=gcc
endif
函数
函数名,参数,返回值
返回值为字符串
$(函数名 参数1, 参数2, 参数3)