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?

Rui Peres
  • 25,741
  • 9
  • 87
  • 137
user230949
  • 1,109
  • 2
  • 16
  • 22

3 Answers3

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.

Cory Kilger
  • 13,034
  • 3
  • 33
  • 24
  • So, does this mean my project should only reference lib.a and not the other two library files? – user230949 May 26 '10 at 06:12
  • If you were to do exactly as I did it, then yes, you would remove the other two files and use the new one. – Cory Kilger May 26 '10 at 17:33
  • I just found on a lib I was working on that I had to call `lipo -remove armv7` before calling `lipo -extract_family armv6`. – Liron Jun 14 '12 at 13:20
  • Thank you very much. This fixed my problems with duplicate symbols. – user1515304 Oct 26 '12 at 16:00
  • @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? – Charlie J Jul 25 '13 at 03:40
  • 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. – Cory Kilger Aug 05 '13 at 19:51
  • I had to use `lipo -thin ` instead of `lipo -extract_family `. Otherwise I got a fat library again for `armv7` and `armv7s`. – wroluk Aug 17 '16 at 13:52
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.

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.

Mark Bessey
  • 19,598
  • 4
  • 47
  • 69
  • 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. – Quinn Taylor May 26 '10 at 05:58
  • Most likely these are fat files and `ar` alone will not be sufficient. He'll also need `lipo` and `libtool` to do this. – Cory Kilger May 26 '10 at 06:08
  • Thanks. What do you mean by a fat file? – user230949 May 26 '10 at 06:24
  • 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. – Cory Kilger May 26 '10 at 17:22