Rdio 和 Google Core 库之间的静态库函数名称冲突

Posted

技术标签:

【中文标题】Rdio 和 Google Core 库之间的静态库函数名称冲突【英文标题】:static library function name conflict between Rdio and Google Core library 【发布时间】:2016-01-18 20:32:43 【问题描述】:

问题

这发生在我可以访问源代码的两个静态库中。

我正在尝试将 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 类或方法。

所以我有点卡住了......有什么想法吗?

【问题讨论】:

【参考方案1】:

如果您有权访问源代码,则可以修改冲突变量的名称或可见范围(例如,使其成为静态)。

如果您无法访问使用库的源代码,您可以联系贡献者要求更改名称/添加前缀/更改函数/变量的可见性。

如果您对该选项不满意,您可以修改其中一个库上的符号表以避免冲突。您可以通过更改冲突函数的可见性或重命名函数来修改符号表。

因为您使用的是 OS X,所以您需要在本地计算机 (see documentation) 上拥有由 Agner Fog(类似 objcopy)提供的 objconv。

以下是为库修改符号表的步骤:

    打开终端并找到您的图书馆 path/to/rdio/rdio-ios-3.1.0/Rdio.framework/Rdio 列出构建胖库的架构 lipo -info Rdio 提取第一个架构 (armv7) lipo Rdio -thin armv7 -output Rdio_armv7 提取冲突的对象文件 (RDPlayer.o) ar x Rdio_armv7 RDPlayer.o 列出目标文件中的符号以确保存在冲突的功能 nm -gU RDPlayer.o 将函数的可见性从全局更改为局部 objconv -nl:_CreateDispatchTimer RDPlayer.o RDPlayer_new.o 删除旧的 RDPlayer.o 并将 RDPlayer_new.o 重命名为 RDPlayer.o rm RDPLayer.o && mv RDPLayer_new.o RDPlayer.o 确保函数在目标文件中不再可见 nm -gU RDPlayer.o 用归档库中的旧目标文件替换新目标文件并重建符号表 ar r -s Rdio_armv7 RDPlayer.o 对其他架构重复步骤 5-18 将所有架构重新组合到胖库中 lipo Rdio_arm64 Rdio_armv7 Rdio_armv7s Rdio_i386 Rdio_x86_64 -create -output Rdio ... 利润

【讨论】:

【参考方案2】:

有问题的符号是一个普通的 C 函数,而不是一个方法(Objective-C 方法不会在链接器级别发生冲突)。

如果你可以访问源代码,你可以在函数定义的前面加上static,看起来可能是这样的:

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

该函数很可能是编译单元的本地函数,因此这将起作用。如果不是,则必须在整个库项目中重命名它。

【讨论】:

感谢 Nikolai,但不幸的是我没有可以访问源代码。我会在问题中说明这一点 @abbood 这两个项目不是开源的吗? @***foe no.. 我们只有两者的静态库 @abbood 您唯一的希望是联系库的创建者,并请他们修复他们的产品。发出没有名称前缀的全局符号通常是错误的。在这种情况下,这可能是一个疏忽。 Dmitry Fantastik's answer 确实做到了

以上是关于Rdio 和 Google Core 库之间的静态库函数名称冲突的主要内容,如果未能解决你的问题,请参考以下文章

Google静态地图api与密钥和无密钥之间的区别?

如何使用 Core-Plot 等静态库创建单捆绑应用程序/存档?

清单合并失败:最小 sdkversion 11 不能小于库 [com.google.firebase:firebase-core:11.0.4] 中声明的版本 14

在静态库和动态库/插件之间进行选择?

使用静态库进行单元测试

带有 .Net Core 3.1 MVC 应用程序的 Google App Engine - 控制器之间的会话数据丢失