Makefile Cheatsheet - Build Automation

Makefile 是 C/C++ 项目最常用的构建工具,也广泛用于自动化任务。按语法分类整理常用写法。

SysOps·42 commands·Last updated 2026-07-19
Back to SysOps

变量与赋值 6

CC = gcc
递归展开变量,引用时才展开(可能有副作用)
CC := gcc
简单展开变量,定义时就展开(推荐)
CC ?= gcc
条件赋值,变量未定义时才赋值
CFLAGS += -Wall
追加值到变量末尾
export PATH := /opt/bin:$(PATH)
导出变量到子进程环境
$(CC) 或 ${CC}
引用变量,圆括号与花括号均可

自动变量 7

$@
当前目标名
$<
第一个依赖
$^
所有依赖(去重)
$+
所有依赖(含重复)
$*
模式规则中 % 匹配的部分
$?
比目标更新的依赖列表
$(@D) / $(@F)
目标的目录名 / 文件名部分

规则与目标 5

target: deps\n\trecipe
基本规则:目标、依赖和配方
.PHONY: clean install
声明伪目标,避免与同名文件冲突
all: prog1 prog2
默认目标(第一个非点开头的目标)
clean:\n\trm -f *.o $(TARGET)
清理目标文件
install: target\n\tcp target /usr/local/bin
安装目标到系统路径

模式规则 5

%.o: %.c\n\t$(CC) -c $< -o $@
通配规则:所有 .o 由同名 .c 生成
%.o: %.c $(HDRS)
为模式规则添加额外依赖(头文件)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
跨目录的模式规则
OBJS := $(SRCS:.c=.o)
变量替换引用,批量改后缀
$(OBJS): obj/%.o: src/%.c
静态模式规则,显式指定目标列表

内置函数 8

$(wildcard *.c)
展开通配符,获取匹配的文件列表
$(patsubst %.c,%.o,$(SRCS))
模式替换:把 .c 后缀换成 .o
$(filter %.c %.h,$(SRCS))
过滤出匹配模式的单词
$(filter-out %.test,$(SRCS))
反向过滤,排除匹配项
$(strip $(string))
去除字符串首尾空格
$(shell date +%Y)
执行 shell 命令并返回输出
$(subst from,to,text)
文本替换(非模式,直接匹配)
$(foreach var,list,text)
遍历列表生成文本

条件判断 5

ifeq ($(OS),Windows_NT)\n...\nendif
相等判断
ifneq ($(CC),gcc)\n...\nendif
不等判断
ifdef DEBUG\nCFLAGS += -g\nendif
变量已定义则执行
ifndef RELEASE\n...\nelse\n...\nendif
带 else 的条件分支
$(if $(DEBUG),-g,-O2)
条件函数:成立返回第二参数,否则第三参数

实用示例 6

SRCS := $(wildcard src/*.c)\nOBJS := $(SRCS:.c=.o)
自动收集源文件并生成目标列表
include config.mk
包含其他 Makefile,适合拆分配置
.DEFAULT_GOAL := install
显式设置默认目标
vpath %.c src:src2
为指定后缀设置搜索目录
make -j4
并行构建,4 个任务同时跑
make CFLAGS="-O2 -g"
命令行覆盖变量(优先级最高)

💡 Tips

  • Makefile 的配方行必须以 Tab 开头,不能用空格,这是最常见的错误。
  • .PHONY 声明的目标不会检查同名文件是否存在,适合 clean、install 等操作。
  • $@ 代表目标,$< 代表第一个依赖,$^ 代表所有依赖,这三个自动变量最常用。
  • := 是立即展开,= 是延迟展开;复杂 Makefile 中推荐用 := 避免递归副作用。
  • include other.mk 可以引入其他 Makefile,适合大型项目拆分配置。
  • 命令行变量会覆盖 Makefile 中的赋值,用 override 关键字可防止被覆盖。