[CMake] Linking problem

Alan W. Irwin irwin at beluga.phys.uvic.ca
Wed Nov 7 17:45:08 EST 2007


On 2007-11-07 11:55-0500 Brandon Van Every wrote:

> On Nov 7, 2007 11:08 AM, KSpam <keesling_spam at cox.net> wrote:
>>
>> Static linking is a strange beast.  When you link in a static library, it will
>> only resolve symbols that are currently being used.  All other symbols from
>> the static library are pruned out.  The nice thing is that this reduces the
>> binary object size.  On the other hand, symbols that may be needed further
>> down the chain are not resolved, as you have found out.
>
> I don't see why people think this is "strange."  Granted, the word
> "static" is overloaded in C parlance, but generally it means the scope
> of the data is hidden.  If you put static stuff into a dynamic
> library, the only intent is to make all the dynamic functions work and
> export properly.  It's not to reveal all your underlying static gunk +
> the dynamic functions.

I agree "static" has overloaded meanings depending on context, but I don't 
agree with your interpreation of the meaning of "static" in the case of Unix
libraries.  (I have no clue about the windows linking case so my remarks
below may only apply to the Unix case.)

Let's take the simple case of one main programme linked to one library. If
the library is static, then linking simply creates an executable consisting
of the main routine and copies of the subset of routines that it directly or
indirectly uses from the library.  The result is a large, completely
independent executable. The shared library case is quite different.  The
linking produces a small incomplete executable consisting of just the main
routine plus some minimal extra information to allow the run-time loader to
do its job.  That executable is essentially completed at run time by the
run-time loader which uses routines from the shared library as required to
resolve the symbols in the main routine. Thus, the shared library code that
is actually used at run time depends on what exists at run time in the
library and not what existed in say a previous version of the library at
link time.  The practical advantage of the static libraries case is
simplicity.  The practical advantage of the shared libraries case is it is a
more flexible linking system which allows fixing bugs in libraries without
having to recompile or relink executables.  For CMake (and all other build
systems I am aware of), the user has a choice of making static libraries or
shared libraries from exactly the same library source code.  There is no
intention to hide the scope of the symbols or anything like that since it is
exactly the same library source code in both cases.

For more complicated cases of say when you are linking a shared library with
a static library, just like the simpler case above the static library code
subset that the shared library uses becomes part of the shared library
(which is why the -fPIC compile option must be used for the static library
code for this case).

For real world cases where you have a large collection of interdependent
libraries being built for some software project that also depend on external
libraries, there are some KISS rules I follow that greatly simplify linking
issues.

(1) No circular dependencies allowed.

(2) For every library that is linked, all symbols in that
library must be resolved by explicitly mentioning all libraries at link time
that supply the required symbol definitions. I enforce that rule in the
Linux case by periodically testing every library that I create with CMake
using the "ldd -r" command.

(3) Note, the above two rules are all you really need for the shared
libraries case (which is my principal development focus).  However, if you
have external libraries that are static or if you choose static libraries
for the libraries you are building internally with CMake, then a third rule
is the static libraries a given executable or library depends upon must be
listed in the correct order when linking.  If, for example, you are linking
an executable which depends on static libraries libb and libc, and libb in
turn depends on libc (i.e., has symbols that are resolved by code in libc),
then you must mention the libraries in the order libb and libc for the link
step and not in the order libc, libb.

These KISS linking rules are not all demanded by the Linux linking
environment but I follow them anyway because all cross-platform linking
issues just simply disappear, and life is good.  Thus, I recommend them to
others.

Alan
__________________________
Alan W. Irwin

Astronomical research affiliation with Department of Physics and Astronomy,
University of Victoria (astrowww.phys.uvic.ca).

Programming affiliations with the FreeEOS equation-of-state implementation
for stellar interiors (freeeos.sf.net); PLplot scientific plotting software
package (plplot.org); the libLASi project (unifont.org/lasi); the Loads of
Linux Links project (loll.sf.net); and the Linux Brochure Project
(lbproject.sf.net).
__________________________

Linux-powered Science
__________________________


More information about the CMake mailing list