详解GCC编译器常用命令
- 嵌入式开发
- 22小时前
- 29热度
- 0评论
GCC 常用命令速查
GCC = GNU Compiler Collection,GNU 的 C/C++ 编译器
基本格式:
gcc [选项] 源文件 -o 输出文件
1. 编译流程
源码(.c) → 预处理(.i) → 编译(.s) → 汇编(.o) → 链接(可执行文件)
用做菜来比喻:
阶段 比喻 源码 .c你写的菜谱 预处理 .i备菜 — 把 #include的食材搬上桌,展开宏(调料包拆开)编译 .s翻译成操作步骤 — "切丝、大火、翻炒..." (汇编指令) 汇编 .o按步骤做出一盘菜 — 每个 .c 文件做成一道菜(半成品) 链接 装盘上桌 — 把所有菜组合成一桌完整的宴席(可执行程序)
| 阶段 | 命令 | 产物 | 用途 |
|---|---|---|---|
| 预处理 | gcc -E main.c -o main.i |
.i |
查看宏展开、头文件包含 |
| 编译 | gcc -S main.c -o main.s |
.s |
查看汇编代码 |
| 汇编 | gcc -c main.c -o main.o |
.o |
生成目标文件 |
| 链接 | gcc main.o -o main |
可执行文件 | 最终程序 |
| 一步到位 | gcc main.c -o main |
可执行文件 | 最常用 |
2. 常用选项速查
| 选项 | 含义 | 说明 |
|---|---|---|
-o |
output | 指定输出文件名 |
-Wall |
Warning all | 开启所有常见警告 |
-Wextra |
比 -Wall 更严格的额外警告 | |
-Werror |
把警告当错误,有警告就编译失败 | |
-g |
生成调试信息,配合 gdb 使用 | |
-c |
compile | 只编译不链接,生成 .o 文件 |
-S |
只编译到汇编,生成 .s 文件 | |
-E |
只做预处理,展开宏和头文件 | |
-O0/1/2/3 |
Optimize | 优化等级(见下方) |
-std= |
standard | 指定 C 标准版本 |
-I |
Include | 添加头文件搜索路径 |
-L |
Library path | 添加库文件搜索路径 |
-l |
link | 链接指定的库 |
-D |
Define | 定义宏,如 -DDEBUG |
-v |
verbose | 显示详细编译过程 |
3. 警告与调试
# -Wall: Warning all,开启所有常见警告(建议始终带上)
# 能发现:未初始化变量、未使用变量、格式串不匹配等
gcc -Wall main.c -o main
# 更严格的警告
gcc -Wall -Wextra main.c -o main
# 把警告当错误,有警告就编译失败
gcc -Wall -Werror main.c -o main
# -g: 生成调试信息,配合 gdb 使用
gcc -g main.c -o main
gdb ./main
4. 优化等级
gcc -O0 main.c -o main # 不优化(默认),编译快,适合调试
gcc -O1 main.c -o main # 基本优化
gcc -O2 main.c -o main # 推荐优化,性能与安全的平衡
gcc -O3 main.c -o main # 激进优化,可能增大体积
gcc -Os main.c -o main # 优化体积(嵌入式常用)
5. 多文件编译
# 方式1: 一步编译
gcc main.c utils.c -o app
# 方式2: 分步编译(大项目推荐,修改单文件只需重新编译该文件)
gcc -c main.c -o main.o
gcc -c utils.c -o utils.o
gcc main.o utils.o -o app
6. Makefile — 自动化多文件编译
文件多了每次手敲 gcc 太累,Makefile 帮你一个
make搞定
基本语法
目标: 依赖
命令 # 注意: 必须用 Tab 缩进,不能用空格!
示例:编译 main.c + utils.c
项目结构:
project/
├── main.c
├── utils.c
├── utils.h
└── Makefile
CC = gcc
CFLAGS = -Wall -g
# 最终目标
app: main.o utils.o
$(CC) main.o utils.o -o app
# 各文件的编译规则
main.o: main.c utils.h
$(CC) $(CFLAGS) -c main.c -o main.o
utils.o: utils.c utils.h
$(CC) $(CFLAGS) -c utils.c -o utils.o
# 清理编译产物
clean:
rm -f *.o app
使用方法
make # 编译项目(只重新编译修改过的文件)
make clean # 清理所有编译产物
make -j4 # 4线程并行编译(大项目更快)
为什么用 Makefile?
| 手动编译 | Makefile |
|---|---|
| 每次敲一堆 gcc 命令 | 一个 make 搞定 |
| 全部重新编译 | 只重编修改过的文件 |
| 容易漏掉文件 | 自动处理依赖关系 |
常用变量
| 变量 | 含义 | 常见值 |
|---|---|---|
CC |
C 编译器 | gcc |
CFLAGS |
编译选项 | -Wall -g |
LDFLAGS |
链接选项 | -lm -lpthread |
$@ |
当前目标名 | |
$< |
第一个依赖 | |
$^ |
所有依赖 |
用自动变量简化后:
CC = gcc
CFLAGS = -Wall -g
app: main.o utils.o
$(CC) $^ -o $@
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o app
%.o: %.c是模式规则,意思是"任何 .o 文件都由同名 .c 文件编译而来",不用再给每个文件单独写规则了。
7. 链接库
# 链接数学库 libm(使用 math.h 中的 sin/cos/sqrt 等)
gcc main.c -o main -lm
# 链接多线程库 libpthread
gcc main.c -o main -lpthread
# 指定头文件搜索路径
gcc -I./include main.c -o main
# 指定库文件搜索路径
gcc -L./lib main.c -o main -lmylib
8. 标准版本
gcc -std=c99 main.c -o main # C99(for循环内定义变量)
gcc -std=c11 main.c -o main # C11(多线程、泛型宏)
gcc -std=c17 main.c -o main # C17(bug修复版)
9. 查看信息
gcc --version # 查看 gcc 版本
gcc -dM -E - < /dev/null # 查看所有预定义宏
gcc -v main.c -o main # 显示详细编译过程
10. 实用场景速查
| 场景 | 命令 |
|---|---|
| 日常练习 | gcc -Wall main.c -o main && ./main |
| 调试段错误 | gcc -g -Wall main.c -o main && gdb ./main |
| 看宏展开了啥 | gcc -E main.c -o main.i |
| 看 sizeof 等编译期结果 | gcc -S main.c -o main.s |
| 用了 math.h 编译报错 | gcc main.c -o main -lm |
| 比较优化前后性能 | gcc -O0 main.c -o v0 && gcc -O2 main.c -o v2 |
| 指定 C 标准 | gcc -std=c99 -Wall main.c -o main |