解决iOS第三方SDK之间重复的symbols问题
前言:某项目准备使用高德导航,其中用到了高德3D地图SDK,然后就出现bug了。在真机上可以完美运行,但是在模拟器上,就出现了一大片的bug:提示有82个
Duplicate symbols
,仔细一看是MobileVLCKit
和高德的MAMapKit
之间的问题。
问题描述及猜想
上图为部分报错内容。两个第三方SDK之间在某些特定平台存在一些duplicate symbols。分析:那是不是除掉其中一个SDK中相应平台上,重复的那部分symbols,是不是就解决问题了呢?且继续向下看。
工具介绍
lipo
lipo是管理Fat File的工具, 可以查看平台列表, 提取特定平台, 重新打包。
nm
nm用来显示一个程序包的符号表, 默认会显示入口地址, 符号类型, 符号名。
strip
strip用来删除程序里的符号表。-R 用来指定一个要删除的符号列表, 使用上述生成的symbols文件.。添加 -S 选项来保留其他符号。
ar
ar可以查看一个程序包里的对象文件列表, 解压出其中的对象文件并重新打包。
ld
ld苹果系统下的链接器, 可以更精确的控制符号表的导出。
具体步骤
因为担心修改MobileVLCKit
对已上线的视频播放造成不可估计的影响,因此,此次修改MAMapKit
,出现任何bug也可以尽快发现并解决。
下面将进行十分小白式的记录
查看MAMapKit的适用平台,可以发现arm7,i386,x86_64,arm64均可用。并且前面bug只是存在于x86_64平台上,那么就先修改这个平台的内容。
|
|
文件瘦身,提取x86_64平台的MAMapKit到新的文件MAMapKit.x86_64,发现该文件只有3M而已(源文件20.2M),该文件位置与MAMapKit相同,发现确实单个平台的文件比较小。
|
|
获取MAMapKit.x86_64文件中以_png为前缀的所有符号,生成符号列表并存于symbols文件中。( -j 选项控制只输出符号名)
因为上面的symbols内容不是上述bug中包含的内容,因此,需要更改该symbols文件,删除里面所有符号,将报错的所有重复符号
|
|
这些符号依次输入到该文件中,每行一个。这就将本次需要删除的符号存在符号列表中了。
|
|
可以发现整个包中就一个主要文件MAMapKit-x86_64-master.o文件,这也是前面bug中提到的重名符号所在的位置。(PS:更确定找对了方法)
|
|
可以发现多出了三个文件,也获得了需要的MAMapKit-86_64-master.o文件。
|
|
可以将symbols文件中的符号列表在MAMapKit-x86_64-master.o文件中删除掉,并生成一个新的文件MAMapKit-x86_64-master.o.strip。
|
|
在执行此命令之前,可以将前面获得MAMapKit.x86_64文件放在其他位置作为对比。
然后通过该命令得到一个新打包好的x86_64平台包。
也可以用以前的获取symbols的方式从这个新包中获取相应的_png的所有符号表,查询刚才需要删除的符号,验证那些符号是否已被删除。(很高兴确实已经删除了,这下问题应该可以解决了吧。)
下面将替换原有包中的x86_64平台包。(该文件中只修改了x86_64平台的内容
|
|
用上面生成的新包替换MAMapKit包中的x86_64平台包,然后生成一个新的文件包,最后将旧的MAMapKit包移除,其他多余内容也一并移除,将MAMapKitTest更名为MAMapKit。至此,MAMapKit.framework看起来跟原来的没有什么区别了。(看事情不能只看表面哦,咱修改的是内在!)
多余的话:如果修改多个平台的包(因为我只需要修改x86_64这一个平台包),可能需要重新生成一个新包更合适。
- 根据前面的方法,生成每个平台的新包;
- 将所有新包对应各个平台,生成一个新包。
上图红色标记即最后的合成新包方法。在此之前记得将前面更改过的x86_64平台包拷贝到这些包的相同路径下。
最后重新编译工程,就这么完美解决了!!!这一刻的感觉,太激动了。暂时未发现有什么问题,以后有什么由此衍生的bug,到时候再更新了。也希望小伙伴们共同学习,有问题大家一定要指出来哟!欢迎大家找我交流问题一起进步哦。
感谢下面两位大神踩过的坑,有了它们的经验,才让我如此顺利的解决问题!
[1]Mac系统下lipo, ar, nm等工具的使用简介
[2]Lipo - 如何为ARMv7/ARMv7s/ARM64架构 创建通用文件(Universal Files)