Other linker flags 配置说明

Targets选项下有Other linker flags的设置,用来填写XCode的链接器参数,如:-ObjC -all_load -force_load等。

还记得我们在学习C程序的时候,从C代码到可执行文件经历的步骤是:

源代码 > 预处理器 > 编译器 > 汇编器 > 机器码 > 链接器 > 可执行文件

在 最后一步需要把.o文件和C语言运行库链接起来,这时候需要用到ld命令。源文件经过一系列处理以后,会生成对应的.obj文件,然后一个项目必然会有许 多.obj文件,并且这些文件之间会有各种各样的联系,例如函数调用。链接器做的事就是把这些目标文件和所用的一些库链接在一起形成一个完整的可执行文 件。

如果要详细研究链接器做了什么,请看:http://www.dutor.net/index.php/2012/02/what-linkers-do/

那么,Other linker flags设置的值实际上就是ld命令执行时后面所加的参数。

下面逐个介绍3个常用参数:

-ObjC:加了这个参数后,链接器就会把静态库中所有的Objective-C类和分类都加载到最后的可执行文件中

-all_load: 会让链接器把所有找到的目标文件都加载到可执行文件中,但是千万不要随便使用这个参数!假如你使用了不止一个静态库文件,然后又使用了这个参数,那么你很 有可能会遇到ld: duplicate symbol错误,因为不同的库文件里面可能会有相同的目标文件,所以建议在遇到-ObjC失效的情况下使用-force_load参数。

-force_load:所做的事情跟-all_load其实是一样的,但是-force_load需要指定要进行全部加载的库文件的路径,这样的话,你就只是完全加载了一个库文件,不影响其余库文件的按需加载

加入-ObjC链接参数后项目走火入魔的事件由来以久,往日只曾听说,却从未见过。最近门派开发产品的时候,本人经身经历了一番。

这个坑是怎么来的?

公司项目遇到的情况如下:首先我们公司的项目是用CocoaPod构建的,CocoaPod在生成项目的时候会自动在Other Link Flags配置项上打上-ObjC,而且,即使强行去除-ObjC选项也无法解决,虽然编译可通过,但是运行的时候,友盟、MJRefresh等众多库均会报错无法运行。

同时,公司的项目基于另一个分公司所提供的一个基础服务framework,这个framework具体实现未知,目前看来应该是使用c++开发,同时库必须禁用掉-ObjC选项,否则会报 duplicated symbols错误,编译都无法通过。

于是坑就这样出来了。

-ObjC是干嘛的?

简单来说,-ObjC链接指令是用来解决static library在运行时调用category方法报selector not recognized错误时使用的。也就是说,如果你在一个static library里面声明了一个category,在运行的时候调用这个方法就很有可能会出现这个错误,而这个错误本不应该出现,因为你已经定义了那个方法。

那么,为什么会出现这样一个问题?

为啥会出 method not recognized 错误

简单来说,这是因为UNIX 的静态库(.a文件)与OC的动态机制之间的不协调导致的。

我们先来看一般情况下,UNIX静态库及C程序的一个链接过程。当一个C语言程序编译的时候,所有的源代码会被编译为对象文件,即.o文件(object file)。这些对象文件中包含了相应的可执行程序,以及相应的静态数据。链接器最终需要将所有这些对象文件组合到一起从而产生一个最终的可执行文件。

当一个源文件引用了定义于其他文件中的一些东西的时候(比如引用其他文件的一个方法),一个 undefined symbol就被写入了它所产生的object 文件,然后等待最终被解释掉。在最终构建可执行文件的时候,链接器将从包含这些undefined symbols的object文件中拉取信息以解决掉之前被标记的undefined symbols。

一个UNIX的静态库其实就是一系统object file的集合,然而,一般情况下只会拉取那些,他需要的object file。而这样做的好处是可以减小最终可执行文件的大小。

举个例子

比如main.c使用一个函数,名叫foo( ),而这个函数定义于B.c里面。在生成.o文件的时候,main.o就会有一个foo( ) 的undefined symbols标记。在链接期间,B.o文件便会被打入最终的可执行文件中。但是,假如另外还有一个C.c,里面定义了的函数并没被使用到,那么最终,这个C.o文件便不会出现在最终的可执行文件中。

Objective-C有什么不同?

然而众所周之,oc是具有一定动态性的语言,只有在最终运行的时候,对象方法的具体实现只有到被调用的时候才会被确定。基于这个原因,Objective-C并没有对方法级别定义符号,而是只对类级别定义符号。

举个栗子。比如在main.c中包含以下代码: [[FooClass alloc] initWithBar:nil]; 那么在链接的时候,main.o在生成的时候就会包含一个未定义符号(Undefined Symbols) FooClass,但却不会定义符号 initWithBar。

所以为什么会产生这个坑?

坑爹的是,Category只是一个方法的集合,而对一个Cateogry中的方法的调用,并不会生成未定义符号,这就意味着链接器并不知道要去加载这个Cateogry文件所生成的object 文件。于是,在最后运行的时候,运行时系统便会无法找到相应方法的定义,从而抛出unrecognized selector 错误。

-ObjC干了啥?

那为啥加上-ObjC就好了? 原来,加上-ObjC选项的时候,链接器便会加载静态Library里面所有Objective-C实现的类和Cateogry。

还有啥选项?

除了-ObjC,文档上还有几个其他的选项,也值得我们关注一下。

-all_load 全加载,意思是加载所有静态库的成员。无论是c还是c++还oc。

-force_load path_to_load 对某个指定静态库全加载。而-all_load则会对所有的库进行全加载。

这到这里,这个问题貌似已经可以解决了。嗯,分公司的开发肯定在framework里面打包了几个没有用到的额外同名实现,而加上-ObjC,会将所有方法全加载上,于是duplicated symbols错误便被抛出。

那么,如果libPod,也就是pod库生成的静态库前面加上-force_load,而不加上-ObjC,问题不就顺利解决了?

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

推荐阅读更多精彩内容