How to handle duplicate symbol error from 3rd party libraries?
Asked Answered
W

3

15

I have two 3rd party libraries that seem to use the same class. That should be fine but I'm getting this type of error when building:

ld: duplicate symbol .objc_class_name_CJSONScanner in /Users/myappOne/TapjoyConnect/Frameworks/libTapjoyConnectSimulatorRewardInstall_Ads_Pinch.a(CJSONScanner.o) and /Developer/Projects/BuildOutput/Debug-iphonesimulator/OtherLibrary_d.a(CJSONScanner.o)

How can I handle this issue...

-- EDIT --

...if the source files are not available?

Weepy answered 26/5, 2010 at 5:13 Comment(0)
H
32

I'm going to assume that these are two third party libraries that have only provided you with the .a files and not the source code. You can use libtool, lipo and ar on the terminal to extract and recombine the files.

To see what architectures are in the file:

$ lipo -info libTapjoy.a
Architectures in the fat file: libTapjoy.a are: armv6 i386

Then to extract just armv6, for example:

$ lipo -extract_family armv6 -output libTapjoy-armv6.a libTapjoy.a
$ mkdir armv6
$ cd armv6
$ ar -x ../libTapjoy-armv6.a

You can then extract the same architecture from the other library into the same directory and then recombine them like so:

$ libtool -static -o ../lib-armv6.a *.o

And then finally, after you've done this with each architecture, you can combine them again with lipo:

$ cd ..
$ lipo -create -output lib.a lib-armv6.a lib-i386.a

This should get rid of any duplicate symbols, but will also combine the two libraries into one. If you want to keep them separate, or just delete the duplicate from one library, you can modify the process accordingly.

Hydrotaxis answered 26/5, 2010 at 5:56 Comment(7)
So, does this mean my project should only reference lib.a and not the other two library files?Weepy
If you were to do exactly as I did it, then yes, you would remove the other two files and use the new one.Hydrotaxis
I just found on a lib I was working on that I had to call lipo -remove armv7 before calling lipo -extract_family armv6.Zerla
Thank you very much. This fixed my problems with duplicate symbols.Poltroonery
@CoryKilger, what effective does this have on the implementations of duplicate symbols? If the two different frameworks have different implementations for each duplicate symbol, what happens? Is there a way to resolve the duplications in this case?Worthington
It would only keep the implementation from one of the libraries (using my example, the latter one being extracted). If the implementations were different, like two completely unrelated classes with the same name, you'd have a serious problem and you should probably work on having the library developers change the symbol names. If they are using good naming practices, this should rarely happen. Hopefully this only happens if both are using a common open source library like TouchJSON. Even then I'd recommend they not link it into the library and just inform you of the dependency.Hydrotaxis
I had to use lipo -thin <arch> instead of lipo -extract_family <arch>. Otherwise I got a fat library again for armv7 and armv7s.Teddy
S
1

Cory Kilger's answer is the right way to go ... just a minor tweak since I don't have the reputation to comment.

On my Mac OS 10.8 system, this lipo command is the one I used to make the .a files for use with ar:

lipo -thin armv6 -output libTapjoy-armv6.a libTabjoy.a

The man page for lipo says -extract and -extract_family both produce universal .a files and my ar command won't extract anything from them.

Salicaceous answered 20/4, 2013 at 1:26 Comment(0)
V
0

If you have the sources to both static libraries, build one of them without the CJSONScanner class. If you don't you can use "ar" from the command line to extract the CJSONScanner.o from one of the libraries.

There's probably some magic flag you can pass to "ld" to fix this, but I don't know it off hand.

Vikki answered 26/5, 2010 at 5:24 Comment(4)
Simply, ar is the name of a command-line tool. If you type man ar, you'll see detailed information, including a description of functionality: "create and maintain library archives". The -x option is for extract, but it seems you'd want -d to delete instead.Edris
Most likely these are fat files and ar alone will not be sufficient. He'll also need lipo and libtool to do this.Hydrotaxis
Thanks. What do you mean by a fat file?Weepy
A fat file contains multiple architectures. That way you can have a single file and have it run both on the simulator and the device.Hydrotaxis

© 2022 - 2024 — McMap. All rights reserved.