linking problems with several static libraries
Oron Peled
oron at actcom.co.il
Thu Jul 11 01:39:13 IDT 2013
On Wednesday 10 July 2013 21:31:51 Diego Iastrubni wrote:
> I have been figthing this nice problem at work, which I would like someone
> to help me. Basically, I have several static libs (liba... libk) which I
> need to link to my program.
>
> My program needs liba, which in turn needs libb.. which in turn needs libk.
> The last libk needs symbols from liba.. and this is where it gets funky.
> While linking g++ complains that symbols are missing ... and from ar+nm I
> see that those symbols are avarilable on liba.
* Omer Zak correctly replied that this circular dependency represent
bad design of the libraries authors.
* But don't despair yet... see below.
> My solution was to
>
> g++ -o blabla $(OBJS) liba.a libb.a l...libk.a liba.a
>
> I know that using -L -l does not work as well, at I do need to link liba.a
> twice.
* It has nothing to do with '-L' which just adds directories to the search path
* It's because the linker in Linux (and all Unix systems I've encountered) is
a single pass one.
* So in general the linking *order* matters -- and circular dependency suck.
* But... there are several workarounds for such brain-dead situations.
* Workaround 1:
- List libraries multiple times, like you did
- It does exactly what you want
- But if the dependency graph is more complex... you'd have to
work harder to find the correct repetitions and order :-(
* Workaround 2:
- Pass the '--whole-archive' option to 'ld'
If you link via gcc, just tell it to pass this option to the linker
via '-Wl' option:
'-Wl,--whole-archive'
- You don't need to think at all about all these cycles, but....
- The complete set of libraries gets into your executable (even
unused data and code) -- so you typically generate very big
executable (yes, doing things the dumb way has its price).
* Workaround 3:
- This is a "partial" workaround 2 solution.
- Let's say only a subset of the libraries has this cyclic
dependency problem
- Than you can use the linker '--start-group', '--end-group' options:
ld .... libx.a liby.a --start-group libbad1.a libbad2.a --end-group libz.a
Or, let the programmers deal with the results of their bad design and
reorganize the code in the libraries -- after all a library should contain
related and well defined functionality -- the cycles just shows that
somebody just threw pieces of code to different libraries.
Enjoy,
--
Oron Peled Voice: +972-4-8228492
oron at actcom.co.il http://users.actcom.co.il/~oron
UNIX is user friendly. It's just selective about who its friends are.
More information about the Linux-il
mailing list