从源码到二进制:深度拆解 Linux 下 C 程序的编译与链接全流程

1. C 程序的完整编译流程

1.1 预处理(Preprocess)

作用

  • 宏替换

  • 头文件展开

  • 条件编译处理

命令

bash 复制代码
gcc -E code.c -o code.i

1.2 编译(Compile → 汇编)

作用

  • 将 C 代码翻译成汇编代码

命令

bash 复制代码
gcc -S code.i -o code.s

.s:汇编代码文件(人类可读)

1.3 汇编(Assemble → 目标文件)

作用

  • 将汇编代码翻译成机器指令

命令

bash 复制代码
gcc -c code.s -o code.o

特点

  • .o:可重定位目标文件

  • 已是二进制

  • 不可直接执行

  • 类似 Windows 的 .obj

作用

  • 将目标文件与库文件链接成最终程序

命令

bash 复制代码
gcc code.o -o code

2. 多文件编译流程

2.1 单独编译每个源文件

bash 复制代码
gcc -c code1.c
gcc -c code2.c

生成:

bash 复制代码
code1.o
code2.o

2.2 链接多个目标文件

bash 复制代码
gcc code.o code1.o code2.o -o code

如:

text 复制代码
1.c → 1.o
2.c → 2.o
3.c → 3.o
     ↓
    链接
     ↓
    exe

3. 程序运行与依赖库分析

3.1 查看动态依赖 - ldd

bash 复制代码
ldd code

示例输出:

bash 复制代码
libc.so.6 => /lib64/libc.so.6

libc 实际位置

bash 复制代码
/lib64/libc.so.6 -> libc-2.17.so

4. 库的分类

4.1 动态库

动态库的本质:

让公共代码在内存中只存在一份

  • Linux:.so

  • Windows:.dll

4.1 静态库

  • Linux:.a

  • Windows:.lib


5. 条件编译

5.1 命令行定义宏

bash 复制代码
gcc code.c -o code -DM
gcc code.c -o code -DM=100

本质

c 复制代码
#define M 100

➡ 预处理阶段直接修改源码文本

5.2 条件编译的用途

  1. 商业版 / 免费版功能裁剪

  2. Linux 内核裁剪

  3. 不同平台、工具链适配


6. 为什么要先编译成汇编?

原因总结:

  • CPU 只识别二进制

  • 汇编是二进制的助记符

  • 编译器最初由汇编写成(自举)

语言翻译层级

text 复制代码
C/C++/Java → 汇编 → 机器码

7. 动态链接与静态链接

7.1 动态链接(默认方式)

特点

  • 程序不包含库代码

  • 运行时跳转到共享库

  • 多个程序共享一份库

示意

text 复制代码
程序 → libc.so → printf()

优点

  • 程序体积小

  • 节省内存和磁盘

缺点

  • 库缺失 → 程序无法运行

7.2 静态链接

命令

bash 复制代码
gcc code.c -o code-static -static

特点

  • 链接时拷贝库代码进程序

  • 运行时不依赖外部库

  • 文件体积大

验证

bash 复制代码
ldd code-static
# not a dynamic executable

7.3 动态 / 静态链接对比总结

对比项 动态链接 静态链接
程序体积
内存占用
库依赖 必须存在 不需要
共享性
相关推荐
艾伦_耶格宇1 小时前
【AI】-4 OpenCode Go 接入 Obsidian 完整指南
运维·开发语言·人工智能·agent·opencode
码匠许师傅1 小时前
【C++ 面试真题】30. 聊聊 C++ 的互斥锁与读写锁
java·c++·面试
皮卡丘不断更1 小时前
从遥操作示范到可复现训练:LeRobot 0.6.1 的机器人学习工作流
人工智能·学习·机器人·开源·开发工具
旋生万物1 小时前
【终极实战】用Python从零“生成“一个宇宙:螺旋干涉模型的代码实现
开发语言·前端·人工智能·react.js·php·wpf
ShineWinsu1 小时前
对于 C++:C++14中从变量模板、泛型 Lambda 到并发与字面量的解析
c++·算法
IZero072 小时前
Elasticsearch 学习笔记筑基-文档操作篇
笔记·学习·elasticsearch
公爵爱学习2 小时前
安装Ubuntu20.04遇到的问题 简要简述笔记
笔记
码行山野赴时序归途2 小时前
算法效率的度量(上):时间复杂度中的对数思维
c语言·数据结构·算法
16月6日-晴2 小时前
Java面向对象进阶—多态
java·开发语言
fb_123452 小时前
Linux三剑客超全精讲(grep+sed+awk)零基础入门|正则+实战面试题
linux·运维·服务器