前言:今天公司項(xiàng)目準(zhǔn)備使用高德導(dǎo)航燕垃,其中用到了高德3D地圖SDK匿醒,然后就出現(xiàn)bug了毫炉。在真機(jī)上可以完美運(yùn)行,但是在模擬器上果港,就出現(xiàn)了一大片的bug:提示有82個Duplicate symbols沦泌,仔細(xì)一看是MobileVLCKit和高德的MAMapKit之間的問題。(PS:今天是真心累啊辛掠,不過解決了bug谢谦,還是很值得的。)
現(xiàn)在萝衩,我就今天踩過的坑回挽,做個簡單的整理,以備以后翻看欠气。 也希望以后遇到類似坑的小伙伴們厅各,可以有些許啟發(fā)和不同見解。
問題描述及猜想
上圖為部分報(bào)錯內(nèi)容预柒。兩個第三方SDK之間在某些特定平臺存在一些duplicate symbols队塘。分析:那是不是除掉其中一個SDK中相應(yīng)平臺上,重復(fù)的那部分symbols宜鸯,是不是就解決問題了呢憔古?且繼續(xù)向下看。
解決問題
通過查找資料淋袖,各種扒論壇鸿市,終于發(fā)現(xiàn),跟我一起踩坑的小伙伴們還真不少。
然后通過借鑒他們的經(jīng)驗(yàn)焰情,在對linux的相關(guān)語法實(shí)在小白的情況下陌凳,終于解決問題了,好感動澳谥邸:隙亍!验游!
工具介紹
lipo
lipo是管理Fat File的工具, 可以查看平臺列表, 提取特定平臺, 重新打包充岛。
nm
nm用來顯示一個程序包的符號表, 默認(rèn)會顯示入口地址, 符號類型, 符號名。
strip
strip用來刪除程序里的符號表耕蝉。-R 用來指定一個要刪除的符號列表, 使用上述生成的symbols文件.崔梗。添加 -S 選項(xiàng)來保留其他符號。
ar
ar可以查看一個程序包里的對象文件列表, 解壓出其中的對象文件并重新打包垒在。
ld
ld蘋果系統(tǒng)下的鏈接器, 可以更精確的控制符號表的導(dǎo)出蒜魄。
具體步驟
因?yàn)閾?dān)心修改MobileVLCKit對已上線的視頻播放造成不可估計(jì)的影響,因此爪膊,此次修改MAMapKit权悟,出現(xiàn)任何bug也可以盡快發(fā)現(xiàn)并解決砸王。
下面將進(jìn)行十分小白式的記錄(PS:主要是我太小白了推盛。)
cd path(framework的路徑)
lipo -info MAMapKit
查看MAMapKit的適用平臺,可以發(fā)現(xiàn)arm7谦铃,i386耘成,x86_64,arm64均可用驹闰。并且前面bug只是存在于x86_64平臺上瘪菌,那么就先修改這個平臺的內(nèi)容。
lipo -thin x86_64 MAMapKit -output MAMapKit.x86_64
文件瘦身嘹朗,提取x86_64平臺的MAMapKit到新的文件MAMapKit.x86_64师妙,發(fā)現(xiàn)該文件只有3M而已(源文件20.2M),該文件位置與MAMapKit相同屹培,發(fā)現(xiàn)確實(shí)單個平臺的文件比較小默穴。
nm -j MAMapKit.x86_64 | grep png > symbols
獲取MAMapKit.x86_64文件中以_png為前綴的所有符號,生成符號列表并存于symbols文件中褪秀。( -j 選項(xiàng)控制只輸出符號名)
因?yàn)樯厦娴膕ymbols內(nèi)容不是上述bug中包含的內(nèi)容蓄诽,因此,需要更改該symbols文件媒吗,刪除里面所有符號仑氛,將報(bào)錯的所有重復(fù)符號
_png_do_invert
_png_set_shift
_png_get_user_transfom_ptr
...
這些符號依次輸入到該文件中,每行一個。這就將本次需要刪除的符號存在符號列表中了锯岖。
ar -t MAMapKit.x86_64
可以發(fā)現(xiàn)整個包中就一個主要文件MAMapKit-x86_64-master.o文件介袜,這也是前面bug中提到的重名符號所在的位置。(PS:更確定找對了方法)
ar -x MAMapKit.x86_64
可以發(fā)現(xiàn)多出了三個文件出吹,也獲得了需要的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
- 在執(zhí)行此命令之前赃额,可以將前面獲得MAMapKit.x86_64文件放在其他位置作為對比。
- 然后通過該命令得到一個新打包好的x86_64平臺包叫确。
- 也可以用以前的獲取symbols的方式從這個新包中獲取相應(yīng)的_png的所有符號表跳芳,查詢剛才需要刪除的符號,驗(yàn)證那些符號是否已被刪除竹勉。(很高興確實(shí)已經(jīng)刪除了飞盆,這下問題應(yīng)該可以解決了吧。)
下面將替換原有包中的x86_64平臺包次乓。(該文件中只修改了x86_64平臺的內(nèi)容)
lipo MAMapKit -replace x86_64 MAMapKit.x86_64 -output MAMapKitTest
用上面生成的新包替換MAMapKit包中的x86_64平臺包吓歇,然后生成一個新的文件包,最后將舊的MAMapKit包移除票腰,其他多余內(nèi)容也一并移除城看,將MAMapKitTest更名為MAMapKit。至此杏慰,MAMapKit.framework看起來跟原來的沒有什么區(qū)別了测柠。(看事情不能只看表面哦,咱修改的是內(nèi)在T道摹)
多余的話:如果修改多個平臺的包(因?yàn)槲抑恍枰薷膞86_64這一個平臺包)轰胁,可能需要重新生成一個新包更合適。
- 根據(jù)前面的方法朝扼,生成每個平臺的新包赃阀;
- 將所有新包對應(yīng)各個平臺,生成一個新包擎颖。
上圖紅色標(biāo)記即最后的合成新包方法榛斯。在此之前記得將前面更改過的x86_64平臺包拷貝到這些包的相同路徑下。
最后重新編譯工程肠仪,就這么完美解決了PけА!异旧!這一刻的感覺意述,太激動了。暫時未發(fā)現(xiàn)有什么問題,以后有什么由此衍生的bug荤崇,到時候再更新了拌屏。也希望小伙伴們共同學(xué)習(xí),有問題大家一定要指出來喲术荤!歡迎大家找我交流問題一起進(jìn)步哦倚喂。
感謝下面兩位大神踩過的坑,有了它們的經(jīng)驗(yàn)瓣戚,才讓我如此順利的解決問題端圈!
[1]Mac系統(tǒng)下lipo, ar, nm等工具的使用簡介
[2]Lipo - 如何為ARMv7/ARMv7s/ARM64架構(gòu) 創(chuàng)建通用文件(Universal Files)](http://blog.csdn.net/volvet/article/details/50097563)