linking problems with several static libraries

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