Rdio 和 Google 核心库之间的静态库函数名称冲突
static library function name conflict between Rdio and Google Core library
问题
这发生在我无法访问源代码的两个静态库中。
我正在尝试将 Rdio SDK 安装到我的项目中(使用 these instructions)。我的项目已经使用了很多Google的服务,Rdio和Google之间似乎存在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)
什么我tried/researched
我做了一些研究,并试图看看我是否能以某种方式 change/remove/hide 在这两个库中的任何一个中使用该方法名称..但是我可以跨越 this apple documentation:
There is no mechanism for hiding an Objective-C class or method defined in a dynamic library from the clients of that library.
所以我有点卡住了..有什么想法吗?
有问题的符号是一个普通的 C 函数,而不是一个方法(Objective-C 方法在链接器级别不会发生冲突)。
如果您可以访问源代码,您可以在函数定义前面放置一个 static
if,它看起来可能是这样的:
static dispatch_source_t CreateDispatchTimer(double interval, dispatch_queue_t queue, dispatch_block_t block)
该函数很可能是编译单元的本地函数,所以这会起作用。如果不是,则必须在整个库项目中重命名它。
如果您有权访问源代码,您可以修改冲突变量的名称或可见性范围(例如,将其设为静态)。
如果您无法访问使用库的源代码,您可以联系贡献者要求更改名称/添加前缀/更改 function/variable 的可见性。
如果您对该选项不满意,可以修改其中一个库中的符号 table 以避免冲突。您可以通过更改冲突函数的可见性或重命名函数来修改符号 table。
因为您使用的是 OS X,所以您需要 objconv by Agner Fog (analog of objcopy) on your local machine (see documentation).
以下是为库修改符号 table 的步骤:
- 打开终端并找到您的图书馆
path/to/rdio/rdio-ios-3.1.0/Rdio.framework/Rdio
- 列出构建 fat 库的架构
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
- 用存档库中的旧目标文件替换新目标文件并重建符号table
ar r -s Rdio_armv7 RDPlayer.o
- 对其他架构重复步骤 5-18
- 将所有架构组合回胖库
lipo Rdio_arm64 Rdio_armv7 Rdio_armv7s Rdio_i386 Rdio_x86_64 -create -output Rdio
- ...
- 利润
问题
这发生在我无法访问源代码的两个静态库中。
我正在尝试将 Rdio SDK 安装到我的项目中(使用 these instructions)。我的项目已经使用了很多Google的服务,Rdio和Google之间似乎存在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)
什么我tried/researched
我做了一些研究,并试图看看我是否能以某种方式 change/remove/hide 在这两个库中的任何一个中使用该方法名称..但是我可以跨越 this apple documentation:
There is no mechanism for hiding an Objective-C class or method defined in a dynamic library from the clients of that library.
所以我有点卡住了..有什么想法吗?
有问题的符号是一个普通的 C 函数,而不是一个方法(Objective-C 方法在链接器级别不会发生冲突)。
如果您可以访问源代码,您可以在函数定义前面放置一个 static
if,它看起来可能是这样的:
static dispatch_source_t CreateDispatchTimer(double interval, dispatch_queue_t queue, dispatch_block_t block)
该函数很可能是编译单元的本地函数,所以这会起作用。如果不是,则必须在整个库项目中重命名它。
如果您有权访问源代码,您可以修改冲突变量的名称或可见性范围(例如,将其设为静态)。
如果您无法访问使用库的源代码,您可以联系贡献者要求更改名称/添加前缀/更改 function/variable 的可见性。
如果您对该选项不满意,可以修改其中一个库中的符号 table 以避免冲突。您可以通过更改冲突函数的可见性或重命名函数来修改符号 table。
因为您使用的是 OS X,所以您需要 objconv by Agner Fog (analog of objcopy) on your local machine (see documentation).
以下是为库修改符号 table 的步骤:
- 打开终端并找到您的图书馆
path/to/rdio/rdio-ios-3.1.0/Rdio.framework/Rdio
- 列出构建 fat 库的架构
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
- 用存档库中的旧目标文件替换新目标文件并重建符号table
ar r -s Rdio_armv7 RDPlayer.o
- 对其他架构重复步骤 5-18
- 将所有架构组合回胖库
lipo Rdio_arm64 Rdio_armv7 Rdio_armv7s Rdio_i386 Rdio_x86_64 -create -output Rdio
- ...
- 利润