2015-10-20 100 views
5

問題

這是通過兩個靜態庫發生在我訪問源代碼。靜態庫函數名稱衝突

我試圖將Rdio SDK安裝到我的項目中(使用these instructions)。我的項目已經大量採用了谷歌的服務,而且似乎是RDIO和谷歌之間的C函數命名衝突:

duplicate symbol _CreateDispatchTimer in: 
    /Users/abdullahbakhach/dev/ios/Vibereel_IOS/Vibereel/Pods/Google/Libraries/libGGLCore.a(GMRAlarm.o) 
    /Users/abdullahbakhach/dev/ios/Vibereel_IOS/Vibereel/Vibereel/rdio-ios-3.1.0/Rdio.framework/Rdio(RDPlayer.o) 
ld: 1 duplicate symbol for architecture armv7 
Google Core is installed on my project using cocoapods, on my podfile I have: 
pod 'Google/SignIn' 

,並在Podfile.lock我:

- Google/Core (1.1.0):   
    - GoogleInterchangeUtilities (~> 1.0) 
    - GoogleNetworkingUtilities (~> 1.0)  
    - GoogleSymbolUtilities (~> 1.0)   
    - GoogleUtilities (~> 1.1)   
    - Google/SignIn (1.1.0):   
    - Google/Core   
    - GoogleSignIn (~> 2.0)   
    - GoogleAppUtilities (1.0.0):   
    - GoogleSymbolUtilities (~> 1.0)   
    - GoogleAuthUtilities (1.0.1):   
    - GoogleNetworkingUtilities (~> 1.0)   
    - GoogleSymbolUtilities (~> 1.0)   
    - GoogleInterchangeUtilities (1.0.0):   
    - GoogleSymbolUtilities (~> 1.0)   
    - GoogleNetworkingUtilities (1.0.0):   
    - GoogleSymbolUtilities (~> 1.0)   
    - GoogleSignIn (2.2.0):   
    - GoogleAppUtilities (~> 1)   
    - GoogleAuthUtilities (~> 1)   
    - GoogleNetworkingUtilities (~> 1)   
    - GoogleUtilities (~> 1)   
    - GoogleSymbolUtilities (1.0.0) 
- GoogleUtilities (1.1.0): 
    - GoogleSymbolUtilities (~> 1.0.0) 

我試圖/研究

我做了一些研究,試圖看到,如果我能以某種方式更改/刪除/書中對這兩個庫的隱藏方法名..但後來我可以在this apple documentation:

沒有從該庫的客戶端隱藏動態庫中定義的Objective-C類或方法的機制。

所以我有點卡住..任何想法?

回答

10

如果您有權訪問源代碼,則可以修改衝突變量或可見性範圍的名稱(例如,使其成爲靜態)。

如果您無法訪問使用庫的源代碼,可以聯繫貢獻者以要求更改名稱/添加前綴/更改函數/變量的可見性。

如果您對該選項不滿意,可以修改其中一個庫的符號表以避免衝突。您可以通過更改衝突函數的可見性或重命名函數來修改符號表。

由於您使用的是OS X,因此您需要在本地計算機上使用Agner Fog(objcopy的模擬)的objconvsee documentation)。

下面是修改符號表庫的步驟:

  1. 打開終端,找到你的圖書館
  2. path/to/rdio/rdio-ios-3.1.0/Rdio.framework/Rdio
  3. 目錄架構爲了什麼建設脂肪庫
  4. lipo -info Rdio
  5. 提取第一個體系結構(armv7)
  6. lipo Rdio -thin armv7 -output Rdio_armv7
  7. 提取衝突對象文件(RDPlayer.o)從對象文件
  8. ar x Rdio_armv7 RDPlayer.o
  9. 列表符號,以確保衝突的功能有功能
  10. nm -gU RDPlayer.o
  11. 更改公開從全球到地方
  12. objconv -nl:_CreateDispatchTimer RDPlayer.o RDPlayer_new.o
  13. 刪除舊的RDPlayer.o並將RDPLayer_new.o重命名爲RDPlayer.o
  14. 確保功能上的目標文件不再可見
  15. nm -gU RDPlayer.o
  16. 更換新的目標文件與舊的歸檔庫和重建符號表
  17. ar r -s Rdio_armv7 RDPlayer.o
  18. 重複步驟5-18其他架構
  19. 將所有架構回到脂肪庫
  20. lipo Rdio_arm64 Rdio_armv7 Rdio_armv7s Rdio_i386 Rdio_x86_64 -create -output Rdio
  21. ...
  22. 利潤
+0

不錯!像魅力一樣工作! – abbood

2

有問題的符號是一個普通的C函數,而不是一個方法(Objective-C方法不會在鏈接器級別發生衝突)。

如果您有訪問源代碼,你可以把一個static如果函數的定義,它看起來大概是這個樣子的面前:

static dispatch_source_t CreateDispatchTimer(double interval, dispatch_queue_t queue, dispatch_block_t block) 

的功能很可能局部的編譯單元,所以這將工作。如果不是,則必須在整個庫項目中對其進行重命名。

+0

感謝尼古拉但不幸的是我*不*訪問源代碼..我會在這個問題 – abbood

+0

@abbood更加明顯不同時爲這些項目開源? – trojanfoe

+0

@trojanfoe不..我們只有 – abbood