链接过程由链接器
ld
负责。通常 GCC 间接驱动之。
越底层的库,在链接命令行中的位置应越靠后。
文章目录
- 链接过程
- [※ 但是对于静态库,链接器仅提取当前未解析符号所需的对象文件,未使用的对象文件会被丢弃。](#※ 但是对于静态库,链接器仅提取当前未解析符号所需的对象文件,未使用的对象文件会被丢弃。)
链接过程
.o 目标文件(Object File)
.a 静态库(Static Library)是多个.o的集合
导出符号:.当前编译单元 .o /.a 定义的、可供其他编译单元使用的符号
导入符号:需要导入,但没找到的符号
符号:
函数声明 与 函数实现
全局变量
局部静态变量
这些需要全局使用,所以进程地址空间有个数据段,代码段。
符号表在链接时用来做这些准备~
链接器ld维护两个符号表:
- 已决符号表A: 遇到的所有.o/.a的导出符号
- 未决符号表B: 遇到的所有.o/.a需要导入,但尚未找到的符号
链接器对一个 .o 文件的每个符号:
- 导出符号 加入到 已决符号表A ,若 未决符号表B 存在该符号,则删除。
若 已决符号表A 已存在该符号,则报错"多重定义" - 导入符号 若 已决符号表A 不存在该符号,则添加到表B
※ 但是对于静态库,链接器仅提取当前未解析符号所需的对象文件,未使用的对象文件会被丢弃。
所以:
静态库(.a)需要在使用它的目标文件之后
(原因见上)
g++ main.o -lprotobuf -o client.out
循环依赖的静态库
(原因见上)
如果 libA.a 依赖 libB.a 里的符号,而 libB.a 也依赖 libA.a
g++ main.o -lA -lB -lA -o myapp
这样 libA.a 会被解析两遍,确保所有符号都能找到。