Boost logo

Boost-Build :

Subject: [Boost-build] library_order failures
From: Vladimir Prus (vladimir.prus_at_[hidden])
Date: 2016-02-04 03:00:13


I've looked into failures of the library_order test, and arrived at this failing command
line:

     $ g++ -o main main.o -Wl,--start-group libd.so liba.so libb.so libc.a -Wl,--end-group
     libc.a(c.o): In function `c()':
     /tmp/tmpSiuzvi/c.cpp:2: undefined reference to `d()'

In this example, each of the libraries has a single function whose name matches library name,
and there's a call chain of main->a->b->c->d.

I can make this work like so:

     $ g++ -o main main.o -Wl,--no-as-needed -Wl,--start-group libd.so liba.so libb.so libc.a -Wl,--end-group

What happens, apparently is that:

- ld now has --as-needed option as default, which makes the final executable not refer to shared
   libraries that are included on the command line, but not needed.
- Whether the library is needed is determined by checking whether it provides any symbols that
   are unresolved at this point in the command line, similarly to how static linking works
- While start-group/end-group fixes order dependency for static libraries, it does not appear to
   do so for shared libraries.

So, for the original command line, the linker sees libd.so, notes that it does not export any
previously unresolved symbol, and skips that library completely. By the time it arrives at
libc.a and sees unresolved reference to 'd', libd.so is already thrown away.

I can solve this in two ways:

- Just stick "-Wl,--no-as-needed" at the start of the command line
- Re-enable automatic sorting of libraries on the command line. That's how Boost.Build
   worked before, until I decided that --start-group/--end-group is fast enough and
   we don't need to bother.

Comments?

-- 
Vladimir Prus
http://vladimirprus.com

Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk