条件编译:

可以额外在外面添加宏定义

条件编译用处:

1.

功能开关

在产品中启用或禁用特定功能,无需修改源代码即可配置不同功能组合。

2.

性能优化

针对不同处理器架构或编译器特性进行优化,提升运行效率。

3.

跨平台兼容性

不同操作系统或硬件平台可能需要不同的代码实现。通过条件编译,可以确保代码在多种环境下正确编译运行

编译器自举:

使用目标语言的编译器来编译自身的过程

自举的基本原理

  1. 初始阶段
    使用其他语言(如C或汇编)编写一个简单的编译器,支持目标语言的核心功能。

  2. 编译器的编译
    利用初始编译器编译目标语言的源代码,生成第一个可执行版本。

  3. 迭代优化
    使用生成的编译器重新编译自身,逐步扩展功能并优化性能。

例如在编译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

可以看出文件大小差别大

Logo

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

更多推荐