你的位置:首页 > 操作系统

[操作系统]iOS开发 引用第三方库出现duplicate symbol时的处理方法


 
该篇文章是我自己从我的新浪博客上摘抄过来的, 原文链接为: http://blog.sina.com.cn/s/blog_dcc636350102wat5.html
 
 
在iOS开发中, 难免会集成别人的三方类库, 当集成的三方类库过多时, 难免会出现某些库同时使用了同样的函数库,导致link的时候报错提示duplicate symbol。详情见图:
 



 
这样的报错让我们觉得很麻烦, 这样的文件重复错误, 不是由自己的程序中的代码造成的, 而是别人的三方类库, 也就是说,这种情况下, 我们没有办法通过修改自己的代码而使问题得到解决。 我们就只能要求第三方(函数库的提供方)提供源码, 然后自己修改,或者是让三方代码提供者自己修改了之后给我们, 不管怎样, 多少会觉得有点无理要求了。  那么我们就只能想想办法自己解决了, 也就是修改.a文件或者framework中的二进制文件。
 
修改这样的错误, 我们需要用到lipo 和 ar 工具。 不知道用法的可以网上稍微搜索一下。
 
那么我们现在就来修改一下吧。
 
 
一、找到重复的库文件(两个库文件重复找其中之一即可, 三个库文件, 找到重复文件的其中两个, .....以此类推),你可以直接在该项目下的文件夹进行操作(不建议, 容易使程序出问题),你也复制这些库文件到其它文件夹进行操作。我们这里复制到其它文件夹下进行操作。需要复制的文件见图:



 
二、打开终端, 并cd 到文件夹下, 使用  lipo -info    ASIAIDCardReader (ASIAIDCardReader替换为自己的文件名称)查看该文件下的架构信息, 留待后用

 
 
三、我们可以看最后一行信息, 此处 Architecturesin the fat file, 说明此处是一个fat文件, 我们需要对该文件先进行瘦身, 即分离出armv7、arm64和armv7s文件。   
使用命令 lipo ASIAIDCardReader -thin armv7-output ASIAIDCardReader.armv7 (ASIAIDCardReader.armv7 中ASIAIDCardReader 可替换为自己的文件名称,且该名称可以自定义), 使用类似的方法(只需要将 .armv7修改为相应的架构信息后缀即可),分离出其它的文件
 



四、文件已经分离出来, 下面我们使用ar 工具, 查看各文件下的二进制文件(.o文件)。 此处我们可以使用 ar -t在终端中查看所有的.o文件



 也可以使用 ar -x将所有.o文件分离到指定的目录文件夹。



根据我们最开始的错误定位,从上面我们都能轻易找到重复的文件 AsyncSocket.o和AsyncSocket相关的文件,接下来就是对分离出来的文件进行修改了。
 
 
五、使用命令 ar -d -sv ASIAIDCardReader.armv7s AsyncSocket.o,即删除ASIAIDCardReader.armv7s下的 AsyncSocket.o二进制文件(你只需要替换成你自己的库文件名称和.o文件即可),同样对分离出来的.arm64、.armv7s进行同样的操作。 
 



 
六、文件修改好了, 接下来我们需要把修改好的文件,全部再组合成我们原来的framework下的fat文件。使用命令 
 lipo-create -output ASIAIDCardReaderASIAIDCardReader.armv7sASIAIDCardReader.arm64 ASIAIDCardReader.armv7(此处需要把所有分离出来的文件都加上)
为了使我们确认还原了ASIAIDCardReader文件, 我们将复制文件夹下的该文件删除, 再进行操作。使用命令之后, 我们就能看到生成了一个新的 ASIAIDCardReader文件, 这就是我们修改之后,符合我们需求的文件了。 
 
七、将修改好的文件, 拖拽到原文件夹下,替换原文件即可。 
 
注:其它由重复的framework, 按照以上方法重复一遍即可。
 
好了, 按照这样的方法, 我解决了自己的问题, 有什么不对的地方, 还希望大家多多指点, 最后,此教程借助博客:http://angelolloqui.com/blog/31-How-to-fix-a-Duplicated-Symbols-error-on-binary-files