11
votes

I've been trying to build up a set of reusable libraries for app development, but I'm starting to run into a problem.

One of my static libs is a set of general use methods (categories on Objective-C Foundation classes to improve their usability) which I tend to use in every project. (We'll call it Lib A... i.e. XCode project A produces libProjectA.a)

Then I have other static libs, things that contain specialized code for math, etc. (We'll call it Lib B.) Lib B links to Lib A because it needs to use some of that general functionality. (i.e. XCode project B links with libProjectA.a and produces libProjectB.a)

In my XCode project, I want to include and depend on Lib A because it has my general use stuff that I use all the time. I also want to include and depend on Lib B because I need that specialized math functionality. (i.e. my app Project wants to link with libProjectA.a and libProjectB.a)

However, when I try to build my XCode project I get errors for duplicate symbols, because the symbols that are defined in Lib A are also defined in Lib B.

ld: duplicate symbol _OBJC_METACLASS_$_Foo in /Users/kenny/xcode_build/Release-iphonesimulator/lib_ApplicationCore.a(Foo.o) and /Users/kenny/xcode_build/Release-iphonesimulator/lib_SpecializedMath.a(Foo.o)

How can I get around this problem? I want to develop reusable libraries to speed my app development as well as increase stability through tested/refined code. Am I approaching this from the wrong perspective? I'm developing for iOS so I can't use dylibs, they must be static.

How can I include these libraries in my project when they are interdependent upon each other and avoid the duplicate symbols?

2
It doesn't make sense for project B to link against Lib A despite how odd that sounds to you. If they were dynamic libraries then that's fine but they are static libraries i.e. archives of object files, nothing more. By "linking" against lib A you are instructing the archiver to take all the objects from lib A and add them to all the objects from project B.Troubadour

2 Answers

7
votes

Although Lib B depends on Lib A you don't actually want to put all the objects from A into B which is what you've done by the looks of it. I'm not sure how you managed that but I would imagine when you built Lib B you linked against Lib A? If so, just omit Lib A from the build line for Lib B. All the symbols from Lib A are meant to be undefined in Lib B.

Static libraries are just archives of object files so the two should be completely separate. When you need to link against Lib B just specify Lib A as well.

1
votes

This thread discussed removing the duplicates using commandline tools.

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

They extracted the .o files inside .a files and removed the duplicates then combined again.