一、 为什么需要 Makefile?
上一节学了 GCC 编译,但如果一个项目有几十个源文件,且每次只改了一个文件,手动敲 gcc 命令重新编译所有文件是非常低效的。
Makefile 解决了两个大问题:
-
把复杂的编译命令封装起来,只需敲一个
make就能编译整个项目。 -
实现"增量编译":它通过对比源文件和目标文件的修改时间,只编译修改过的文件。
二、 Makefile 的编写规则
核心公式是:目标 : 依赖,换行后写 命令。
⚠️ 最大的天坑 :命令前面必须按 Tab 键 ,绝对不能用空格,否则会报错 missing separator。
三、 实战演示
1. 最基础的 Makefile
cpp
hello: hello.c
gcc hello.c -o hello
执行 make,系统会自动调用对应的 gcc 命令。
2. 伪目标 .PHONY
当我们需要执行一些清理动作(如 make clean 删除编译产物)时,为了防止同名的文件干扰,需要声明伪目标。
cpp
.PHONY: clean
clean:
rm -f hello
声明为 .PHONY 后,make clean 总是会被无条件执行。
3. 使用变量优化
为了让 Makefile 更具扩展性,我们可以引入变量:
cpp
BIN = hello
SRC = hello.c
$(BIN): $(SRC)
gcc $(SRC) -o $(BIN)
.PHONY: clean
clean:
rm -f $(BIN)
总结
make 是一个命令,Makefile 是一个规则文件。它通过比较文件的 Modify 时间(修改时间)来决定是否重新编译,极大地提升了开发效率。
自我实战操作
linux_study/gcc_test 目录里操作。
实战 1:写第一个 Makefile
bash
cd ~/linux_study/gcc_test
vim Makefile # 注意首字母大写,或者全小写 makefile 也行
在 Vim 里(按 i 进入插入模式),输入以下内容:
(注意:第二行的开头必须按一下键盘上的 Tab 键,千万别敲空格!)
cpp
hello: hello.c
gcc hello.c -o hello
按 Esc,输入 :wq 保存退出。

实战 2:使用 make 编译
bash
# 1. 删掉之前手动编译的旧文件,确保干净
rm -f hello
# 2. 直接敲 make 命令
make
# 输出:gcc hello.c -o hello (它自动读取了 Makefile 并执行了里面的命令)
# 3. 验证一下程序
./hello
实战 3:体验 Make 的"智能"特性
bash
# 1. 再次敲 make
make
# 输出:make: 'hello' is up to date. (它会说 hello 已经是最新的了,不重复编译,省时间!)
# 2. 我们用 touch 修改一下 hello.c 的修改时间
touch hello.c
# 3. 再次 make
make
# 输出:gcc hello.c -o hello (它发现 hello.c 比 hello 新,于是重新编译了!)
实战 4:加入伪目标 clean
重新编辑 Makefile:
bash
vim Makefile
改成这样(注意 rm 前面依然是 Tab):
cpp
hello: hello.c
gcc hello.c -o hello
.PHONY: clean
clean:
rm -f hello
保存退出后,测试一下:
bash
make clean # 会执行 rm -f hello,把程序删掉
ls # 发现 hello 没了
实战 5:Makefile 进阶语法(变量)
前面的代码写死了 hello.c,如果有多个文件,每次改 Makefile 太麻烦。我们用变量优化(这部分面试提到会加分):
cpp
# 定义变量
BIN = hello
SRC = hello.c
$(BIN): $(SRC)
gcc $(SRC) -o $(BIN)
.PHONY: clean
clean:
rm -f $(BIN)
(注意:Makefile 里的变量赋值和引用,跟 Shell 脚本略有不同,直接写 变量名 = 值,引用用 $(变量名))


