tags:

views:

1102

answers:

4

In C++, static library A is linked into dynamic libraries B and C. If a class, Foo, is used in A which is defined in B, will C link if it doesn't use Foo?

I thought the answer was yes, but I am now running into a problem with xlc_r7 where library C says Foo is an undefined symbol, which it is as far as C is concerned. My problem with that is Library C isn't using the class referencing it. This links in Win32 (VC6) and OpenVMS.

Is this a linker discrepancy or a PBCAK?

New info:

  1. B depends on C, but not visa-versa.

  2. I'm not using /OPT:REF to link on Windows and it links without issue.

A: 

Sounds like it's probably the linker (ld/unix), as (most versions that I've used of) ld links the libraries in from left to right - and if there is a reference in the first one that is required by a later one the usual trick is to append the first library (or any required library) to the end of the command.

It's a try it and see....

Richard Harrison
xlc's linker is trickier, though... A left-to-right link line will mostly work, but effectively, everything is loaded into memory and then a graph walk is done to satisfy the link. It's more expensive than an old style link, but the link line doesn't have to be ordered. It also breaks in fun ways
Mike G.
I don't think this is the problem because 1. I tried different order and 2. Foo is not used by any of the other libraries.
Jake
A: 

Is your link line for C including the export lib for B? If so then as Richard suggest it sounds like an ordering thing.

Another suggestion is to see if there is a linker option to ignore unreferenced symbols, if C doesn't need that functionality from A. For the Microsoft linker this achieved with the /OPT:REF switch.

Rob Walker
+4  A: 

When you statically link, two modules become one. So when you compile C and link A into it, its as if you had copied all the source code of A into the source code of C, then compiled the combined source. So C.dll includes A, which has a dependency on B via Foo. You'll need to link C to B's link library in order to satisfy that dependency.

Note that according to your info, this will create a circular dependency between B and C.

Bruce
I will probably accept this answer on Monday when I am working on it again. I suppose other linkers only pull in the symbols it needs and ignores any undefined ones while xlc's wants every symbol defined.
Jake
A: 

The only reason why C wouldn't link is that the compiler thinks it does need the Foo symbol.

Since C doesn't refer to Foo symbols, there has to be another reason why the linker needs the symbol.

The only other reason I know of, is an export of some kind. I know only of Visual C++, so I suggest you search for some equivalent of __declspec( dllexport ) in the preprocessed files, and see what generates it.

Here's what I'd do: have the preprocessor output stored in a separate file and search it for occurences of Foo. Either it will occur as an export, or it has been referenced some way by the compiler.

xtofl
I already grep'd the crap out of it looking for anything I missed. Foo is only used by one class in A in a file that C doesn't include. None of the classes involved are being exported. The linker is complaining about specific methods in Foo, e.g. Foo::DoThis() Foo::DoThat().
Jake