Duplicate symbol: Include static lib A in static lib B, also include lib A and B in XCode Project
Asked Answered
L

2

11

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?

Lazurite answered 9/3, 2011 at 22:35 Comment(1)
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.Problem
P
7

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.

Problem answered 9/3, 2011 at 22:40 Comment(6)
What do you mean by "put all the objects from A into B?" I'm not copying code at all. My XCode project that builds lib B links it with lib A. Then my XCode project for my app links with Lib A and Lib B. I updated my question to clarify how the inter-projects are linked.Lazurite
By linking lib B with lib A you effectively take all the objects that are archived in lib A and put them into lib B. What you end up with is then really "lib A and B". Don't link against lib A when building the lib B archive.Problem
Oh! facepalm I thought my app project had to directly link to lib A as well, but I guess I just need the app project to know where the Header files are. Thanks! That worked beautifully.Lazurite
@Kenny Wyland: Not quite! Your final app does need to link to both A and B. It's B that doesn't "link" to A. lib A is just an archive of the object files from project A. Similarly lib B ought to be just an archive of files from project B. Static libraries don't have in-built dependencies in the same way as dynamic libraries and so you don't (shouldn't) attempt to specify those dependencies when creating the archive. Yes, there will be symbols from A that are undefined in B but they get resolved when you specify both A and B as dependencies in the final target i.e. your application.Problem
Oh, ok. I thought for libProjectB.a to be able to build it would need to be linked against libProjectA.a. It's been far too many years since I dealt with building and linking C code and I never truly grok'd it back then either. :) Ok, so lib B just needs to know where the header files for lib A are, but doesn't need the libProjectA.a to be linked. Then the final project where these things are put into use will do all of the needed linking. Is that right?Lazurite
@Kenny Wyland: That's it exactly. Spot on. Sorry for the delay in replying, I went to bed after my last comment!Problem
C
1

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.

Curlew answered 7/2, 2013 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.