news 2026/4/15 12:04:32

GCC/G++ 编译器完全指南:从编译流程到进阶用法(附实操案例)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GCC/G++ 编译器完全指南:从编译流程到进阶用法(附实操案例)

一. GCC 核心认知:编译的四个阶段(ESc-iso速记)

GCC 编译 C/C++ 程序并非一步到位,而是分为预处理、编译、汇编、链接四个阶段,每个阶段完成特定任务,最终生成可执行文件。

1.1 阶段 1:预处理

  • 核心任务:宏替换、删除注释、条件编译、头文件展开(不进行语法检查);
  • 关键选项-E(仅执行预处理,停止后续编译);
  • 输出文件.i后缀(预处理后的 C 文件);
  • 实操命令
[Lotso@VM-0-3-centos lesson9]$ vim hello.c [Lotso@VM-0-3-centos lesson9]$ gcc -E hello.c -o hello.i [Lotso@VM-0-3-centos lesson9]$ ll total 24 -rw-rw-r-- 1 Lotso Lotso 382 Nov 13 16:50 hello.c -rw-rw-r-- 1 Lotso Lotso 17170 Nov 13 16:50 hello.i

  • 示例:#include <stdio.h>会被展开为 stdio.h 的全部内容,#define MAX 10会替换所有MAX为 10。

1.2 阶段 2:编译

  • 核心任务:检查语法错误,将预处理后的代码(.i)转换为汇编语言代码;
  • 关键选项-S(仅执行编译,停止后续流程);
  • 输出文件.s后缀(汇编文件);
  • 实操命令
[Lotso@VM-0-3-centos lesson9]$ gcc -S hello.c -o hello.s [Lotso@VM-0-3-centos lesson9]$ ll total 28 -rw-rw-r-- 1 Lotso Lotso 327 Nov 13 16:54 hello.c -rw-rw-r-- 1 Lotso Lotso 17104 Nov 13 16:54 hello.i -rw-rw-r-- 1 Lotso Lotso 1094 Nov 13 17:01 hello.s

说明:生成的汇编代码与 CPU 架构相关(如 x86_64、ARM),可直接查看指令逻辑。

1.3 阶段 3:汇编(Assembly)

  • 核心任务:将汇编代码(.s)转换为机器可识别的二进制目标文件;
  • 关键选项-c(仅执行汇编,生成目标文件);
  • 输出文件.o后缀(目标文件,二进制格式,不可执行);
  • 实操命令
[Lotso@VM-0-3-centos lesson9]$ gcc -c hello.s -o hello.o [Lotso@VM-0-3-centos lesson9]$ ll total 32 -rw-rw-r-- 1 Lotso Lotso 327 Nov 13 16:54 hello.c -rw-rw-r-- 1 Lotso Lotso 17104 Nov 13 16:54 hello.i -rw-rw-r-- 1 Lotso Lotso 2184 Nov 13 17:05 hello.o -rw-rw-r-- 1 Lotso Lotso 1094 Nov 13 17:01 hello.s

[Lotso@VM-0-3-centos lesson9]$ objdump -d hello.o hello.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <main>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: be 0a 00 00 00 mov $0xa,%esi 9: bf 00 00 00 00 mov $0x0,%edi e: b8 00 00 00 00 mov $0x0,%eax 13: e8 00 00 00 00 callq 18 <main+0x18> 18: be 0a 00 00 00 mov $0xa,%esi 1d: bf 00 00 00 00 mov $0x0,%edi 22: b8 00 00 00 00 mov $0x0,%eax 27: e8 00 00 00 00 callq 2c <main+0x2c> 2c: be 0a 00 00 00 mov $0xa,%esi 31: bf 00 00 00 00 mov $0x0,%edi 36: b8 00 00 00 00 mov $0x0,%eax 3b: e8 00 00 00 00 callq 40 <main+0x40> 40: be 0a 00 00 00 mov $0xa,%esi 45: bf 00 00 00 00 mov $0x0,%edi 4a: b8 00 00 00 00 mov $0x0,%eax 4f: e8 00 00 00 00 callq 54 <main+0x54> 54: be 0a 00 00 00 mov $0xa,%esi 59: bf 00 00 00 00 mov $0x0,%edi 5e: b8 00 00 00 00 mov $0x0,%eax 63: e8 00 00 00 00 callq 68 <main+0x68> 68: be 0a 00 00 00 mov $0xa,%esi 6d: bf 00 00 00 00 mov $0x0,%edi 72: b8 00 00 00 00 mov $0x0,%eax 77: e8 00 00 00 00 callq 7c <main+0x7c> 7c: be 0a 00 00 00 mov $0xa,%esi 81: bf 00 00 00 00 mov $0x0,%edi 86: b8 00 00 00 00 mov $0x0,%eax 8b: e8 00 00 00 00 callq 90 <main+0x90> 90: be 0a 00 00 00 mov $0xa,%esi 95: bf 00 00 00 00 mov $0x0,%edi 9a: b8 00 00 00 00 mov $0x0,%eax 9f: e8 00 00 00 00 callq a4 <main+0xa4> a4: be 0a 00 00 00 mov $0xa,%esi a9: bf 00 00 00 00 mov $0x0,%edi ae: b8 00 00 00 00 mov $0x0,%eax b3: e8 00 00 00 00 callq b8 <main+0xb8> b8: be 0a 00 00 00 mov $0xa,%esi bd: bf 00 00 00 00 mov $0x0,%edi c2: b8 00 00 00 00 mov $0x0,%eax c7: e8 00 00 00 00 callq cc <main+0xcc> cc: be 0a 00 00 00 mov $0xa,%esi d1: bf 00 00 00 00 mov $0x0,%edi d6: b8 00 00 00 00 mov $0x0,%eax db: e8 00 00 00 00 callq e0 <main+0xe0> e0: b8 00 00 00 00 mov $0x0,%eax e5: 5d pop %rbp e6: c3 retq
  • 说明:目标文件包含机器指令,但缺少库依赖(如 printf 函数的实现),无法直接运行。
[Lotso@VM-0-3-centos lesson9]$ ./hello.o -bash: ./hello.o: Permission denied

1.4 阶段 4:链接(Linking)

核心任务:将目标文件(.o)与系统库、第三方库链接,生成可执行文件;
核心逻辑:解析未定义符号(如 printf),从库文件(如 libc.so)中找到实现并关联;
输出文件:默认名为a.out(可通过-o指定名称);

实操命令

[Scy@VM-0-3-centos lesson9]$ gcc hello.o -o hello.exe [Scy@VM-0-3-centos lesson9]$ ll total 44 -rw-rw-r-- 1 Scy Scy 327 Nov 13 16:54 hello.c -rwxrwxr-x 1 Scy Scy 8360 Nov 13 17:11 hello.exe -rw-rw-r-- 1 Scy Scy 17104 Nov 13 16:54 hello.i -rw-rw-r-- 1 Scy Scy 2185 Nov 13 17:05 hello.o -rw-rw-r-- 1 Scy Scy 1094 Nov 13 17:01 hello.s [Scy@VM-0-3-centos lesson9]$ ./hello.exe 10 10 10 10 10 10 10 10 10 10 10

1.5 一键编译(合并四阶段)

日常开发中无需分步执行,GCC支持一键完成四阶段编译:

# 也可以 gcc -o hello.exe1 hello.c [Scy@VM-0-3-centos lesson9]$ gcc hello.c -o hello.exe1 [Scy@VM-0-3-centos lesson9]$ ll total 56 -rw-rw-r-- 1 Scy Scy 327 Nov 13 16:54 hello.c -rwxrwxr-x 1 Scy Scy 8360 Nov 13 17:11 hello.exe -rwxrwxr-x 1 Scy Scy 8360 Nov 13 17:15 hello.exe1 -rw-rw-r-- 1 Scy Scy 17104 Nov 13 16:54 hello.i -rw-rw-r-- 1 Scy Scy 2185 Nov 13 17:05 hello.o -rw-rw-r-- 1 Scy Scy 1094 Nov 13 17:01 hello.s [Scy@VM-0-3-centos lesson9]$ ./hello.exe1 10 10 10 10 10 10 10 10 10 10 10

本质是 GCC 自动依次执行预处理→编译→汇编→链接,隐藏了中间文件。

二. GCC核心功能选项 && 条件编译 && 编译器和语言的历史(理解编译的过程)

2.1 核心功能速查表:

选项功能描述使用示例
-E只进行预处理,不编译、汇编和链接gcc -E main.c -o main.i
-S编译到汇编语言,不进行汇编和链接gcc -S main.c -o main.s
-c编译到目标代码,生成.o文件gcc -c main.c -o main.o
-o指定输出文件名gcc main.c -o myapp
-static使用静态链接生成可执行文件gcc main.c -static -o app_static
-g生成调试信息,供GDB使用gcc -g main.c -o debug_app
-shared尽量使用动态库,生成较小的文件gcc -shared lib.c -o lib.so
-O0不进行优化(编译速度最快)gcc -O0 main.c -o app
-O1基本优化(默认级别)gcc -O1 main.c -o app
-O2较多优化,平衡性能与编译时间gcc -O2 main.c -o app
-O3最高级别优化(可能增加代码大小)gcc -O3 main.c -o app
-w禁止所有警告信息gcc -w main.c -o app
-Wall开启所有常见警告信息gcc -Wall main.c -o app

2.2 条件编译的逻辑和应用场景2.3 编译的过程:编译器和语言的历史

关键逻辑

三. 关键原理:静态链接和动态链接

链接阶段的核心是"关联库文件",GCC支持两种链接方式,各有优劣

3.1 静态链接(Static Linking)

3.2 动态链接(Dynamic Linking)

3.2 查看依赖的库文件

通过ldd可以查看可执行程序依赖的动态库

# 动态链接的文件 [Lotso@VM-0-3-centos lesson10]$ ldd hello_dynamic linux-vdso.so.1 => (0x00007ffe61b15000) libc.so.6 => /lib64/libc.so.6 (0x00007f2e519cd000) /lib64/ld-linux-x86-64.so.2 (0x00007f2e51d9b000) # 静态链接的文件 [Lotso@VM-0-3-centos lesson10]$ ldd hello_static not a dynamic executable

3.3 通过一个故事感性的理解一下库

3.3.1 阶段一:动态库的故事(共享网吧模式)

小王是一中的新生,他学习刻苦,但也需要偶尔上网放松。一中管理严格,但小王从学长张三那里得知,学校东门左转100米再右转100米有一家“小蚂蚁电竞馆”。小王记下地址,在某个周六中午,他按计划完成部分作业后,前往电竞馆上网。老板给他开了编号1234的电脑,小王愉快地度过了中午。下午2:30,他回到学校继续学习。
后来,越来越多的学生知道了电竞馆,纷纷前去放松。直到月考,全班成绩下滑,校长调查后举报导致了电竞馆关闭。

✅️阶段一理解

声明:这里是为了方便故事举例说明哈,动态库其实也是在内存里的

图示理解

┌─────────────┐ 询问地址 ┌─────────────┐ │ 小王 │ ──────────────> │ 张三 │ │ (程序) │ │ (编译器/链接器)│ └─────────────┘ └─────────────┘ │ │ │ 获得地址:"东门左转100m右转100m" │ │ ▼ ▼ ┌─────────────────────────────────────────────┐ │ 一中 │ │ (内存) │ └─────────────────────────────────────────────┘ │ │ 按计划执行:作业→上网→作业 │ ▼ ┌─────────────┐ 上网请求 ┌─────────────┐ │ 小王 │ ──────────────> │ 小蚂蚁电竞馆 │ │ (程序) │ │ (动态库) │ └─────────────┘ └─────────────┘ │ │ 分配1234号电脑 │ (库函数地址) ▼ ┌─────────┐ │ 愉快上网 │ │ (函数执行)│ └─────────┘

动态库特点

3.3.2 阶段二:静态库的故事(自带电脑模式)

小王因不能上网而学习状态不佳,父亲了解情况后,与校长协商并去小蚂蚁电竞馆找老板买下那台1234号电脑,放在学校供小王使用。此后,小王和同学们都可以在学校内直接上网,无需外出。

✅️阶段二理解

图示理解

┌─────────────┐ 成绩下滑 ┌─────────────┐ │ 小王 │ ──────────────> │ 爸爸 │ │ (程序) │ │ (静态链接器) │ └─────────────┘ └─────────────┘ │ │ │ 协商购买 │ │ │ ▼ ▼ ┌─────────────┐ 购买1234电脑 ┌─────────────┐ │ 校长 │ <────────────── │ 电竞馆老板 │ │ (系统环境) │ │ (库提供者) │ └─────────────┘ └─────────────┘ │ │ 电脑安置在学校 │ ▼ ┌─────────────────────────────────────────────┐ │ 一中 │ │ (内存) │ └─────────────────────────────────────────────┘ │ │ 每个学生都自带电脑 │ (程序各自包含库代码) ▼ ┌─────────────┐ 直接使用 ┌─────────────┐ │ 小王和室友 │ ──────────────> │ 个人电脑 │ │ (程序) │ │ (静态库) │ └─────────────┘ └─────────────┘

静态库特点

3.3.3 核心概念对比 && 整体总结
特性动态库(小蚂蚁电竞馆)静态库(个人电脑)
资源使用共享,节省资源独占,浪费资源
依赖性强依赖,库缺失则全崩独立,自给自足
更新维护更新库即更新所有程序每个程序需重新编译
内存占用多个程序共享同一份每个程序都有一份拷贝

现实世界类比

编程世界: 现实世界: ┌─────────────────┐ ┌─────────────────┐ │ 动态库 │ │ 共享网吧 │ │ (共享函数集合) │ │ (共享电脑资源) │ └─────────────────┘ └─────────────────┘ │ │ │ 多个程序共用 │ 多个顾客共用 │ 库缺失=所有程序挂掉 │ 网吧关门=所有人都不能上网 │ │ ┌─────────────────┐ ┌─────────────────┐ │ 静态库 │ │ 个人电脑 │ │ (函数嵌入程序内) │ │ (自有电脑资源) │ └─────────────────┘ └─────────────────┘ │ │ │ 每个程序都包含库代码 │ 每个人都有自己的电脑 │ 程序体积大但独立运行 │ 随时可用但占用更多空间

整体总结:
通过这两个故事,我们理解了动态库和静态库的区别:

在编程中,我们根据需求选择使用动态库还是静态库。动态库适合多个程序共享,减少内存占用;静态库适合程序独立发布,避免依赖问题。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/12 0:44:41

王宝强新女友太美了!世界小姐亚军,身高178力压前妻马蓉

在娱乐圈的纷纷扰扰中&#xff0c;王宝强一直是备受瞩目的存在。他那朴实憨厚的形象深入人心&#xff0c;而其感情生活更是大众关注的焦点。如今&#xff0c;王宝强新女友的出现&#xff0c;宛如一颗璀璨星辰划过夜空&#xff0c;引发了无数人的惊叹。这位新女友&#xff0c;竟…

作者头像 李华
网站建设 2026/4/11 2:51:30

软件便携化全攻略:从绿色部署到跨设备无缝协作

软件便携化全攻略&#xff1a;从绿色部署到跨设备无缝协作 【免费下载链接】Playnite Video game library manager with support for wide range of 3rd party libraries and game emulation support, providing one unified interface for your games. 项目地址: https://gi…

作者头像 李华
网站建设 2026/4/5 10:57:06

Qucs-S:电路行为模拟4个维度彻底掌握电子系统设计

Qucs-S&#xff1a;电路行为模拟4个维度彻底掌握电子系统设计 【免费下载链接】qucs_s Qucs-S is a circuit simulation program with Qt-based GUI 项目地址: https://gitcode.com/gh_mirrors/qu/qucs_s 一、价值定位&#xff1a;重新定义电路设计效率 你是否曾遇到这…

作者头像 李华
网站建设 2026/4/11 3:30:53

7天效率革命:鸣潮玩家效率解决方案全指南

7天效率革命&#xff1a;鸣潮玩家效率解决方案全指南 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸上锁合成 自动肉鸽 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 在游戏世界中&#x…

作者头像 李华
网站建设 2026/4/11 0:00:05

如何用Jellyfin安卓客户端Findroid打造极致媒体体验

如何用Jellyfin安卓客户端Findroid打造极致媒体体验 【免费下载链接】findroid Third-party native Jellyfin Android app 项目地址: https://gitcode.com/gh_mirrors/fi/findroid 作为影音爱好者&#xff0c;你是否正在寻找一款能够充分释放Jellyfin媒体服务器潜力的安…

作者头像 李华