在應用開發過程中,經常會用到靜態庫,比如音視頻編解碼靜態庫、友盟分享靜態庫、第三方支付靜態庫...有時靜態庫中也會引入一些第三方框架,如果項目中碰巧也引入了相同的第三方,有時候編譯的時候就可能會提示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、重新編譯。
通過一系列的調試,我是使用方案三解決這個問題的,希望這段調試之路可以幫助到需要的小伙伴。