This is happening with two static libraries where I don't have access to the source code.
I'm trying to install the Rdio SDK into my project (using these instructions). My project already uses a lot of Google's services, and there seems to be a C function naming conflict between Rdio and Google:
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'
and in the Podfile.lock I have:
- 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)
I've done some research and tried to see if i could somehow change/remove/hide that method name in either of those two libraries.. but then I can across 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.
So I'm kind of stuck.. any ideas?
If you have access to a source code you could modify the name of the conflicted variable or visibility scope (e.g. make it static).
If you don't have access to a source code of using libraries you could contact the contributors to ask to change the name / add the prefix / change the visibility of function/variable.
If you aren't satisfied with that option you could modify the symbol table on the one of libraries to avoid the conflict. You could modify the symbol table by changing the visibility of conflicting function or renaming the function.
Because you're using OS X you need to have objconv by Agner Fog (analog of objcopy) on your local machine (see documentation).
The following are steps for modifying symbol table for a library:
path/to/rdio/rdio-ios-3.1.0/Rdio.framework/Rdio
lipo -info Rdio
lipo Rdio -thin armv7 -output Rdio_armv7
ar x Rdio_armv7 RDPlayer.o
nm -gU RDPlayer.o
objconv -nl:_CreateDispatchTimer RDPlayer.o RDPlayer_new.o
rm RDPLayer.o && mv RDPLayer_new.o RDPlayer.o
nm -gU RDPlayer.o
ar r -s Rdio_armv7 RDPlayer.o
lipo Rdio_arm64 Rdio_armv7 Rdio_armv7s Rdio_i386 Rdio_x86_64 -create -output Rdio
The problematic symbol is a plain C function, not a method (Objective-C methods don't clash on the linker level).
If you have access to the source code you can put a static
if front of the function definition, which looks probably like this:
static dispatch_source_t CreateDispatchTimer(double interval, dispatch_queue_t queue, dispatch_block_t block)
The function is very likely local to the compilation unit, so this will work. If it's not, you have to rename it in the whole library project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With