图解静态库链接过程

正常链接过程

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

  • 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. 多个静态库实现了同名方法,全局用了'-all_load'或者各自都用了'-force_load',会导致符号冲突。
-ObjC

这个flag告诉链接器把库中定义的Objective-C类和Category都加载进来。这样编译之后的app会变大(因为加载了其他的objc代码进来)。但是如果静态库中有类和category的话只有加入这个flag才行。

-all_load

这个flag是专门处理-ObjC的一个bug的。用了-ObjC以后,如果类库中只有category没有类的时候这些category还是加载不进来。变通方法就是加入-all_load或者-force-load。-all_load会强制链接器把目标文件都加载进来,即使没有objc代码。

注意:假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件

-force_load

这个flag所做的事情跟-all_load其实是一样的,只是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载 ,-force_load在xcode3.2后可用。

解决方法:

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

参考文章

Linker Design -- lld

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容