Without libtool, the programmer would invoke the
ar command to
create a static library:
burger$ ar cru libhello.a hello.o foo.o burger$
But of course, that would be too simple, so many systems require that
you run the
ranlib command on the resulting library (to give it
better karma, or something):
burger$ ranlib libhello.a burger$
It seems more natural to use the C compiler for this task, given
libtool’s “libraries are programs” approach. So, on platforms without
shared libraries, libtool simply acts as a wrapper for the system
ar (and possibly
Again, the libtool control file name (.la suffix) differs from the standard library name (.a suffix). The arguments to libtool are the same ones you would use to produce an executable named libhello.la with your compiler (see Link mode):
a23$ libtool --mode=link gcc -g -O -o libhello.la foo.o hello.o *** Warning: Linking the shared library libhello.la against the *** non-libtool objects foo.o hello.o is not portable! ar cru .libs/libhello.a ranlib .libs/libhello.a creating libhello.la (cd .libs && rm -f libhello.la && ln -s ../libhello.la libhello.la) a23$
Aha! Libtool caught a common error… trying to build a library from standard objects instead of special .lo object files. This doesn’t matter so much for static libraries, but on shared library systems, it is of great importance. (Note that you may replace libhello.la with libhello.a in which case libtool won’t issue the warning any more. But although this method works, this is not intended to be used because it makes you lose the benefits of using Libtool.)
So, let’s try again, this time with the library object files. Remember
also that we need to add -lm to the link command line because
foo.c uses the
cos math library function (see Using libtool).
Another complication in building shared libraries is that we need to specify the path to the directory wher they will (eventually) be installed (in this case, /usr/local/lib)1:
a23$ libtool --mode=link gcc -g -O -o libhello.la foo.lo hello.lo \ -rpath /usr/local/lib -lm ar cru .libs/libhello.a foo.o hello.o ranlib .libs/libhello.a creating libhello.la (cd .libs && rm -f libhello.la && ln -s ../libhello.la libhello.la) a23$
Now, let’s try the same trick on the shared library platform:
burger$ libtool --mode=link gcc -g -O -o libhello.la foo.lo hello.lo \ -rpath /usr/local/lib -lm rm -fr .libs/libhello.a .libs/libhello.la ld -Bshareable -o .libs/libhello.so.0.0 .libs/foo.o .libs/hello.o -lm ar cru .libs/libhello.a foo.o hello.o ranlib .libs/libhello.a creating libhello.la (cd .libs && rm -f libhello.la && ln -s ../libhello.la libhello.la) burger$
Now that’s significantly cooler… Libtool just ran an obscure
ld command to create a shared library, as well as the static
Note how libtool creates extra files in the .libs subdirectory, rather than the current directory. This feature is to make it easier to clean up the build directory, and to help ensure that other programs fail horribly if you accidentally forget to use libtool when you should.
Again, you may want to have a look at the .la file to see what Libtool stores in it. In particular, you will see that Libtool uses this file to remember the destination directory for the library (the argument to -rpath) as well as the dependency on the math library (‘-lm’).
If you don’t
rpath, then libtool builds a libtool convenience
archive, not a shared library (see Static libraries).