[Bf-committers] scons and static libs

Giuseppe Ghibò ghibo at mandriva.com
Fri Apr 18 14:59:21 CEST 2008

Ken Hughes ha scritto:
> I don't know if the other platform managers have this issue, but it's a 
> bit of a pain to make the releases using the minimum number of shared 
> libraries.  My solution has been to create a separate directory 
> containing the static libs I want to use and then override the default 
> scons variables  for them.  For example, I link OpenAL, OpenEXR, and PNG 
> statically.  I can't use the "out-of-the-box" static libs since gcc 
> needs to separate the shared and static libs with a "-Xlinker -Bstatic".
> I'd like to propose one of two solutions:
> (1) Specify the libs using a shared (".so") or static (".a") suffix.  
> Parse each BF_*_LIB string and tack the lib into either a shared or 
> static list, then send these to the linker separated by the appropriate 
> platform-specific flags ("-Xlinker -Bstatic" for linux, for example).  I 
> played with the output of scons and found that this worked reliably, 
> including the shared or static OpenGL libs.
> (2) The static OpenGL libs are handled by passing the explicit static 
> libs to gcc.  This can't be done as far as I can tell using something 
> like BF_FREETYPE_LIB='/usr/lib/libfreetype.a' because scons expands 
> BF_*_LIB to a string of libs with "-l" tacked on the front of each.  I 
> played around with tools/Blender.py and found it wasn't too hard to 
> check for something like "/usr" or ".a" in the BF_*_LIB strings and if 
> true tack those libs onto the static library list.
> Ken
> _____________________________

Dear Ken, I was thinking to post something similar some month ago. 
Static linking has advantages when
you have to provide cross-distro binaries, as usually it's hard to find 
the right version of shared libraries
which works everywhere (e.g. one might have OpenEXR 1.2, 1.4, or 1.6)...

IMHO the best approach is to use the solution #1. Solution #2 depends 
also on paths which might
be more difficult to handle for the various architectures and distros 
(e.g. you might have libs in  /usr/lib, /usr/lib64, /usr/X11R6/lib,
/usr/X11R6/lib64, etc.).

I think that that for each library there could be four cases:

1) library is coming from the system shared (so system-wide).

2) library is coming from internal blender tarball  (these are generally 
tagged with "#extern")

3) library is coming from the system (so system-wide), but need to be 
linked statically.

4) library is coming from internal blender tarball, but it's linked 
statically (I don't think we have ones).

In the case of 3), which is the one of your point #1, the compilation 
flags that can be used are:

-Xlinker -Bstatic -llibrary -Xlinker -Bdynamic

or better

-Wl,-static -llibrary -Wl,-dy

i.e. -Xlinker -Bdynamic or -Wl,-dy should be provided to switch back to 
shared linking, otherwise the
libraries which follows are tried to be linked statically too. In other 
words, given libA, libB and libC
which are shared linked with:
   gcc ... -lA -lB -lC

and you want to link libA and libC statically but libB dynamically you 
have to use:

   gcc ... -Wl,-static -lA -Wl,-dy -lB -Wl,-static -lC -Wl,-dy

Note also that it's not said that linking a single libraries statically 
providing just its name could be enough. This because of dependencies
Generally this doesn't happens with shared (because they have are 
further crosslinked with other shared libs),
but sometimes a static libraries needs also to be linked with some extra 
static library to resolve  all the symbols.
E.g. in the case of above, libA, might depends also on libD, so you'll have:

   gcc ... -Wl,-static -lD -lA -Wl,-dy -lB -Wl,-static -lC -Wl,-dy

Another alternative is to use the tool "pkg-config", to get the strings 
for correct linkage, e.g. as in:

 pkg-config --libs --static gtk+


More information about the Bf-committers mailing list