Search code examples
iosobjective-ccocoapodsgoogle-signinrdio

static library function name conflict between Rdio and Google Core library


Problem

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)

What I tried/researched

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?


Solution

  • 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:

    1. Open Terminal and locate your library
    2. path/to/rdio/rdio-ios-3.1.0/Rdio.framework/Rdio
    3. List architectures for what build the fat library
    4. lipo -info Rdio
    5. Extract the first architecture (armv7)
    6. lipo Rdio -thin armv7 -output Rdio_armv7
    7. Extract conflicting object file (RDPlayer.o)
    8. ar x Rdio_armv7 RDPlayer.o
    9. List symbols from object file to ensure conflicting function there
    10. nm -gU RDPlayer.o
    11. Change visibility of function from global to local
    12. objconv -nl:_CreateDispatchTimer RDPlayer.o RDPlayer_new.o
    13. Delete old RDPlayer.o and rename RDPLayer_new.o to RDPlayer.o
    14. rm RDPLayer.o && mv RDPLayer_new.o RDPlayer.o
    15. Ensure the function is no longer visible on object file
    16. nm -gU RDPlayer.o
    17. Replace new object file with old one in archived library and rebuild symbol table
    18. ar r -s Rdio_armv7 RDPlayer.o
    19. Repeat steps 5-18 for other architectures
    20. Combine all architectures back into fat library
    21. lipo Rdio_arm64 Rdio_armv7 Rdio_armv7s Rdio_i386 Rdio_x86_64 -create -output Rdio
    22. ...
    23. PROFIT