编译流程与库机制
594 字
3 分钟
编译流程与库机制
1. C 程序的完整编译流程
1.1 预处理(Preprocess)
作用:
-
宏替换
-
头文件展开
-
条件编译处理
命令
gcc -E code.c -o code.i1.2 编译(Compile → 汇编)
作用:
- 将 C 代码翻译成汇编代码
命令
gcc -S code.i -o code.s.s:汇编代码文件(人类可读)
1.3 汇编(Assemble → 目标文件)
作用:
- 将汇编代码翻译成机器指令
命令
gcc -c code.s -o code.o特点
-
.o:可重定位目标文件 -
已是二进制
-
不可直接执行
-
类似 Windows 的
.obj
1.4 链接(Link → 可执行文件)
作用:
- 将目标文件与库文件链接成最终程序
命令
gcc code.o -o code2. 多文件编译流程
2.1 单独编译每个源文件
gcc -c code1.cgcc -c code2.c生成:
code1.ocode2.o2.2 链接多个目标文件
gcc code.o code1.o code2.o -o code如:
1.c → 1.o2.c → 2.o3.c → 3.o ↓ 链接 ↓ exe3. 程序运行与依赖库分析
3.1 查看动态依赖 - ldd
ldd code示例输出:
libc.so.6 => /lib64/libc.so.6libc 实际位置
/lib64/libc.so.6 -> libc-2.17.so4. 库的分类
4.1 动态库
动态库的本质: 让公共代码在内存中只存在一份
-
Linux:
.so -
Windows:
.dll
4.1 静态库
-
Linux:
.a -
Windows:
.lib
5. 条件编译
5.1 命令行定义宏
gcc code.c -o code -DMgcc code.c -o code -DM=100本质
#define M 100➡ 预处理阶段直接修改源码文本
5.2 条件编译的用途
-
商业版 / 免费版功能裁剪
-
Linux 内核裁剪
-
不同平台、工具链适配
6. 为什么要先编译成汇编?
原因总结:
-
CPU 只识别二进制
-
汇编是二进制的助记符
-
编译器最初由汇编写成(自举)
语言翻译层级
C/C++/Java → 汇编 → 机器码7. 动态链接与静态链接
7.1 动态链接(默认方式)
特点
-
程序不包含库代码
-
运行时跳转到共享库
-
多个程序共享一份库
示意
程序 → libc.so → printf()优点
-
程序体积小
-
节省内存和磁盘
缺点
- 库缺失 → 程序无法运行
7.2 静态链接
命令
gcc code.c -o code-static -static特点
-
链接时拷贝库代码进程序
-
运行时不依赖外部库
-
文件体积大
验证
ldd code-static# not a dynamic executable7.3 动态 / 静态链接对比总结
| 对比项 | 动态链接 | 静态链接 |
|---|---|---|
| 程序体积 | 小 | 大 |
| 内存占用 | 低 | 高 |
| 库依赖 | 必须存在 | 不需要 |
| 共享性 | 高 | 无 |
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
库制作与原理
Linux 系统库是写好的、现有的、成熟的、可以复用的代码。每个程序都依赖很多底层库,库的存在使得开发不必从零开始。
2
线程同步与互斥
Linux 系统线程共享地址空间:同一个进程内的多个线程共享进程的虚拟地址空间。
3
make 与 Makefile
Linux 系统Makefile:描述构建规则的文件
4
linux基础知识点
Linux 系统图形界面 vs 命令行: 所有操作系统最初都只有命令行界面。 Windows 和 Linux Desktop 虽有图形界面,但终端命令操作是核心与基础。
5
进程优先级、切换与调度
Linux 系统是什么:进程获得CPU资源的先后顺序。
随机文章随机推荐

