翻譯--How to fix a "Duplicated Symbols" error on binary files

原文作者:Angel G. Olloqui
原文鏈接:http://angelolloqui.com/blog/31-How-to-fix-a-Duplicated-Symbols-error-on-binary-files

介紹

將第三方庫包含在項目中時,可能會在鏈接過程中遇到“Duplicated Symbols(重復(fù)的符號)”錯誤畔柔。 這個令人討厭的錯誤是由于您的一個或多個類別之間的名稱沖突唬复,通常是由以下兩種之一引起的:

  • 您不使用前綴作為命名空間橡淑,并使用通用名稱悉尾,如Ses sion主儡,User或similar暑诸。 這有一個簡單的解決方案,因為所有你需要做的是重命名你的類使用前綴峰搪。 例如岔冀,User可以重命名為AGUser。使用前綴是一個很好的做法概耻,您應(yīng)該始終遵循沒有像C或Objective-C這樣的命名空間的編程語言使套。
  • 一個或多個庫包含同一個第三方庫。這在靜態(tài)框架和某些構(gòu)建的庫中是相當(dāng)普遍的鞠柄。 通常侦高,庫的創(chuàng)建者包括通用實用程序,例如SBJON厌杜,Reachability以及編譯二進制內(nèi)的類似內(nèi)容奉呛。然后,您的項目或其他使用它的庫嘗試再次包含它夯尽,導(dǎo)致重復(fù)的符號錯誤瞧壮。 如果您有權(quán)訪問源代碼,可以將重復(fù)的一個從您的目標(biāo)中輕松解決呐萌。不幸的是馁痴,當(dāng)這個問題發(fā)生時,很多次來自編譯的庫或框架肺孤,它們不能讓我們控制源代碼文件,而只是用一個二進制文件替代济欢。解決這個問題可能看起來并不容易赠堵,甚至只是有可能,但正如我們將在這篇文章中提的那樣法褥,并不難看到癥結(jié)所在茫叭。

特別考慮

整個帖子假定兩個重復(fù)的庫是相同的版本,或至少完全向后兼容半等。此外揍愁,我們還假設(shè)兩個重復(fù)的庫都沒有被修改,因為任何修改都可能會破壞注釋的兼容性杀饵。如果庫不兼容莽囤,那么您將需要分析差異,并查看是否可以使用“混合”庫來提供所需的兼容性切距,或者移動其中一個組件以使用其他不兼容的版本朽缎。無論如何,解決方案非常受您的應(yīng)用程序的約束,有點舍本逐末话肖。

舉個栗子

為了提高可讀性北秽,我們將修復(fù)一個真正的項目。 在這個示例項目中最筒,我們有一個名為Serenity的靜態(tài)框架贺氓,其中包含SBJSON庫。將CocoaPods與“unoffical-twitter-sdk”一起使用時床蜘,會出現(xiàn)重復(fù)的符號辙培,這也與SBJSON有關(guān)系。 在這種情況下悄泥,重復(fù)的符號因此包含在Serenity和Pods.a二進制文件中虏冻。
我們可以通過操控Podspecs來解決它,從“unoffical-twitter-sdk”中刪除SBJSON弹囚,但是我們決定將SBJSON從Serenity中刪除厨相,因為它不應(yīng)該被添加在第一個實例中,反正它包含 在CocoaPods中的一個舊版本的SBJSON鸥鹉。

content_duplicatedsymbols.png

您應(yīng)該能夠在項目中沖突的庫中遵循相同的過程蛮穿。 只需檢查并確定要保留的版本,以及要刪除的版本(通常保留較新的版本)毁渗。

Slimming down the fat binary

大多數(shù)庫實際上是胖二進制文件践磅。 這意味著您可以在同一文件中找到多個架構(gòu)的編譯二進制代碼。例如灸异,在我們的示例項目中府适,Serenity框架包含三種架構(gòu):i386(模擬器),armv7(iPhone 3GS +兼容)和armv7(iPhone 5)肺樟。 注意檐春,在寫這篇文章的時候,armv7不能被lipo工具識別為有效的架構(gòu)(它被顯示為“cputype(12)cpusubtype(11)”)么伯,所以我們需要做一個小技巧來支持它疟暖。希望蘋果將盡快更新這些工具來支持它。 您可以通過運行以下方式檢查庫的體系結(jié)構(gòu):

$ lipo Serenity -info
Architectures in the fat file: Serenity are: armv7 (cputype (12) cpusubtype (11)) i386
為了繼續(xù)整個過程田柔,我們需要在自己的文件中提取每個架構(gòu)俐巴。 我們可以通過運行:
$ lipo Serenity -thin armv7 -output Serenity.armv7
$ lipo Serenity -thin i386 -output Serenity.i386
$ xcrun -sdk iphoneos lipo Serenity -thin armv7s -output Serenity.armv7s

注意在最后一種情況下使用xcrun是由于缺乏對armv7的支持。 在這篇文章中解釋的其余步驟同樣適用于armv7硬爆,armv7s和i386欣舵。

Removing duplicated symbols

現(xiàn)在我們在瘦文件中有兩種不同的架構(gòu),我們可以繼續(xù)刪除每個文件上的重復(fù)符號摆屯。 讓我們先來看看靜態(tài)包中包含的符號:

$ ar -t Serenity.armv7
__.SYMDEF
MainView.o
PushRequest.o
PaymentViewController.o
SBJsonBase.o
SBJsonParser.o
SBJsonWriter.o
NSObject+SBJSON.o
NSString+SBJSON.o
FileManager.o
Barcode.o
qr_draw_png.o
QR_Encode.o
png.o
pngerror.o
pngget.o
pngmem.o
pngpread.o
pngread.o
pngrio.o
pngrtran.o
pngrutil.o
pngset.o
pngtrans.o
pngwio.o
pngwrite.o
pngwtran.o
pngwutil.o

我們選擇了armv7版本邻遏,但是i386和armv7應(yīng)該是一樣的糠亩。

我們懷疑,庫中包含五個符號:
SBJsonBase.o
SBJsonParser.o
SBJsonWriter.o
NSObject+SBJSON.o
NSString+SBJSON.o
我們只需要運行:

$ ar -d -sv Serenity.armv7 SBJsonBase.o
d - SBJsonBase.o

運行其他4個符號的命令准验。 然后赎线,重復(fù)一切與其他架構(gòu)(i386和armv7s在我們的情況)。 如果再次使用ar -t選項檢查二進制文件糊饱,那么您應(yīng)該看到符號不再存在垂寥。

Fattening the library

好的,我們差不多完成了 我們有三種架構(gòu)沒有重復(fù)的符號另锋。 我們現(xiàn)在需要做的就是將它們重新組合成一個將用于我們項目的胖庫滞项。 所以首先讓我們移動舊版本并保留一個副本,以防出現(xiàn)問題夭坪。

$ mv Serenity Serenity_original

And now lets build the fat library:

$ lipo Serenity.armv7 Serenity.armv7s Serenity.i386 -create -output Serenity

你做到了文判! 你應(yīng)該有一個新的二進制文件沒有重復(fù)的類。 您現(xiàn)在可以刪除中間的Serenity.armv7室梅,Serenity.armv7s和Serenity.i386文件戏仓,因為它們不再需要。

Finishing

如果您現(xiàn)在再次構(gòu)建項目亡鼠,您應(yīng)該可以鏈接赏殃,而不會在之前呈現(xiàn)的重復(fù)符號錯誤(至少沒有這個,也許你有另一個)间涵。
重要的是仁热,您再次測試您的應(yīng)用程序,因為如果上述任何特殊注意事項不能滿足您的應(yīng)用程序可能會發(fā)生故障甚至崩潰勾哩。 測試抗蠢,測試和測試!
最后記住思劳,你只是修改了第三方庫物蝙,所以不要忘記,任何更新都可能會再次包含重復(fù)的符號敢艰。 請不要責(zé)怪我,如果有什么不起作用册赛,只要求你的第三方開發(fā)人員正確地完成工作钠导,并將依賴關(guān)系從二進制文件中刪除:D。

以上森瘪;
分割線---------------------------------------------------------

謝謝牡属!如有出入,敬請見諒扼睬!之前使用融云的庫有過這個沖突逮栅,就依照這個方法順利解決悴势。嗯,就這樣吧措伐,如果還是解決不了特纤,私信我,一起來看看侥加。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捧存,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子担败,更是在濱河造成了極大的恐慌昔穴,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件提前,死亡現(xiàn)場離奇詭異吗货,居然都是意外死亡,警方通過查閱死者的電腦和手機狈网,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門宙搬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人孙援,你說我怎么就攤上這事害淤。” “怎么了拓售?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵窥摄,是天一觀的道長。 經(jīng)常有香客問我础淤,道長崭放,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任鸽凶,我火速辦了婚禮币砂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘玻侥。我一直安慰自己决摧,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布凑兰。 她就那樣靜靜地躺著掌桩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪姑食。 梳的紋絲不亂的頭發(fā)上波岛,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天,我揣著相機與錄音音半,去河邊找鬼则拷。 笑死贡蓖,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的煌茬。 我是一名探鬼主播斥铺,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼宣旱!你這毒婦竟也來了仅父?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤浑吟,失蹤者是張志新(化名)和其女友劉穎笙纤,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體组力,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡省容,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了燎字。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片腥椒。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖候衍,靈堂內(nèi)的尸體忽然破棺而出笼蛛,到底是詐尸還是另有隱情,我是刑警寧澤蛉鹿,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布滨砍,位于F島的核電站,受9級特大地震影響妖异,放射性物質(zhì)發(fā)生泄漏惋戏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一他膳、第九天 我趴在偏房一處隱蔽的房頂上張望响逢。 院中可真熱鬧,春花似錦棕孙、人聲如沸舔亭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽分歇。三九已至,卻和暖如春欧漱,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葬燎。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工误甚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留缚甩,地道東北人。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓窑邦,卻偏偏與公主長得像擅威,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子冈钦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容