5

I currently have ShareKit in my project that is compiled as a static library. It is properly implemented. I also have implemented Amazon's AWS SDK by just adding their framework into my project.

It seems that the duplicate symbol is coming from Amazon's AWS SDK file, "AWSIOSSDK". This is what it looks like:

enter image description here

And that file is colliding with ShareKit's file, libShareKit.a. This is what that file looks like:

enter image description here

Anyway both of these files are ones that I haven't seen before. And it seems that some JSON files are colliding within them.

I have looked at other SO questions and they say to do some things with the compiled sources but none of these files are in the compiled sources from either library.

Here is the exact error Xcode gives:

ld: duplicate symbol _OBJC_CLASS_$_SBJsonParser

Anyway, does anyone have any ideas what I should do? My app does not compile unless I fix this issue.

Thanks!

SimplyKiwi
  • 12,376
  • 22
  • 105
  • 191

3 Answers3

5

You could go ahead and split a library archive into its object files and merge them again by leaving out the duplicates.

See the following walkthrough for getting an idea to manage that task: Avoiding duplicate symbol errors during linking by removing classes from static libraries

Till
  • 27,559
  • 13
  • 88
  • 122
4

Both of these have built SBJsonParser into their static libraries. This is not the correct way to build a static library. Each should build without SBJson and then you should link all of them together with SBJson. There are a couple of solutions:

  • Rebuild these libraries (or have their maintainers do so) to not include third-party libraries directly into a static library. This is the ideal solution.
  • Remove the incorrect SBJson files from the .a files using ar. You should be able to do this using ar -t to list the objects in the .a and then ar -d to delete the ones that shouldn't be in there. You could of course also ar -x to extract all the .o files and link them directly.
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • 1
    +1 for spelling it out loud: do not include other libraries in your library but tell the user to link against them. – Till Jul 22 '12 at 20:43
  • I will probably go with the second solution. The thing is, the AWSIOSSDK file is not a .a file is it? So I remove the SBJSON files from ShareKit's .a file only or the AWSIOSSDK one also? Where is each library supposed to look then for the SBJSON files? – SimplyKiwi Jul 22 '12 at 20:53
  • 1
    What do you mean AWSIOSSDK isn't a `.a` file? I've never used it, but what else could it be? You can't ship third-party shared libraries on iOS. "Each library" doesn't look anywhere when they're static libraries. A static library is just a bundle of unlinked `.o` files. It is the same as dropping the relevant `.m` files into your project. The entire program just needs to resolve every symbol; no one cares where the symbol is resolved from. – Rob Napier Jul 22 '12 at 20:58
  • Nevermind, I was just confused. Can you point me to a link that does what you explain in your second bullet or should I just follow @Till's link? – SimplyKiwi Jul 22 '12 at 21:04
  • Till's link looks like a very good tutorial. It's basically the same approach I'm discussing, though it also includes some excellent instruction on how to deal with universal libraries using lipo (which I didn't cover). – Rob Napier Jul 22 '12 at 21:22
  • Okay thank you. Lastly, since both files are .a's should I remove the conflicting files just from any one of the two .a's? I think thats what you were getting at, but I am not entirely sure. Thanks – SimplyKiwi Jul 22 '12 at 21:39
  • That would work. Typically I would remove them from both, and link SBJson myself. That way I control the version of SBJson. But you're fine as long as there's only one copy somewhere. – Rob Napier Jul 22 '12 at 22:02
  • I hate to keep asking questions, but when I follow that tutorial and enter ar in terminal it says -bash: ar: command not found – SimplyKiwi Jul 22 '12 at 22:24
  • Also that AWSiOSSDK file is a binary file, is that the same as a .a? – SimplyKiwi Jul 22 '12 at 22:32
  • Yes. In a static-library framework, the binary is a static library. You can run `file AWSiOSSDK.framework/Versions/A/AWSiOSSDK" to see this. It's called a "current ar archive random library." "ar" means static. – Rob Napier Jul 23 '12 at 13:54
  • Ok thanks I ended up figuring that out. However terminal still says the ar command is not found. I am just copying what is in that tutorial and it doesn't see that command. Is there something that I am missing? – SimplyKiwi Jul 23 '12 at 21:21
  • Instead of -all_load should I use -force_load in one of the static libraries or is that a bad solution? – SimplyKiwi Jul 23 '12 at 21:26
  • Update: I found that in ShareKit's targets, one of them is Static Library. Then there is a list of files some of which include the conflicting JSON files. So I just removed them from there and the error seems to be gone, is that the right way to go? – SimplyKiwi Jul 23 '12 at 21:38
  • Yes. ShareKit shouldn't include these. – Rob Napier Jul 23 '12 at 22:37
0

I had the same issue with FaceBookConnect Framework (let's call it project B) and my project (project A). Both were linking again JSON framework.

The solution is :

  1. Go to Project B > Target > Build Phase > Remove JSON from the "Link Binary with libraries"
  2. Make sure the JSON framework is still in the project (don't remove it) so project B can build
  3. Build your project B you shouldn't get any error. The project should build but not embed the JSON frameworks symbols
  4. Add both project B product (a framework) AND JSON framework in project A
  5. Go to Project A > Target > Build Phase and check that both project B and JSON have been added to the "Link binary with libraries" section
  6. Build your project A

Regards,

GPY
  • 3,832
  • 1
  • 16
  • 11