views:

102

answers:

1

I'm porting an existing system from Windows to Linux. The build is structured with multiple static libraries. I ran into a linking error where a symbol (defined in libA) could not be found in an object from libB. The linker line looked like

g++ test_obj.o -lA -lB -o test

The problem of course being that by the time the linker finds it needs the symbol from libA, it has already passed it by, and does not rescan, so it simply errors out even though the symbol is there for the taking.

My initial idea was of course to simply swap the link (to -lB -lA) so that libA is scanned afterwards, and any symbols missing from libB that are in libA are picked up. But then I find there is actually a recursive dependency between libA and libB! I'm assuming the Visual C++ linker handles this in some way (does it rescan by default?).

Ways of dealing with this I've considered:

  • Use shared objects. Unfortunately this is undesirable from the perspective of requiring PIC compliation (this is performance sensitive code and losing %ebx to hold the GOT would really hurt), and shared objects aren't needed.

  • Build one mega ar of all of the objects, avoiding the problem.

  • Restructure the code to avoid the recursive dependency (which is obviously the Right Thing to do, but I'm trying to do this port with minimal changes).

Do you have other ideas to deal with this? Is there some way I can convince the binutils linker to perform rescans of libraries it has already looked at when it is missing a symbol?

+3  A: 

Just do this:

g++ test_obj.o -lA -lB -LA -o test

When the linker reads the first libA on the command line, it'll discard the object/symbols in it that noone has depended on yet, e.g. all the symbols libB needs but not test_obj.o. So you just make it read libA again, and it'll pick up the those symbols as well.

nos
This question and that answer is such a great example of an elegant solution staring you in the face... It reads almost like the punchline of a joke... :)
dicroce