Why does xcode not call the correct library function?
Say I have 3 C libraries, as you mentioned. Say it has the following code.
Library 1 - test1lib.a with code:
#include <stdio.h> void doStuff() { printf("\nDoing stuff for lib1\n"); } void uniqueEntryPoint1() { printf("\nUnique entry point for lib1\n"); doStuff(); }
Library 2 - test2lib.a with code:
#include <stdio.h> void doStuff() { printf("\nDoing stuff for lib2\n"); } void uniqueEntryPoint2() { printf("\nUnique entry point for lib2\n"); doStuff(); }
Library 3 - test3lib.a with code:
#include <stdio.h> void doStuff() { printf("\nDoing stuff for lib3\n"); } void uniqueEntryPoint3() { printf("\nUnique entry point for lib3\n"); doStuff(); }
Here, each library has a unique function and one common doStuff()
function
When we add these 3 libraries to xcode and link them. xcode, but does not load all object files. Let's say the objective C code looks like this:
@implementation ViewController - (void)viewDidLoad { [super viewDidLoad];
Output signal
Unique entry point for lib1 Doing stuff for lib1
In this case, xcode will only load the characters that are passed (library objects 1) in this case.
If you read about checkboxes or linker options like -all_load
, -force_load
and -objC
, you will have a better understanding.
If we add the -all_load
linker option, this will force the linker to load all library objects, so we get the following error in xcode
ld: 2 duplicate symbols for architecture arm64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
The reason for this does not work, because the linker detects that doStuff()
redefined several times.
The only way to solve this problem is to change the linker input, i.e. characters present in these 3 libraries. This is already mentioned by Josh in the comments. I will add $ 0.02 to it.
Possible solutions
Solution 1:
The best solution (self-evident) is to change the source code if you have access to the same.
Solution 2:
Use objcopy to rename or prefix a function as indicated in the answer to this How to deal with character conflicts between statically linked libraries?
Now you doubt how to find objcopy.
Option 1: You can use this project https://github.com/RodAtDISA/llvm-objcopy . This will be difficult to compile as it builds with llvm. You will need to follow the instructions at http://llvm.org/docs/GettingStarted.html and http://llvm.org/docs/CMake.html .
If you are rewriting https://github.com/RodAtDISA/llvm-objcopy/blob/master/llvm-objcopy.cpp , you can probably reuse the logic of parsing and rewriting objects, regardless of llvm.
Option 2:
Compile and reuse binutils objcopy from https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=binutils/objcopy.c;h=2636ab4bcb34cf1e1e54db9933018a805b366727;
Solution 3:
You can follow the answer provided by Richard in this link Rewrite characters in static iOS libraries . This is more of a hack, but using a hex editor you can rewrite characters if their length is kept the same. If you have more characters and a large library, you can use https://sourceforge.net/projects/bbe-/ and nm write a script.
All this is a considerable effort, but apparently there is no shortcut.