解決iOS第三方SDK之間重復的symbols問題


前言:今天公司項目准備使用高德導航,其中用到了高德3D地圖SDK,然后就出現bug了。在真機上可以完美運行,但是在模擬器上,就出現了一大片的bug:提示有82個Duplicate symbols,仔細一看是MobileVLCKit和高德的MAMapKit之間的問題。(PS:今天是真心累啊,不過解決了bug,還是很值得的。)


現在,我就今天踩過的坑,做個簡單的整理,以備以后翻看。 也希望以后遇到類似坑的小伙伴們,可以有些許啟發和不同見解。


問題描述及猜想



duplicate symbols.png

上圖為部分報錯內容。兩個第三方SDK之間在某些特定平台存在一些duplicate symbols。分析:那是不是除掉其中一個SDK中相應平台上,重復的那部分symbols,是不是就解決問題了呢?且繼續向下看。


解決問題


通過查找資料,各種扒論壇,終於發現,跟我一起踩坑的小伙伴們還真不少。
然后通過借鑒他們的經驗,在對linux的相關語法實在小白的情況下,終於解決問題了,好感動啊!!!


工具介紹


lipo

lipo是管理Fat File的工具, 可以查看平台列表, 提取特定平台, 重新打包。

nm

nm用來顯示一個程序包的符號表, 默認會顯示入口地址, 符號類型, 符號名。

strip

strip用來刪除程序里的符號表。-R 用來指定一個要刪除的符號列表, 使用上述生成的symbols文件.。添加 -S 選項來保留其他符號。

ar

ar可以查看一個程序包里的對象文件列表, 解壓出其中的對象文件並重新打包。

ld

ld蘋果系統下的鏈接器, 可以更精確的控制符號表的導出。


具體步驟


因為擔心修改MobileVLCKit對已上線的視頻播放造成不可估計的影響,因此,此次修改MAMapKit,出現任何bug也可以盡快發現並解決。
下面將進行十分小白式的記錄(PS:主要是我太小白了。)

cd path(framework的路徑) lipo -info MAMapKit

lipo info MAMapKit

查看MAMapKit的適用平台,可以發現arm7,i386,x86_64,arm64均可用。並且前面bug只是存在於x86_64平台上,那么就先修改這個平台的內容。

 lipo -thin x86_64 MAMapKit -output MAMapKit.x86_64

文件瘦身,提取x86_64平台的MAMapKit到新的文件MAMapKit.x86_64,發現該文件只有3M而已(源文件20.2M),該文件位置與MAMapKit相同,發現確實單個平台的文件比較小。

nm -j MAMapKit.x86_64 | grep png > symbols
  • 獲取MAMapKit.x86_64文件中以_png為前綴的所有符號,生成符號列表並存於symbols文件中。( -j 選項控制只輸出符號名)

  • 因為上面的symbols內容不是上述bug中包含的內容,因此,需要更改該symbols文件,刪除里面所有符號,將報錯的所有重復符號

_png_do_invert _png_set_shift _png_get_user_transfom_ptr ...

這些符號依次輸入到該文件中,每行一個。這就將本次需要刪除的符號存在符號列表中了。

ar -t MAMapKit.x86_64

ar -t MAMapKit.x86_64

可以發現整個包中就一個主要文件MAMapKit-x86_64-master.o文件,這也是前面bug中提到的重名符號所在的位置。(PS:更確定找對了方法)


Duplicate symbols path
ar -x MAMapKit.x86_64

MAMapKit.x86_64 File Path

可以發現多出了三個文件,也獲得了需要的MAMapKit-86_64-master.o文件。

ld -x -r -unexported_symbols_list symbols MAMapKit-x86_64-master.o -o MAMapKit-x86_64-master.o.strip

可以將symbols文件中的符號列表在MAMapKit-x86_64-master.o文件中刪除掉,並生成一個新的文件MAMapKit-x86_64-master.o.strip。

ar -r MAMapKit.x86_64 MAMapKit-x86_64-master.o.strip Pods-MAMapKit-dummy.o
  • 在執行此命令之前,可以將前面獲得MAMapKit.x86_64文件放在其他位置作為對比。
  • 然后通過該命令得到一個新打包好的x86_64平台包。
  • 也可以用以前的獲取symbols的方式從這個新包中獲取相應的_png的所有符號表,查詢剛才需要刪除的符號,驗證那些符號是否已被刪除。(很高興確實已經刪除了,這下問題應該可以解決了吧。)

下面將替換原有包中的x86_64平台包。(該文件中只修改了x86_64平台的內容)

lipo MAMapKit -replace x86_64 MAMapKit.x86_64 -output MAMapKitTest

用上面生成的新包替換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)](http://blog.csdn.net/volvet/article/details/50097563)

 

轉載:http://www.jianshu.com/p/e857730015cf


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM