2015-10-20 169 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