9.揭秘编译器的秘密:从预处理到链接全解析和 动静态库
可以额外在外面添加宏定义1.在产品中启用或禁用特定功能,无需修改源代码即可配置不同功能组合。2.针对不同处理器架构或编译器特性进行优化,提升运行效率。3.不同操作系统或硬件平台可能需要不同的代码实现。通过条件编译,可以确保代码在多种环境下正确编译运行使用目标语言的编译器来编译自身的过程自举的基本原理使用其他语言(如C或汇编)编写一个简单的编译器,支持目标语言的核心功能。利用初始编译器编译目标语言的
条件编译:
可以额外在外面添加宏定义



条件编译用处:
1.
功能开关
在产品中启用或禁用特定功能,无需修改源代码即可配置不同功能组合。
2.
性能优化
针对不同处理器架构或编译器特性进行优化,提升运行效率。
3.
跨平台兼容性
不同操作系统或硬件平台可能需要不同的代码实现。通过条件编译,可以确保代码在多种环境下正确编译运行
编译器自举:
使用目标语言的编译器来编译自身的过程
自举的基本原理
-
初始阶段
使用其他语言(如C或汇编)编写一个简单的编译器,仅支持目标语言的核心功能。 -
编译器的编译
利用初始编译器编译目标语言的源代码,生成第一个可执行版本。 -
迭代优化
使用生成的编译器重新编译自身,逐步扩展功能并优化性能。
例如在编译c语言编译器时,会先用汇编编写的编译器来先编译一个简单的编译器,然后再用这个编译器重新编译c源代码同时生成更优化的编译器版本
四大过程:
1.
预处理
宏定义(#define)、文件包含(#include)、条件编译(#ifdef、#ifndef)等。预处理器会展开宏、将包含的文件插入到源代码中,并处理条件编译指令,生成一个纯C/C++的中间文件(通常为.i或.ii扩展名)。


2.
编译
编译阶段将预处理后的中间文件转换为汇编代码。编译器进行词法分析、语法分析、语义分析和优化,生成与平台相关的汇编代码。此阶段会检查语法错误和类型错误,确保代码符合语言规范。生成的汇编代码是低级语言,但仍需进一步转换为机器码。


3.
汇编
汇编阶段将预处理后的代码转换为机器可执行的指令。编译器将高级语言代码翻译成汇编语言代码(.s文件),随后汇编器将汇编代码转换为目标文件(.o或.obj)。目标文件包含机器指令和符号表,但尚未解决外部依赖(如库函数或外部变量)。(二进制目标代码)


4.
链接
链接器将多个目标文件和库文件合并为一个可执行文件。链接分为静态链接和动态链接。静态链接将库代码直接嵌入可执行文件,动态链接则在运行时加载共享库。链接器的主要任务是解析符号引用(如函数和变量地址),确保所有外部依赖被正确连接,最终生成可执行文件(如.exe或.out)。我们自己写的.c在汇编变成.o后,与库文件的.o链接形成可执行的文件

![]()
库:是预先编写好的代码集合,提供特定功能或工具,供开发者调用以提升开发效率。根据用途可分为:

去掉lib和.so 或.a剩下的c即为c库

动态库和静态库
动态库:
优点:多个程序可以共享同一个动态库,节省磁盘和内存空间。库的更新可以独立进行,无需重新编译主程序,便于维护和升级。(语言层面的公共代码在内存中只出现一份)
缺点:程序运行时依赖外部库文件,部署时需要确保库文件存在且版本兼容。加载动态库会带来一定的运行时开销。


静态库:
优点:静态库的代码被完整嵌入到可执行文件中,使得程序部署更加简单,不需要依赖外部库文件。程序的运行性能通常更好,因为减少了运行时加载的开
缺点:可执行文件体积较大,占用更多磁盘空间。更新库需要重新编译和分发整个程序,维护成本较高。(一旦库文件缺失所有程序不能正常运行)

在链接方式上静态库在编译时被完整地复制到可执行文件中,导致最终生成的文件体积较大。动态库在程序运行时才被加载,多个程序可以共享同一份动态库代码。

ldd:显示可执行文件或共享库依赖关系的命令行工具(看文件属于哪一个库)
file:用于检测文件类型,。适用于二进制文件、文本文件、脚本等多种格式。
验证工作:
eg:动态库链接

eg:静态库链接
首先下载c静态库:yum install glibc-static
再![]()

可以看出文件大小差别大

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)