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