Linux 学习笔记(八):GCC 编译器的四大阶段与链接原理

一、 代码是如何变成程序的?

在 Linux 下,我们习惯用 gcc hello.c -o hello 一键编译。但这背后其实经历了四个极其清晰的阶段(面试高频考点):

  1. 预处理(-E) :展开头文件、宏替换、去注释。生成 .i 文件。

  2. 编译(-S) :检查语法,将 C 代码翻译成汇编语言。生成 .s 文件。

  3. 汇编(-c) :将汇编代码翻译成机器指令,生成二进制的目标文件 .o。

  4. 链接:将目标文件与库文件结合起来,生成最终的可执行文件。

二、 动态链接 vs 静态链接

如果程序用到了标准库函数(如 printf),链接阶段就要把库连进来。

  • 静态链接(.a):把库代码直接拷贝进可执行文件。优点是运行不依赖环境;缺点是文件大、占内存、更新困难。

  • 动态链接(.so) :程序运行时才去加载共享库。优点是文件小、省内存;缺点是环境缺失会导致无法运行。

    Linux 下 GCC 默认使用动态链接。

三、 实战:用指令拆解编译过程

bash

复制代码
# 1. 预处理
gcc -E hello.c -o hello.i
# 2. 编译(生成汇编)
gcc -S hello.i -o hello.s
# 3. 汇编(生成二进制目标文件)
gcc -c hello.s -o hello.o
# 4. 链接
gcc hello.o -o hello

四、 实用工具:file 与 ldd

  • file hello:可以查看文件类型,验证它是一个 dynamically linked(动态链接)的可执行文件。

  • ldd hello:列出该程序依赖的所有动态库(如 libc.so.6),排查库缺失问题时的利器。

总结

以前只知道敲 gcc,现在明白了"预处理 -> 编译 -> 汇编 -> 链接"的底层逻辑。这不仅是语法,更是操作系统运行程序的基石。

自我实战操作

在云服务器上,你需要先确认装了 gcc。如果没装,执行 sudo apt install -y gcc。

实战 1:剥洋葱式看编译过程
bash 复制代码
cd ~/linux_study
mkdir gcc_test
cd gcc_test
vim hello.c

(在 vim 里写一段简单代码,按 Esc 后敲 :wq 保存)

cpp 复制代码
#include <stdio.h>
#define PI 3.14
int main() {
    printf("Hello GCC! PI = %f\n", PI);
    return 0;
}

接下来,我们一步步"拆解"它:

bash 复制代码
# 1. 预处理:把展开头文件、替换宏(把 PI 换成 3.14)
gcc -E hello.c -o hello.i
# 用 vim 或者 cat 看看 hello.i,你会发现代码变得极长,PI 全变成了 3.14

# 2. 编译:变成汇编代码
gcc -S hello.i -o hello.s
# 用 vim 看看 hello.s,你能看到类似 mov, push 这种汇编指令

# 3. 汇编:变成二进制目标文件(无法直接 cat 看,会乱码)
gcc -c hello.s -o hello.o

# 4. 链接:生成最终可执行文件
gcc hello.o -o hello

# 5. 运行
./hello

实战 2:验证动态链接(装逼神技)
bash 复制代码
# 查看 hello 这个程序到底是什么类型的文件
file hello

# 查看 hello 依赖了哪些动态库(会看到 libc.so.6,这就是 C 标准库)
ldd hello

# 看看 hello.o 和 hello 的体积差异(链接后变大了,因为引入了库信息)
ls -l hello.o hello
相关推荐
运维踩坑日记1 小时前
【无标题】
linux·运维·windows
Z21-X1 小时前
云原生运维学习笔记:从云计算概念到服务器硬件的入门之旅
运维·笔记·学习·云原生
虚无的纽扣1 小时前
【Linux】线程(下):怎么创建、终止与分离一个线程
linux·运维·服务器
滴啦嘟啦哒1 小时前
【具身笔记】【Piper+PI0.5】一、基于键盘实现数据采集
笔记·vla·具身
叼烟扛炮1 小时前
Linux 学习笔记(七):软件安装与 Vim 编辑器极速入门
linux·学习·编辑器
金色熊族1 小时前
在Qt中使用asan检测内存泄漏(二)--检查依赖库的内存使用
linux·qt·asan
hgy89691 小时前
Sufer技能积累手册
学习
叼烟扛炮1 小时前
Linux 学习笔记(十六):进程的调度与优先级——谁先抢到 CPU?
linux·笔记·学习
幽灵诶1 小时前
学习Linux
linux·学习