详解GCC编译器常用命令

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