Boost logo

Boost-Build :

From: Caleb Epstein (caleb.epstein_at_[hidden])
Date: 2006-06-16 13:00:12


On 6/16/06, Tomas Puverle <Tomas.Puverle_at_[hidden]> wrote:

> I am not sure whether it is a good idea to force people to link
> everything dynamically. In our case, all of our apps are built with
> static libraries, and for good reasons.

I'm not recommending this, but Sun makes it impossible to link a 100% static
binary on Solaris 10. You can (with care) link with static versions of your
own and third-party libraries, but there are simply no static versions of
the system libraries provided.

When linking with gcc, the naive approach of just using -static fails:

% gcc -static -o hello hello.o
/openpkg/bin/ld: cannot find -lc
collect2: ld returned 1 exit status

Sun's linker, I believe, supports using both -Bstatic and -Bdynamic on the
same link line, so you can choose to link some libraries staticly and others
dynamically, but with GNU ld it seems like these flags are all-or-none:

% ls
Makefile greet.c hello.c hello.cpp

% make
gcc -c -o greet.o greet.c
gcc -shared -o libgreet.so greet.o
ar rv libgreet.a greet.o
ar: creating libgreet.a
a - greet.o
gcc -c -o hello.o hello.c
gcc -L. -o hello hello.o -lgreet
gcc -L. -o hello-static -Bstatic hello.o -lgreet -Bdynamic

% ldd hello-static
        libgreet.so => ./libgreet.so
        libc.so.1 => /lib/libc.so.1
        libm.so.2 => /lib/libm.so.2

So even though I've tried to request static linking for -lgreet, I've gotten
the shared version. I believe this is because the -Bdynamic at the end of
the command line overrides the earlier -Bstatic so the entire link is
performed using dynamic libraries.

Thankfully, GNU ld offers a "grouping" feature which seems to offer a
solution to the problem:

% gcc -o hello-static hello.o -Wl,--start-group -Wl,-static -L. -lgreet
-Wl,--end-group -Wl,-dy
% ldd hello-static
        libc.so.1 => /lib/libc.so.1
        libm.so.2 => /lib/libm.so.2

Note that I've had to tell the linker, after the -static group, to revert to
dynamic linking or else I end up with the dreaded "/openpkg/bin/ld: cannot
find -lc"

The command lines I'm seeing from BBv2 when static linking is requested look
like (paraphrased):

g++ -o program -Wl,--start-group object-files
/full/path/to/libboost_filesystem-gcc41-sgd-1_34.a \
    -Wl,--end-group -static -Wl,--strip-all

So this is almost right. I think that the -static needs to move inside the
"group" and after the group must come, paradoxically, -Wl,-dy. Then any
libraries mentioned inside the --start-group/--end-group pair would be
linked staticly and the system libraries which are pulled in implicitly
would be dynamically linked. Note that the Boost libraries themselves are
being linked using fully qualified paths to the archive library; this is a
can't-miss approach to ensuring that exact file is the one that is used.

For my testing, I have a simple brute-force workaround in place that
eliminates the use of -static altogether. This addresses these regression
testing issues for me, but I think this issue might bear some further
discussion.

-- 
Caleb Epstein


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