DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

(libtool14.info.gz) Linking executables

Info Catalog (libtool14.info.gz) Linking libraries (libtool14.info.gz) Using libtool (libtool14.info.gz) Debugging executables
 
 3.3 Linking executables
 =======================
 
 If you choose at this point to "install" the library (put it in a
 permanent location) before linking executables against it, then you
 don't need to use libtool to do the linking.  Simply use the appropriate
 `-L' and `-l' flags to specify the library's location.
 
    Some system linkers insist on encoding the full directory name of
 each shared library in the resulting executable.  Libtool has to work
 around this misfeature by special magic to ensure that only permanent
 directory names are put into installed executables.
 
    The importance of this bug must not be overlooked: it won't cause
 programs to crash in obvious ways.  It creates a security hole, and
 possibly even worse, if you are modifying the library source code after
 you have installed the package, you will change the behaviour of the
 installed programs!
 
    So, if you want to link programs against the library before you
 install it, you must use libtool to do the linking.
 
    Here's the old way of linking against an uninstalled library:
 
      burger$ gcc -g -O -o hell.old main.o libhello.a -lm
      burger$
 
    Libtool's way is almost the same(1) ( Link mode):
 
      a23$ libtool gcc -g -O -o hell main.o libhello.la -lm
      gcc -g -O -o hell main.o ./.libs/libhello.a -lm
      a23$
 
    That looks too simple to be true.  All libtool did was transform
 `libhello.la' to `./.libs/libhello.a', but remember that `a23' has no
 shared libraries.
 
    On `burger' the situation is different:
 
      burger$ libtool gcc -g -O -o hell main.o libhello.la -lm
      gcc -g -O -o .libs/hell main.o -L./.libs -R/usr/local/lib -lhello -lm
      creating hell
      burger$
 
    Now assume `libhello.la' had already been installed, and you want to
 link a new program with it.  You could figure out where it lives by
 yourself, then run:
 
      burger$ gcc -g -O -o test test.o -L/usr/local/lib -lhello
 
    However, unless `/usr/local/lib' is in the standard library search
 path, you won't be able to run `test'.  However, if you use libtool to
 link the already-installed libtool library, it will do The Right Thing
 (TM) for you:
 
      burger$ libtool gcc -g -O -o test test.o /usr/local/lib/libhello.la
      gcc -g -O -o .libs/test test.o -Wl,--rpath
      -Wl,/usr/local/lib /usr/local/lib/libhello.a -lm
      creating test
      burger$
 
    Note that libtool added the necessary run-time path flag, as well as
 `-lm', the library libhello.la depended upon.  Nice, huh?
 
    Since libtool created a wrapper script, you should use libtool to
 install it and debug it too.  However, since the program does not depend
 on any uninstalled libtool library, it is probably usable even without
 the wrapper script.  Libtool could probably be made smarter to avoid the
 creation of the wrapper script in this case, but this is left as an
 exercise for the reader.
 
    Notice that the executable, `hell', was actually created in the
 `.libs' subdirectory.  Then, a wrapper script was created in the
 current directory.
 
    On NetBSD 1.2, libtool encodes the installation directory of
 `libhello', by using the `-R/usr/local/lib' compiler flag.  Then, the
 wrapper script guarantees that the executable finds the correct shared
 library (the one in `./.libs') until it is properly installed.
 
    Let's compare the two different programs:
 
      burger$ time ./hell.old
      Welcome to GNU Hell!
      ** This is not GNU Hello.  There is no built-in mail reader. **
              0.21 real         0.02 user         0.08 sys
      burger$ time ./hell
      Welcome to GNU Hell!
      ** This is not GNU Hello.  There is no built-in mail reader. **
              0.63 real         0.09 user         0.59 sys
      burger$
 
    The wrapper script takes significantly longer to execute, but at
 least the results are correct, even though the shared library hasn't
 been installed yet.
 
    So, what about all the space savings that shared libraries are
 supposed to yield?
 
      burger$ ls -l hell.old libhello.a
      -rwxr-xr-x  1 gord  gord  15481 Nov 14 12:11 hell.old
      -rw-r--r--  1 gord  gord   4274 Nov 13 18:02 libhello.a
      burger$ ls -l .libs/hell .libs/libhello.*
      -rwxr-xr-x  1 gord  gord  11647 Nov 14 12:10 .libs/hell
      -rw-r--r--  1 gord  gord   4274 Nov 13 18:44 .libs/libhello.a
      -rwxr-xr-x  1 gord  gord  12205 Nov 13 18:44 .libs/libhello.so.0.0
      burger$
 
    Well, that sucks.  Maybe I should just scrap this project and take up
 basket weaving.
 
    Actually, it just proves an important point: shared libraries incur
 overhead because of their (relative) complexity.  In this situation, the
 price of being dynamic is eight kilobytes, and the payoff is about four
 kilobytes.  So, having a shared `libhello' won't be an advantage until
 we link it against at least a few more programs.
 
    ---------- Footnotes ----------
 
    (1) However, you should avoid using `-L' or `-l' flags to link
 against an uninstalled libtool library.  Just specify the relative path
 to the `.la' file, such as `../intl/libintl.la'.  This is a design
 decision to eliminate any ambiguity when linking against uninstalled
 shared libraries.
 
Info Catalog (libtool14.info.gz) Linking libraries (libtool14.info.gz) Using libtool (libtool14.info.gz) Debugging executables
automatically generated byinfo2html