admin 发表于 2016-6-12 14:53:52

使用-all_load参数后导致ld: duplicate symbol xxxx错误的解决办法

一、错误现象:
通常来说,单独使用AnyChat类库是不需要增加-all_load参数的,但如果在项目中使用了第三方的类库,而第三方类库又必须使用-all_load参数时,就会导致编译出错,形如:duplicate symbol _vp8_decode_frame in:
    ../../sdk/libs/libvpx.a(decodframe.c.o)
    ../../sdk/libs/libvpx.a(decodeframe.c.o)
ld: 39 duplicate symbols for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
二、形成原因:
至于为什么要使用-all_load参数,是因为Apple的部分编译机制所导致的,可参考:
Objective C 中特有的语法特性 Category 大家肯定很熟悉,类似于C#中的扩展方法,可以在一个类的外面扩展这个类的功能,使得我们可以方便的为系统类添加自己的功能,比如为 NSString 添加 md5 编码。在编译到静态库时,这些代码模块实际上是存在不同的obj文件里的。程序在连接Category方法时,实际上只加载了Category模块,扩展的基类代码并没有被加载。这样,程序虽然可以编译通过,但是在运行时,因为找不到基类模块,就会出现 unrecognized selector 这样的错误。
三、解决方案:
有两个解决方案,使用-all_load 的替代参数。
1、苹果的官方文档里给了我们一个解决方案,去掉-all_load参数,使用 -ObjC 参数。它的文档说,-ObjC 参数会把所有的 Objective-C 代码模块加载。
2、另外一个解决方案是去掉-all_load参数,使用 -force_load 参数,我们可以只加载感兴趣的 静态库,对于第三方类库,用force_load参数进行强制加载,便可解决因第三方类库不能完全加载所导致的“ unrecognized selector”出错。注意,-force_load后面需要跟一个类库的地址,如:“-force_load $(BUILT_PRODUCTS_DIR)/libxxx.a”,如果第三方类库有多个.a文件,则需要使用多个-force_load进行强制加载。

四、参考:
1、Building Objective-C static libraries with categories(Apple官方的解决方案)
2、谈谈关于使用category的静态库
3、Objective-C categories in static library;
4、How can I avoid “duplicate symbol” errors in xcode with shared static libraries?


页: [1]
查看完整版本: 使用-all_load参数后导致ld: duplicate symbol xxxx错误的解决办法