Static library name conflict between Rdio and Google Core

Problem

This happens with two static libraries where I do not have access to the source code.

I am trying to install the Rdio SDK in my project (using these instructions ). My project already uses many Google services, and there seems to be a conflict between the names and functions of Rdio and Google as follows:

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 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 did some research and tried to find out if I can somehow change / delete / hide this method name in any of these two libraries .. but then I can through this apple documentation:

There is no mechanism to hide a class or Objective-C method defined in a dynamic library from clients of this library.

So, I'm stuck .. any ideas?

+5
source share
2 answers

If you have access to the source code, you can change the name of the conflicting variable or scope (for example, make it static).

If you do not have access to the source code for using libraries, you can contact the participants to request a name change / add a prefix / change the visibility of the function / variable.

If you are not satisfied with this option, you can change the symbol table in one of the libraries to avoid conflict. You can change the symbol table by changing the visibility of a conflicting function or renaming a function.

Since you are using OS X, you need objconv to use Agner Fog (an analogue of objcopy) on your local machine ( see the documentation ).

The following are the steps to change the symbol table for the library:

  • Open a terminal and find your library
  • path/to/rdio/rdio-ios-3.1.0/Rdio.framework/Rdio
  • List of architectures for which a bold library is created.
  • lipo -info Rdio
  • Extract the first architecture (armv7)
  • lipo Rdio -thin armv7 -output Rdio_armv7
  • Extract conflicting object file (RDPlayer.o)
  • ar x Rdio_armv7 RDPlayer.o
  • Map characters from the object file to provide a conflicting function there.
  • nm -gU RDPlayer.o
  • Change the visibility of a function from global to local
  • objconv -nl:_CreateDispatchTimer RDPlayer.o RDPlayer_new.o
  • Delete the old RDPlayer.o and rename RDPLayer_new.o to RDPlayer.o
  • rm RDPLayer.o && mv RDPLayer_new.o RDPlayer.o
  • Make sure the function no longer appears in the object file
  • nm -gU RDPlayer.o
  • Replace the new object file with the old one in the archive library and rebuild the symbol table
  • ar r -s Rdio_armv7 RDPlayer.o
  • Repeat steps 5-18 for other architectures.
  • Combine all architectures back into the fat library.
  • lipo Rdio_arm64 Rdio_armv7 Rdio_armv7s Rdio_i386 Rdio_x86_64 -create -output Rdio
  • ...
  • PROFIT
+10
source

The problem character is a simple C function, not a method (Objective-C methods do not collide at the linker level).

If you have access to the source code, you can put the static option if before defining a function that looks something like this:

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

The function is most likely local to the compilation unit, so this will work. If this is not the case, you need to rename it to the entire library project.

+2
source

Source: https://habr.com/ru/post/1234096/


All Articles