Static Libraries: Compiling and Dependencies

Member
Posts: 46
Joined: 2008.10
Post: #1
Hello! I am attempting to consolidate the current version of my game engine into a set of static libraries. I'm running into a problem with the dependencies between each library when I try to link everything together with the main program code. Here's a simplified version of the problem:

[Image: mlDiagram.jpg]

In other words: There are two libraries, one of which uses objects from the other. (When compiling lib2, headers from lib1 are included but not the source code.) I am attempting to link against both of these libraries in the main program code (with both headers included, of course). The exact error produced by xCode is:

Code:
duplicate symbol myClass::myClass() in ../build/Debug/lib1.a (lib1.o) and ../build/Debug/lib2.a (lib2.o)

... where myClass is an object defined in library lib1.

The problem seems pretty obvious - it doesn't like having header definitions for a class in both libraries - but not the solution (to me, at least). And yes, before you ask, the proper precautions with #ifndef... are being made. Apparently, the scope of precompiler symbols doesn't last into a static library's object files.

At root of the problems, of course, is a lack of understanding regarding the nuts-and-bolts of compiling static libraries. Can anyone recommend a good resource where the gaps in my knowledge could be filled?

"Who's John Galt?"
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #2
If lib2 links against lib1, and seemingly the symbols are exported, you don't need to link against lib1 from your main app.

It should not be possible to build lib2 without also linking to lib1, if both are static libraries, so something different to what you think must be going on.
Quote this message in a reply
Member
Posts: 46
Joined: 2008.10
Post: #3
I'm not sure I understand your response. Let me try and explain it to myself.

DoG Wrote:If lib2 links against lib1,

I'm confused. I don't know enough about static libraries to fix my problem, but I'm fairly certain that neither static library is linking against anything. They're compiled, archived, and left alone - until a program is written that uses them. At least, this is my understanding (and reflected in xCode's build report).

DoG Wrote:and seemingly the symbols are exported

Let's focus on this little bit for a second, since this is where my deep end starts. The symbols for each library, after they are compiled, come from... their definitions (.cpp source)? Their declarations (.h headers)? Some weird object-code combination of both? This seems to be the main point I need to learn, since knowing where the symbols are defined will let me avoid duplicating them.

A good friend of mine recommended using extern to define lib1 references used in lib2, instead of compiling lib2 with lib1's headers. This seems like it might work, but I'd rather not have to update the extern definitions in lib2 every time lib1 changes. Wouldn't this kind of ruin the point of maintaining separate libraries?

DoG Wrote:you don't need to link against lib1 from your main app.

Tried this, but got the same error - only the conflict takes place between the two object files (lib1.o and lib2.o) within the same library (lib2.a), instead. Again, though, it doesn't occur until linking. Same problem, different location.

DoG Wrote:It should not be possible to build lib2 without also linking to lib1, if both are static libraries, so something different to what you think must be going on.

This sort of goes back to my original point. By my understanding, building the static library lib2 involves a) compiling lib2 source code, and b) archiving the resulting lib2 object file. No linking is involved until the libraries are used by the main program.

It seems that an education in static library symbol-handling might be profitable. Can anyone recommend a good resource where I can learn more on this topic?

"Who's John Galt?"
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #4
When you compile a static library, it must link against other static libraries it uses.

Since your conflict is apparently between two modules (lib1.o and lib2.o), it is more likely that you have method definitions in your headers which aren't inlined (either defined in the class definition, or defined outside the class definition with the "inline" keyword).
Quote this message in a reply
Luminary
Posts: 5,125
Joined: 2002.04
Post: #5
Static libraries can't be "linked" against anything. You can force one to include the contents of another if you try hard enough, but you probably shouldn't. Your diagram at top looks fine, so I'm going to side with DoG and guess you've got some functions in a header not marked static/inline/in an anonymous namespace.

A static library is just a generic archive (like tar, but an even sillier format) of the .o files that make it up.
Quote this message in a reply
DoG
Moderator
Posts: 869
Joined: 2003.01
Post: #6
My point about the "linking" might have been badly worded, I was just trying to say that a lib2 using lib1 means that lib1 is contained in lib2, as lib1 is static, so it needs to be included in the binary. Including lib1 in another binary that includes lib2 would mean it'll be included twice, effectively, but the linker doesn't really know, since it would just see the same symbols in lib1 and lib2, but it can't tell that they're redundant (as they might not be).

Note that you have to distinguish between modules, compiled object files, binaries, etc. It's all a bit complex Smile
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Xcode: loading static libraries on ppc/i386 Taxxodium 6 4,194 Mar 22, 2006 05:39 PM
Last Post: TomorrowPlusX
  Distributing Dependencies DesertPenguin 2 2,357 Feb 26, 2006 06:57 PM
Last Post: DesertPenguin