美文网首页
图解静态库链接过程

图解静态库链接过程

作者: 人生看淡不服就干 | 来源:发表于2018-11-03 10:52 被阅读52次

正常链接过程

假设一个工程里有两个源码文件和两个静态库:

  • main.m
    实现了程序入口main,它又调用了未知方法Fun1Fun2
  • object.m
    实现了方法Fun1Fun3,其中Fun1调用了未知方法Fun4
  • libA.a
    包含两个目标文件,第一个实现了Fun2Fun5,第二个实现了Fun6
  • libB.a
    包含一个目标文件,它实现了Fun2Fun4

下图是链接过程:

  1. 解析所有目标文件,生成一个个符号图(符号图用来表示各符号间的引用关系,紫色节点表示未定义符号)
  2. 将所有的符号图合并成一张符号主图(master graph),中间会用已定义符号替换掉同名的未定义符号。同时生成一张全局符号表,用于记录每个符号的状态。
  3. 若生成的符号主图中仍存在未定义的符号,则按顺序扫描静态库,否则跳转第6步直接生成可执行文件。
  4. 静态库其实就是带有符号目录的目标文件集合。若符号目录匹配到了主图所需符号,则从静态库里找到定义该符号的目标文件,并把它所有的符号都合并到主图和全局符号表中,过程中会替换掉已有的同名符号(包括已定义的)。重复执行第3步和第4步,如果所有静态库都扫描完了,仍然存在未定义符号,则报符号找不到的错误symbol not found
  5. 如果有需要(一般Release下才做),会进行死代码剥离的操作,即从主图入口(main)开始遍历,不能访问到的节点就是无效可剥离的符号。
  6. 将主图中的符号都写入可执行文件中去。 每个符号在可执行文件中的地址顺序,与输入文件的先后顺序保持一致。

经典链接错误

  • symbol not found
    报错时机:链接过程中扫描完所有的静态库和动态库后,仍然存在未定义的符号。
    解决方法:工程中添加定义该符号的静态库,同时添加正确的静态库搜索路径。

  • duplicated symbol
    报错时机:

    1. 如果main.oobject.o实现了同名方法,那链接过程中合并符号图时会报错。
    2. 如果object.olibA.a中实现了同名方法,而且libA.a使用了-force_load描述,它会强行加载libA中所有的目标文件,导致符号冲突。
    3. 多个静态库,往往会引用相同的第三方库,极容易冲突。

    解决方法:

    1. 同工程源码中不能定义多个同名方法,可以通过修改方法前缀、修改命名空间(宏替换也可)、使用static方法等方式
    2. 谨慎使用'-force_load',它主要用来强制加载OC的category,对于纯C++库来说没多大意义。
    3. 多个静态库冲突时,如果你是第三方库的提供者,应该用使用prelink等方式减少无用符号的导出(参考如何隐藏SDK符号)。如果你只是第三方库使用者(无源码),有一种风险较大的方法就是在其中一个静态库里剔除冲突的目标文件。

参考文章

Linker Design -- lld

相关文章

  • 图解静态库链接过程

    正常链接过程 假设一个工程里有两个源码文件和两个静态库: main.m实现了程序入口main,它又调用了未知方法F...

  • APP编译及加载过程

    编译过程 静态库&动态库 一.静态库在链接阶段,会将会将汇编生成的目标文件与引用的库一起链接打包到可执行文件中。二...

  • 2.动态库和静态库

    1.库分类:库一般分为两种:静态库(.a 、.lib)动态库(.so 、.dll )所谓静态、动态是指链接过程。2...

  • 静态库静态链接静态库

    静态库·静态链接·静态库 这么搞的都是有强迫症的人在做SDK。 not me. PS: 多次静态链接同一个第三方库...

  • linux下静态库 动态库和 gcc gdb Makefile

    一、静态库和动态库 定义 根据链接时期的不同,库有静态库和动态库之分。 静态库是在链接阶段被链接的,所以生成的可执...

  • Linux链接库

    动态链接库(共享链接库) 杂项 生成.o文件 生成.so 使用动态库 静态链接库 杂项 生成.a 查看.a 使用静态库

  • 程序的加载与链接(五) 静态库链接

    前面我们已经了解到了多个点.o文件是怎么链接的,今天关注一下静态库的结构和链接的过程。先写个简单的静态库 好了编译...

  • 静态库和动态库

    静态库:.a 和 .framework动态库:.tbd(.dylib) 和 .framework静态库:链接时会...

  • 使用Swift创建Swift模块 - 静态链接库

    使用Swift创建Swift模块 - 静态链接库 使用Swift创建Swift模块 - 静态链接库

  • IOS SDK 静态.a库创建调试

    静态库 1、静态库即静态链接库(例如: windows下的.lib、Mac和Linux下的.a); 2、静态库在编...

网友评论

      本文标题:图解静态库链接过程

      本文链接:https://www.haomeiwen.com/subject/mvfkxqtx.html