最简C++编译规则为:app: main.cpp g++ -o app main.cpp;必须用Tab缩进命令,依赖变化时才重编,支持增量构建。

Makefile里怎么写最简C++编译规则
直接上手写 g++ 命令就能编译,但 Makefile 的价值在于「只重编改过的文件」。最基础的规则必须包含目标、依赖、命令三要素,缺一不可。
比如项目只有一个 main.cpp,想生成可执行文件 app,规则应写成:
app: main.cpp
g++ -o app main.cpp
注意:第二行命令前必须是**一个 Tab 字符**,不是空格,否则 make 会报错 *** missing separator。
-
app是目标(target),也是最终产物名 -
main.cpp是依赖(prerequisite),make会检查它的修改时间 -
g++ -o app main.cpp是命令(recipe),仅在main.cpp比app新时才执行
如何让Makefile自动处理头文件依赖
只写 main.cpp 作依赖,一旦它 #include "util.h",而你改了 util.h,make 就不会重新编译——这是新手最常踩的坑。
解决方法是让 g++ 自动生成依赖信息,用 -M 或 -MM 选项:
main.o: main.cpp util.h
g++ -c -o main.o main.cpp
<h1>更健壮的做法:用编译器自动生成依赖</h1><p>depend: <em>.cpp
g++ -MM </em>.cpp > .deps</p><p>-include .deps</p>
-MM 排除系统头文件,生成形如 main.o: main.cpp util.h 的规则;-include .deps 把这些规则加载进来。
- 必须加
-前缀(即-include),否则没有.deps文件时make直接失败 -
.deps文件需手动首次生成,或加到all目标里自动触发 - 某些旧版
make不支持-include,可改用sinclude
为什么推荐用变量定义编译器和标志
硬编码 g++ -O2 -Wall 在每条命令里,后期改优化级别或加调试符号时得改多处,极易漏掉。
用变量统一管理更安全:
CXX = g++ CXXFLAGS = -Wall -Wextra -O2 LDFLAGS = LIBS = <p>app: main.o utils.o $(CXX) $(LDFLAGS) -o app main.o utils.o $(LIBS)</p>
变量名用大写是 Makefile 传统,$(CXX) 和 $(CXXFLAGS) 是标准写法,多数开源项目都这么约定。
-
CXXFLAGS只用于编译(-c),不用于链接;LDFLAGS用于链接阶段 -
LIBS放库名(如-lpthread),放在命令末尾,顺序不能颠倒 - 不要在
CXXFLAGS里写-o或输出文件名,那是命令逻辑,不是编译选项
clean目标为什么总被忽略,又为什么必须写
clean 不是文件名,而是伪目标(phony target)。如果漏写 .PHONY: clean,而当前目录下恰好有叫 clean 的文件,make clean 就什么也不做——因为 make 认为“目标已存在且最新”。
.PHONY: clean
clean:
rm -f *.o app .deps
实际项目中,clean 往往要删中间文件、可执行文件、依赖文件三类东西。
-
rm -f的-f很关键,避免因文件不存在导致make中断 - 别用
rm -rf *,可能误删.git或配置文件 - 如果项目用了
build/目录隔离,clean应只清那个目录,而不是整个源码树
真正麻烦的是跨平台构建——Windows 上 del 和 Unix 的 rm 不兼容,这时候要么用 $(RM) 变量(GNU make 内置),要么老老实实用 shell 脚本封装清理逻辑。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











