【转】XCode: duplicate symbol 解决方案
原文地址: https://www.cnblogs.com/wengzilin/p/3734751.html 感谢
遇到引用库重复定义的问题,需要解决,在这里记录一下方便以后查看。
项目需要,同时引用融云和WXFrameworks,XCode编译时报错:
duplicate symbol ******* in:
…*(*******.o)
…*(*******.o)
意思就是在这两个库中都定义了重复文件,编译器认为你重复定义了。至于为什么编译器认为重复定义,个人认为编译器编译全局变量时会根据名字进行编译,会把相同名称的全局变量编译为相同变量,也就是多个编译成一个,而编译器认为这样可能会引起错误,就提醒用户这里有错。
解决方案:
参考了:http://blog.sina.com.cn/s/blog_4beb28f301012bl6.html
删掉了 set building->other linker flag-> -all_load
ios的Framework是共享动态库,不会被打包到app中,非系统Framework静态库都会被打包到app中,所以会产生"Duplicate Symbol"的错误。
在Build Settings->Other link flags中删除所有的-all_load与-force_load, XCode会很smart的去掉"Duplicate Symbol"。
这里:-all_load是把 ABCDEFG 连接器找到所有的库的所有的目标文件都编译起来,所以 A中的目标文件 和 B的某目标文件 xx.o 一旦重名就会报 duplicate symblos 误。
-all_load 是解决苹果自己bug的,64位 mac 会链接不到库的一些目标文件 所以苹果加了个标志 -all_load 强制加入。
-force_load 的作用和 -all_load 一样,但是 不同的是 force_load 需要你指定哪个参与编译, 哪个不参与。也就是说 force 后得跟参数, 路径你得自己指定。
以下是从外国友人那获取的终极解决策略,方案是修改类库:
I’m going to assume that these are two third party libraries that have only provided you with the .a files and not the source code. You can use libtool, lipo and ar on the terminal to extract and recombine the files.
假设有两个三方类库仅提供给你了.a文件,没有源码,你可以通过libtool, lipo和ar在terminal中解压合并他们。
To see what architectures are in the file:
查看文件都支持了什么架构
$ lipo -info libTapjoy.a
Architectures in the fat file: libTapjoy.a are: armv6 i386
Then to extract just armv6, for example:
然后只解压armv6,例如
$ lipo -extract_family armv6 -output libTapjoy-armv6.a libTapjoy.a
$ mkdir armv6
$ cd armv6
$ ar -x …/libTapjoy-armv6.a
You can then extract the same architecture from the other library into the same directory and then recombine them like so:
你可以从另一个类库中解压同样架构的部分,然后将两者合并在一起
$ libtool -static -o …/lib-armv6.a *.o
And then finally, after you’ve done this with each architecture, you can combine them again with lipo:
如上所示,你可以将所有架构都按照这个流程走一遍,然后合并
$ cd …
$ lipo -create -output lib.a lib-armv6.a lib-i386.a
This should get rid of any duplicate symbols, but will also combine the two libraries into one. If you want to keep them separate, or just delete the duplicate from one library, you can modify the process accordingly.
这个过程不仅解决掉了duplicate symbols的问题,也将两个类库合并为一个。如果你想分别保存两个类库,你可以将duplicate的部分从任意一个类库中删除,你可以相应的修改这个过程。