在应用开发过程中,经常会用到静态库,比如音视频编解码静态库、友盟分享静态库、第三方支付静态库...有时静态库中也会引入一些第三方框架,如果项目中碰巧也引入了相同的第三方,有时候编译的时候就可能会提示duplicate symbol xxx.
解决方案:
方案一、向静态库提供方反馈,将重复使用的symbol(其实就是变量名)修改一下,然后重新打包静态库;
方案二、使用lipo命令 将静态库中涉及的.o文件移除,然后再重新合并静态库;
相关命令如下:假设冲突的静态库名为libx.a
$ lipo -info libx.a 查看静态库中支持哪些cpu架构
结果:Architectures in the fat file: libx.a are: i386 armv6 armv7
$ lipo -extract_family armv6 -output libx-inter.a libx.a 分离出提示冲突的那个架构的静态库,这里已armv6为例
- 这里需要注意的有个问题,通过这个命令我们是想要分离出一个thin的静态库,然后将.o还原出来。有时候这个命令执行后,再次执行还原出.o命令时会提示错误,原因是这个分离出来的静态库libx-inter.a依然是一个fat的库,此时我们需要继续分离:
lipo libx-inter.a -thin armv6 -output libx-armv6.a lipo libx-inter.a -thin armv7 -output libx-armv7.a
这样就能分离出2份不同版本arm的.a了
ar -x libx-armv6.a
如果libx-inter.a可以直接还原出.o,那我们就可以跳过上面一步,直接分离就好。
注意分离静态库和还原.o可以执行文件的操作,最好放在单独的文件夹里进行。
如果是两个不同静态库相互冲突,我们可以把这个两个静态库还原到同一个文件夹,然后重复的.o文件就会只保留一个。最后再将所有的.o在合并为一个公共的静态库。当然,也可以保留其中一个静态库不变,将另外一个静态库的.o还原出来,删除提示重复的.o,然后再将剩下的.o link回原来的静态库。
link命令如下:
libtool -static -o ../libx-armv6.a *.o 这里是以cup 架构armv6为例link的
当然最终供编译器使用的静态库,是有多份cpu指令的。所以要把通过以上方法link的 thin类型的静态库,合并回fat lib:
lipo -create -output libx.a libx-armv6.a libx-i386.a libx-armv7.a
这样,将fat静态库再重新导入工程,也许就不会出现duplicate symbol了。
方案三、如果方案一、二都无法实现,别担心,我们还可以修改工程里的symbol(变量名)。
duplicate symbol _isDismissing in:
/Users/daruo/Library/Developer/Xcode/DerivedData/XiaoxianRobot-eobqnwnoghynwdayazeefklxkbro/Build/Intermediates.noindex/XiaoxianRobot.build/Debug-iphoneos/XiaoxianRobot.build/Objects-normal/arm64/ASIAuthenticationDialog.o
/Users/daruo/Desktop/XXR_Cloudring/XiaoxianRobot/Libs/iOS_v3.0.1/UCS_VOIP/UCS_VOIPSDK/libucsrtcvideo.a(UCSVoipASIAuthenticationDialog.o)
从上方的提示编译提示可知:“isDismissing”这个变量需要重新命名
- 1、由ASIAuthenticationDialog.o 可以找到变量坐在的类为 ASIAuthenticationDialog,在工程中找到ASIAuthenticationDialog.m
- 2、搜索isDismissing 变量,并重命名(加前缀,后缀都行)
- 3、重新编译。
通过一系列的调试,我是使用方案三解决这个问题的,希望这段调试之路可以帮助到需要的小伙伴。