靜態(tài)庫duplicate symbols

符號表和編譯鏈

一個程序從簡單易讀的代碼到可執(zhí)行文件往往要經(jīng)歷以下步驟:

源代碼 > 預(yù)處理器 > 編譯器 > 匯編器 > 機器碼 > 鏈接器 > 可執(zhí)行文件

源文件經(jīng)過一系列處理以后烤镐,會生成對應(yīng)的.o文件,然后一個項目必然會有許多.o文件市俊,并且這些文件之間會有各種各樣的聯(lián)系,例如函數(shù)調(diào)用。鏈接器做的事就是把這些目標(biāo)文件和所用的一些庫鏈接在一起形成一個完整的可執(zhí)行文件仅政。

通俗的講兴想,我們在源碼中寫的全局變量名斩例、函數(shù)名類名在生成的*.o對象文件中都叫做符號吼具,存在一個叫做符號表的地方僚纷。

舉個例子:

我們在a.c文件中寫了一個函數(shù)叫foo()矩距,然后在main.c文件中調(diào)用了foo()函數(shù)拗盒,在將源碼編譯生成的對象文件中a.o對象文件中的符號表里保存著foo()函數(shù)符號,并通過該符號可以定位到a.o文件中關(guān)于foo()方法的具體實現(xiàn)代碼锥债。

鏈接器在鏈接生成最終的二進制程序的時候會發(fā)現(xiàn)main.o對象文件中引用了符號foo()陡蝇,而foo()符號并沒有在main.o文件中定義,所以不會存在與main.o對象文件的符號表中哮肚,于是鏈接器就開始檢查其他對象文件登夫,當(dāng)檢查到a.o文件中定義了符號foo(),于是就將a.o對象文件鏈接進來允趟。這樣就確保了在main.c中能夠正常調(diào)用a.c中實現(xiàn)的foo()方法了恼策。

注意: Objective-C 中方法的執(zhí)行是在運行時決定的,所以鏈接器只鏈接類的符號潮剪,不鏈接方法的符號

.a靜態(tài)庫

一般可能是.a靜態(tài)庫和工程里面的某個類重復(fù)了涣楷,得到錯誤比如:

duplicate symbol _OBJC_CLASS_$_GTMBase64 in:
    *****
duplicate symbol _OBJC_METACLASS_$_GTMBase64 in:
    *****
ld: 2 duplicate symbols for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

從上面錯誤我們可以看出在arm64這個架構(gòu)的靜態(tài)鏈接庫出現(xiàn)了類名重復(fù),我們可以得到對應(yīng)架構(gòu)的靜態(tài)鏈接庫里面所有類和分類的信息(以.o結(jié)尾的文件)抗碰,所以可以把某個重復(fù)的類刪除了狮斗,重新打包成靜態(tài)庫。具體參考處理.a靜態(tài)庫弧蝇。

Other Linker Flags

一般你的工程里Other Linker Flags會設(shè)置了-ObjC碳褒。如果我們刪除了-ObjC折砸,就會發(fā)現(xiàn)在編譯時不會有duplicate symbols的錯誤了。但是運行的時候可能會出現(xiàn)unrecognized selector sent to class 0x105494cd8的錯誤沙峻。這是由于靜態(tài)庫中的分類沒被鏈接器鏈接進可執(zhí)行文件中睦授。

對于ObjC,官方解釋如下:

This flag causes the linker to load every object file in the library that defines an Objective-C class or category. While this option will typically result in a larger executable (due to additional object code loaded into the application), it will allow the successful creation of effective Objective-C static libraries that contain categories on existing classes.

簡單的說就是ObjC會把靜態(tài)庫中所有的類和分類都鏈接進可執(zhí)行文件摔寨,但是它不會去檢查此類是否重復(fù)了睹逃,所以才會出現(xiàn)duplicate symbols的錯誤。

所以這里我們想要的就是只把分類給鏈接進去祷肯,而ObjC顯然會帶出其他問題沉填。
這里有另一個配置-force_load,這個的作用其實跟ObjC是類似的佑笋。它是只指定某一個靜態(tài)庫才執(zhí)行鏈接所有類和分類的操作翼闹,而ObjC表示的是所以靜態(tài)庫。

所以理想的狀態(tài)就是不使用ObjC蒋纬,只有包含分類的靜態(tài)庫才使用-force_load猎荠,這樣既能避免一些不必要的文件使包變大,又能使出現(xiàn)duplicate symbols的概率減小蜀备。

為什么只是減小呢关摇?因為如果你這個靜態(tài)庫里即有重復(fù)文件又存在分類,那只能使用-force_load碾阁,同時那個重復(fù)的類也鏈接進來了输虱,這樣duplicate symbols就還會出現(xiàn)。

總結(jié)解決辦法

  • 如果是工程里的類跟靜態(tài)庫重名了脂凶,那可以重命名工程里面的類名宪睹。
  • 如果是兩個靜態(tài)庫有重名了,可以解壓靜態(tài)庫蚕钦,把重復(fù)的類刪了亭病,然后重新打包并合并兩個靜態(tài)庫(要確保兩個重復(fù)類結(jié)構(gòu)相同)
  • 如果重復(fù)的類所在的靜態(tài)庫沒有分類,那Other Linker Flags中可以去掉ObjC嘶居,只在有分類的靜態(tài)庫前加上-force_load罪帖。

參考

ios 靜態(tài)庫沖突的解決辦法
解決兩個靜態(tài)庫沖突 duplicate symbols
How can I avoid “duplicate symbol” errors in xcode with shared static libraries?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市邮屁,隨后出現(xiàn)的幾起案子整袁,更是在濱河造成了極大的恐慌,老刑警劉巖樱报,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葬项,死亡現(xiàn)場離奇詭異,居然都是意外死亡迹蛤,警方通過查閱死者的電腦和手機民珍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門襟士,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人嚷量,你說我怎么就攤上這事陋桂。” “怎么了蝶溶?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵嗜历,是天一觀的道長。 經(jīng)常有香客問我抖所,道長梨州,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任田轧,我火速辦了婚禮暴匠,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘傻粘。我一直安慰自己每窖,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布弦悉。 她就那樣靜靜地躺著窒典,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稽莉。 梳的紋絲不亂的頭發(fā)上瀑志,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機與錄音肩祥,去河邊找鬼后室。 笑死缩膝,一個胖子當(dāng)著我的面吹牛混狠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疾层,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼将饺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了痛黎?” 一聲冷哼從身側(cè)響起予弧,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎湖饱,沒想到半個月后掖蛤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡井厌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年蚓庭,在試婚紗的時候發(fā)現(xiàn)自己被綠了致讥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡器赞,死狀恐怖垢袱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情港柜,我是刑警寧澤请契,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站夏醉,受9級特大地震影響爽锥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜畔柔,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一救恨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧释树,春花似錦肠槽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至桩盲,卻和暖如春寂纪,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背赌结。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工捞蛋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人柬姚。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓拟杉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親量承。 傳聞我的和親對象是個殘疾皇子搬设,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,614評論 2 353

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