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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?