【Linux】Makefile:让编译自动化

当项目只有一个 hello.c 时,手动敲 gcc 命令没有负担。但当源文件增加到几十个、上百个,分布在不同的目录里,而且有复杂的依赖关系时,每次手动编译就变成了效率黑洞。

Makefile 定义了源文件之间的依赖关系和编译规则,然后通过 make 命令执行自动化构建。它最核心的用途是只重新编译那些被修改过的文件,而不是整个项目重新来过。

1. 一个最简 Makefile

makefile

复制代码
myproc: myproc.c
	gcc -o myproc myproc.c

.PHONY: clean
clean:
	rm -f myproc

这里有两个目标(target):

  • myproc:依赖 myproc.c。依赖关系下面缩进的那行是依赖方法------具体要执行的命令。

  • clean:不依赖任何文件,执行 rm -f 清理生成的可执行文件。

make 默认执行文件中的第一个目标(这里是 myproc)。执行 make clean 则显式指定执行 clean 目标。

clean 被声明为 .PHONY,意思是它是一个伪目标 ,不代表一个真实的输出文件。伪目标的特性是"总是被执行"------无论 clean 文件是否已经存在,make clean 都会无条件运行。如果不加 .PHONY 且当前目录下恰好有一个叫 clean 的文件,make clean 可能会因为"依赖文件已最新"而拒绝执行。

2. 依赖推导:make 是如何工作的

make 的机制可以概括为"逐层检查与构建"。它从第一个目标开始,检查它依赖的文件是否存在、是否比目标更新。如果依赖不存在,则递归查找能生成该依赖的规则。如果依赖比目标新(说明源码修改过),则执行生成命令。

假如有这样一个文件体系:

makefile

复制代码
myproc: myproc.o
	gcc myproc.o -o myproc
myproc.o: myproc.s
	gcc -c myproc.s -o myproc.o
myproc.s: myproc.i
	gcc -S myproc.i -o myproc.s
myproc.i: myproc.c
	gcc -E myproc.c -o myproc.i

make 在构建myproc时会沿着依赖链一直往回推:

  1. 发现需要 myproc.o,但目录下没有,于是找生成 myproc.o 的规则。

  2. 发现需要 myproc.s,又没有,继续回溯。

  3. 最终追溯到底层的 myproc.c,然后按顺序执行:.c → .i → .s → .o → myproc

这样,如果只修改了一个源文件,make 只重编译受影响的目标,其它已经是最新的不会重复编译。

3. 变量与模式规则

重复写文件名容易出错,也不好维护。make 支持定义变量:

makefile

复制代码
BIN = myproc
CC = gcc
SRC = $(wildcard *.c)
OBJ = $(SRC:.c=.o)

$(BIN): $(OBJ)
	$(CC) -o $@ $^

%.o: %.c
	$(CC) -c $@ $<

.PHONY: clean
clean:
	rm -f $(OBJ) $(BIN)

几个关键点:

  • $(wildcard *.c):获取当前目录下所有 .c 文件名。

  • $(SRC:.c=.o):把 .c 后缀替换成 .o

  • $@:当前规则的目标文件名。

  • $^:当前规则的所有依赖文件名。

  • $<:当前规则的第一个依赖文件名。

  • %.o: %.c 是一个模式规则,对所有 .o 目标匹配同名的 .c 依赖。

@前缀放在命令前的作用是关闭命令本身的回显,让输出更干净,只显示像"linking..."、"compiling..."这样的关键信息。

这套写法写好以后,当源文件新增时 Makefile 通常不需要改动,这就是自动化构建的真正价值。

相关推荐
猫头虎3 小时前
【Trea】Trea国内版|国际版|海外版下载|Mac版|Windows版|Linux下载配置教程
linux·人工智能·windows·macos·aigc·ai编程·agi
Jinkxs3 小时前
LoadBalancer- 简单限流策略:Nginx 基于连接 / 请求的限流实现
java·运维·nginx
User_芊芊君子3 小时前
一条命令搞定 mysql_exporter 部署,Shell 脚本把重复配置这件事自动化了
android·mysql·自动化
流浪0013 小时前
告别静态打印:Linux C 实现实时刷新进度条
linux·运维·c语言
qq_196976173 小时前
硬核教程:用Gemini境像站构建端到端自动化办公工作流,告别重复操作(国内免费镜像实测)
运维·自动化
小此方3 小时前
Re:Linux系统篇(二十)进程篇·五:深入理解 Linux 进程优先级:从底层逻辑到实战修改
linux·运维·服务器
路溪非溪3 小时前
Linux下物理总线驱动模型之SDIO驱动框架
linux·驱动开发
深圳市九鼎创展科技3 小时前
九鼎创展 X7110 开发板(JH7110):国产 RISC-V 多媒体平台全解析
大数据·linux·人工智能·嵌入式硬件·ubuntu·risc-v
流浪0013 小时前
Linux篇(八) Make 与 Makefile 超详细入门教程|从零基础到手写自动化编译
linux·运维·自动化