Copyright (C) 1996-2003, 2005-2007 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.1 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
This file documents GNU Libtool, a script that allows package developers to provide generic shared library support. This edition documents version 1.5.24.
See Reporting bugs, for information on how to report problems with libtool.
Introduction
Using libtool
Invoking libtool
Integrating libtool with your package
Configuring libtool
Including libtool in your package
Library interface versions
Tips for interface design
Dlopened modules
Using libltdl
Using libtool with other languages
Troubleshooting
The libtool test suite
Maintenance notes for libtool
Porting libtool to new systems
Platform quirks
In the past, if a source code package developer wanted to take advantage of the power of shared libraries, he needed to write custom support code for each platform on which his package ran. He also had to design a configuration interface so that the package installer could choose what sort of libraries were built.
GNU Libtool simplifies the developer's job by encapsulating both the platform-specific dependencies, and the user interface, in a single script. GNU Libtool is designed so that the complete functionality of each host type is available via a generic interface, but nasty quirks are hidden from the programmer.
GNU Libtool's consistent interface is reassuring... users don't need
to read obscure documentation in order to have their favorite source
package build shared libraries. They just run your package
configure script (or equivalent), and libtool does all the dirty
work.
There are several examples throughout this document. All assume the same environment: we want to build a library, libhello, in a generic way.
libhello could be a shared library, a static library, or both... whatever is available on the host system, as long as libtool has been ported to it.
This chapter explains the original design philosophy of libtool. Feel free to skip to the next chapter, unless you are interested in history, or want to write code to extend libtool in a consistent way.
Since early 1995, several different GNU developers have recognized the importance of having shared library support for their packages. The primary motivation for such a change is to encourage modularity and reuse of code (both conceptually and physically) in GNU programs.
Such a demand means that the way libraries are built in GNU packages needs to be general, to allow for any library type the package installer might want. The problem is compounded by the absence of a standard procedure for creating shared libraries on different platforms.
The following sections outline the major issues facing shared library support in GNU, and how shared library support could be standardized with libtool.
The following specifications were used in developing and evaluating this system:
The following issues need to be addressed in any reusable shared library system, specifically libtool:
LD_LIBRARY_PATH must be set properly (if
it is supported), or programs fail to run.
LD_LIBRARY_PATH or equivalent),
or run ldconfig.
Even before libtool was developed, many free software packages built and installed their own shared libraries. At first, these packages were examined to avoid reinventing existing features.
Now it is clear that none of these packages have documented the details of shared library systems that libtool requires. So, other packages have been more or less abandoned as influences.
In all fairness, each of the implementations that were examined do the job that they were intended to do, for a number of different host systems. However, none of these solutions seem to function well as a generalized, reusable component.
Most were too complex to use (much less modify) without understanding exactly what the implementation does, and they were generally not documented.
The main difficulty is that different vendors have different views of what libraries are, and none of the packages which were examined seemed to be confident enough to settle on a single paradigm that just works.
Ideally, libtool would be a standard that would be implemented as series of extensions and modifications to existing library systems to make them work consistently. However, it is not an easy task to convince operating system developers to mend their evil ways, and people want to build shared libraries right now, even on buggy, broken, confused operating systems.
For this reason, libtool was designed as an independent shell script. It isolates the problems and inconsistencies in library building that plague Makefile writers by wrapping the compiler suite on different platforms with a consistent, powerful interface.
With luck, libtool will be useful to and used by the GNU community, and that the lessons that were learned in writing it will be taken up by designers of future library systems.
At first, libtool was designed to support an arbitrary number of library object types. After libtool was ported to more platforms, a new paradigm gradually developed for describing the relationship between libraries and programs.
In summary, “libraries are programs with multiple entry points, and more formally defined interfaces.”
Version 0.7 of libtool was a complete redesign and rewrite of libtool to reflect this new paradigm. So far, it has proved to be successful: libtool is simpler and more useful than before.
The best way to introduce the libtool paradigm is to contrast it with the paradigm of existing library systems, with examples from each. It is a new way of thinking, so it may take a little time to absorb, but when you understand it, the world becomes simpler.
It makes little sense to talk about using libtool in your own packages until you have seen how it makes your life simpler. The examples in this chapter introduce the main features of libtool by comparing the standard library building procedure to libtool's operation on two different platforms:
You can follow these examples on your own platform, using the preconfigured libtool script that was installed with libtool (see Configuring).
Source files for the following examples are taken from the demo subdirectory of the libtool distribution. Assume that we are building a library, libhello, out of the files foo.c and hello.c.
Note that the foo.c source file uses the cos math library
function, which is usually found in the standalone math library, and not
the C library (see Trigonometric Functions). So, we need to add -lm to
the end of the link line whenever we link foo.o or foo.lo
into an executable or a library (see Inter-library dependencies).
The same rule applies whenever you use functions that don't appear in the standard C library... you need to add the appropriate -lname flag to the end of the link line when you link against those objects.
After we have built that library, we want to create a program by linking main.o against libhello.
To create an object file from a source file, the compiler is invoked with the `-c' flag (and any other desired flags):
burger$ gcc -g -O -c main.c
burger$
The above compiler command produces an object file, main.o, from the source file main.c.
For most library systems, creating object files that become part of a static library is as simple as creating object files that are linked to form an executable:
burger$ gcc -g -O -c foo.c
burger$ gcc -g -O -c hello.c
burger$
Shared libraries, however, may only be built from position-independent code (PIC). So, special flags must be passed to the compiler to tell it to generate PIC rather than the standard position-dependent code.
Since this is a library implementation detail, libtool hides the complexity of PIC compiler flags by using separate library object files (which end in `.lo' instead of `.o'). On systems without shared libraries (or without special PIC compiler flags), these library object files are identical to “standard” object files.
To create library object files for foo.c and hello.c, simply invoke libtool with the standard compilation command as arguments (see Compile mode):
a23$ libtool --mode=compile gcc -g -O -c foo.c
gcc -g -O -c foo.c
echo timestamp > foo.lo
a23$ libtool --mode=compile gcc -g -O -c hello.c
gcc -g -O -c hello.c
echo timestamp > hello.lo
a23$
Note that libtool creates two files for each invocation. The `.lo' file is a library object, which may be built into a shared library, and the `.o' file is a standard object file. On `a23', the library objects are just timestamps, because only static libraries are supported.
On shared library systems, libtool automatically inserts the PIC generation flags into the compilation command, so that the library object and the standard object differ:
burger$ libtool --mode=compile gcc -g -O -c foo.c
gcc -g -O -c -fPIC -DPIC foo.c
mv -f foo.o foo.lo
gcc -g -O -c foo.c >/dev/null 2>&1
burger$ libtool --mode=compile gcc -g -O -c hello.c
gcc -g -O -c -fPIC -DPIC hello.c
mv -f hello.o hello.lo
gcc -g -O -c hello.c >/dev/null 2>&1
burger$
Notice that the second run of GCC has its output discarded. This is done so that compiler warnings aren't annoyingly duplicated.
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 ranlib) commands.
Again, the libtool library name differs from the standard name (it has a `.la' suffix instead of a `.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
libtool: cannot build libtool library `libhello.la' from non-libtool \
objects
a23$
Aha! Libtool caught a common error... trying to build a library from standard objects instead of library objects. This doesn't matter for static libraries, but on shared library systems, it is of great importance.
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 in which they (eventually) will 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
mkdir .libs
ar cru .libs/libhello.a foo.o hello.o
ranlib .libs/libhello.a
creating 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
mkdir .libs
ld -Bshareable -o .libs/libhello.so.0.0 foo.lo hello.lo -lm
ar cru .libs/libhello.a foo.o hello.o
ranlib .libs/libhello.a
creating 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
library.
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.
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 same2 (see Link mode):
a23$ libtool --mode=link 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 --mode=link 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 --mode=link 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.
If hell was a complicated program, you would certainly want to test and debug it before installing it on your system. In the above section, you saw how the libtool wrapper script makes it possible to run the program directly, but unfortunately, this mechanism interferes with the debugger:
burger$ gdb hell
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i386-unknown-netbsd), (C) 1996 Free Software Foundation, Inc.
"hell": not in executable format: File format not recognized
(gdb) quit
burger$
Sad. It doesn't work because GDB doesn't know where the executable lives. So, let's try again, by invoking GDB directly on the executable:
burger$ gdb .libs/hell
trick:/home/src/libtool/demo$ gdb .libs/hell
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i386-unknown-netbsd), (C) 1996 Free Software Foundation, Inc.
(gdb) break main
Breakpoint 1 at 0x8048547: file main.c, line 29.
(gdb) run
Starting program: /home/src/libtool/demo/.libs/hell
/home/src/libtool/demo/.libs/hell: can't load library 'libhello.so.2'
Program exited with code 020.
(gdb) quit
burger$
Argh. Now GDB complains because it cannot find the shared library that hell is linked against. So, we must use libtool in order to properly set the library path and run the debugger. Fortunately, we can forget all about the .libs directory, and just run it on the executable wrapper (see Execute mode):
burger$ libtool --mode=execute gdb hell
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is no warranty for GDB; type "show warranty" for details.
GDB 4.16 (i386-unknown-netbsd), (C) 1996 Free Software Foundation, Inc.
(gdb) break main
Breakpoint 1 at 0x8048547: file main.c, line 29.
(gdb) run
Starting program: /home/src/libtool/demo/.libs/hell
Breakpoint 1, main (argc=1, argv=0xbffffc40) at main.c:29
29 printf ("Welcome to GNU Hell!\n");
(gdb) quit
The program is running. Quit anyway (and kill it)? (y or n) y
burger$
Installing libraries on a non-libtool system is quite straightforward... just copy them into place:3
burger$ su
Password: ********
burger# cp libhello.a /usr/local/lib/libhello.a
burger#
Oops, don't forget the ranlib command:
burger# ranlib /usr/local/lib/libhello.a
burger#
Libtool installation is quite simple, as well. Just use the
install or cp command that you normally would
(see Install mode):
a23# libtool --mode=install cp libhello.la /usr/local/lib/libhello.la
cp libhello.la /usr/local/lib/libhello.la
cp .libs/libhello.a /usr/local/lib/libhello.a
ranlib /usr/local/lib/libhello.a
a23#
Note that the libtool library libhello.la is also installed, to help libtool with uninstallation (see Uninstall mode) and linking (see Linking executables) and to help programs with dlopening (see Dlopened modules).
Here is the shared library example:
burger# libtool --mode=install install -c libhello.la \
/usr/local/lib/libhello.la
install -c .libs/libhello.so.0.0 /usr/local/lib/libhello.so.0.0
install -c libhello.la /usr/local/lib/libhello.la
install -c .libs/libhello.a /usr/local/lib/libhello.a
ranlib /usr/local/lib/libhello.a
burger#
It is safe to specify the `-s' (strip symbols) flag if you use a BSD-compatible install program when installing libraries. Libtool will either ignore the `-s' flag, or will run a program that will strip only debugging and compiler symbols from the library.
Once the libraries have been put in place, there may be some additional configuration that you need to do before using them. First, you must make sure that where the library is installed actually agrees with the `-rpath' flag you used to build it.
Then, running `libtool -n --mode=finish libdir' can give you further hints on what to do (see Finish mode):
burger# libtool -n --mode=finish /usr/local/lib
PATH="$PATH:/sbin" ldconfig -m /usr/local/lib
-----------------------------------------------------------------
Libraries have been installed in:
/usr/local/lib
To link against installed libraries in a given directory, LIBDIR,
you must use the `-LLIBDIR' flag during linking.
You will also need to do one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-RLIBDIR' linker flag
See any operating system documentation about shared libraries for
more information, such as the ld and ld.so manual pages.
-----------------------------------------------------------------
burger#
After you have completed these steps, you can go on to begin using the installed libraries. You may also install any executables that depend on libraries you created.
If you used libtool to link any executables against uninstalled libtool libraries (see Linking executables), you need to use libtool to install the executables after the libraries have been installed (see Installing libraries).
So, for our Ultrix example, we would run:
a23# libtool install -c hell /usr/local/bin/hell
install -c hell /usr/local/bin/hell
a23#
On shared library systems, libtool just ignores the wrapper script and installs the correct binary:
burger# libtool install -c hell /usr/local/bin/hell
install -c .libs/hell /usr/local/bin/hell
burger#
Why return to ar and ranlib silliness when you've had a
taste of libtool? Well, sometimes it is desirable to create a static
archive that can never be shared. The most frequent case is when you
have a set of object files that you use to build several different
programs. You can create a “convenience library” out of those
objects, and link programs with the library, instead of listing all
object files for every program. This technique is often used to
overcome GNU automake's lack of support for linking object files built
from sources in other directories, because it supports linking with
libraries from other directories. This limitation applies to GNU
automake up to release 1.4; newer releases should support sources in
other directories.
If you just want to link this convenience library into programs, then
you could just ignore libtool entirely, and use the old ar and
ranlib commands (or the corresponding GNU automake
`_LIBRARIES' rules). You can even install a convenience library
(but you probably don't want to) using libtool:
burger$ libtool --mode=install ./install-sh -c libhello.a \
/local/lib/libhello.a
./install-sh -c libhello.a /local/lib/libhello.a
ranlib /local/lib/libhello.a
burger$
Using libtool for static library installation protects your library from
being accidentally stripped (if the installer used the `-s' flag),
as well as automatically running the correct ranlib command.
But libtool libraries are more than just collections of object files: they can also carry library dependency information, which old archives do not. If you want to create a libtool static convenience library, you can omit the `-rpath' flag and use `-static' to indicate that you're only interested in a static library. When you link a program with such a library, libtool will actually link all object files and dependency libraries into the program.
If you omit both `-rpath' and `-static', libtool will create a convenience library that can be used to create other libtool libraries, even shared ones. Just like in the static case, the library behaves as an alias to a set of object files and dependency libraries, but in this case the object files are suitable for inclusion in shared libraries. But be careful not to link a single convenience library, directly or indirectly, into a single program or library, otherwise you may get errors about symbol redefinitions.
When GNU automake is used, you should use noinst_LTLIBRARIES
instead of lib_LTLIBRARIES for convenience libraries, so that
the `-rpath' option is not passed when they are linked.
As a rule of thumb, link a libtool convenience library into at most one libtool library, and never into a program, and link libtool static convenience libraries only into programs, and only if you need to carry library dependency information to the user of the static convenience library.
Another common situation where static linking is desirable is in creating a standalone binary. Use libtool to do the linking and add the `-all-static' flag.
libtool
The libtool program has the following synopsis:
libtool [option]... [mode-arg]...
and accepts the following options:
less (or
more) or redirect to a file.
mode must be set to one of the following:
The mode-args are a variable number of arguments, depending on the selected operation mode. In general, each mode-arg is interpreted by programs libtool invokes, rather than libtool itself.
For compile mode, mode-args is a compiler command to be used in creating a `standard' object file. These arguments should begin with the name of the C compiler, and contain the `-c' compiler flag so that only an object file is created.
Libtool determines the name of the output file by removing the directory component from the source file name, then substituting the source code suffix (e.g. `.c' for C source code) with the library object suffix, `.lo'.
If shared libraries are being built, any necessary PIC generation flags are substituted into the compilation command. You can pass link specific flags to the compiler driver using `-XCClinker flag' or pass linker flags with `-Wl,flag' and `-Xlinker flag'. You can also pass compile specific flags using `-Wc,flag' and `-Xcompiler flag'.
If both PIC and non-PIC objects are being built, libtool will normally suppress the compiler output for the PIC object compilation to save showing very similar, if not identical duplicate output for each object. If the `-no-suppress' option is given in compile mode, libtool will show the compiler output for both objects.
If the `-static' option is given, then a `.o' file is built, even if libtool was configured with `--disable-static'.
Note that the `-o' option is now fully supported. It is emulated on the platforms that don't support it (by locking and moving the objects), so it is really easy to use libtool, just with minor modifications to your Makefiles. Typing for example
libtool gcc -c foo/x.c -o foo/x.lo
will do what you expect.
Note, however, that, if the compiler does not support `-c' and `-o', it is impossible to compile foo/x.c without overwriting an existing ./x.o. Therefore, if you do have a source file ./x.c, make sure you introduce dependencies in your Makefile to make sure ./x.o (or ./x.lo) is re-created after any sub-directory's x.lo:
x.o x.lo: foo/x.lo bar/x.lo
This will also ensure that make won't try to use a temporarily corrupted x.o to create a program or library. It may cause needless recompilation on platforms that support `-c' and `-o' together, but it's the only way to make it safe for those that don't.
Link mode links together object files (including library objects) to form another library or to create an executable program.
mode-args consist of a command using the C compiler to create an output file (with the `-o' flag) from several object files.
The following components of mode-args are treated specially:
self libtool will make sure that the program can dlopen
itself, either by enabling -export-dynamic or by falling back to
`-dlpreopen self'.
self, the symbols of the program itself will be added to
lt_preloaded_symbols.
If file is force libtool will make sure that
lt_preloaded_symbols is always defined, regardless of whether
it's empty or not.
dlsym
(see Dlopened modules).
gcc -ftest-coverage for example.
If the output-file ends in `.la', then a libtool library is created, which must be built only from library objects (`.lo' files). The `-rpath' option is required. In the current implementation, libtool libraries may not depend on other uninstalled libtool libraries (see Inter-library dependencies).
If the output-file ends in `.a', then a standard library is
created using ar and possibly ranlib.
If output-file ends in `.o' or `.lo', then a reloadable object file is created from the input files (generally using `ld -r'). This method is often called partial linking.
Otherwise, an executable program is created.
For execute mode, the library path is automatically set, then a program is executed.
The first of the mode-args is treated as a program name, with the rest as arguments to that program.
The following components of mode-args are treated specially:
This mode sets the library path environment variable according to any `-dlopen' flags.
If any of the args are libtool executable wrappers, then they are translated into the name of their corresponding uninstalled binary, and any of their required library directories are added to the library path.
In install mode, libtool interprets most of the elements of
mode-args as an installation command beginning with
cp, or a BSD-compatible install program.
The following components of mode-args are treated specially:
automake uses
DESTDIR. For instance, if prefix is /usr/local,
but inst-prefix-dir is /tmp, then the object will be
installed under /tmp/usr/local/. If the installed object
is a libtool library, then the internal fields of that library
will reflect only prefix, not inst-prefix-dir:
# Directory that this library needs to be installed in:
libdir='/usr/local/lib'
not
# Directory that this library needs to be installed in:
libdir='/tmp/usr/local/lib'
inst-prefix is also used to insure that if the installed
object must be relinked upon installation, that it is relinked
against the libraries in inst-prefix-dir/prefix,
not prefix.
In truth, this option is not really intended for use when calling
libtool directly; it is automatically used when libtool --mode=install
calls libtool --mode=relink. Libtool does this by
analyzing the destination path given in the original
libtool --mode=install command and comparing it to the
expected installation path established during libtool --mode=link.
Thus, end-users need change nothing, and automake-style
make install DESTDIR=/tmp will Just Work(tm).
The rest of the mode-args are interpreted as arguments to the
cp or install command.
The command is run, and any necessary unprivileged post-installation commands are also completed.
Finish mode helps system administrators install libtool libraries so that they can be located and linked into user programs.
Each mode-arg is interpreted as the name of a library directory. Running this command may require superuser privileges, so the `--dry-run' option may be useful.
Uninstall mode deletes installed libraries, executables and objects.
The first mode-arg is the name of the program to use to delete files (typically /bin/rm).
The remaining mode-args are either flags for the deletion program (beginning with a `-'), or the names of files to delete.
Clean mode deletes uninstalled libraries, executables, objects and libtool's temporary files associated with them.
The first mode-arg is the name of the program to use to delete files (typically /bin/rm).
The remaining mode-args are either flags for the deletion program (beginning with a `-'), or the names of files to delete.
This chapter describes how to integrate libtool with your packages so that your users can install hassle-free shared libraries.
Libtool is fully integrated with Automake (see Introduction), starting with Automake version 1.2.
If you want to use libtool in a regular Makefile (or Makefile.in), you are on your own. If you're not using Automake 1.2, and you don't know how to incorporate libtool into your package you need to do one of the following:
Libtool library support is implemented under the `LTLIBRARIES' primary.
Here are some samples from the Automake Makefile.am in the libtool distribution's demo subdirectory.
First, to link a program against a libtool library, just use the `program_LDADD' variable:
bin_PROGRAMS = hell hell.debug
# Build hell from main.c and libhello.la
hell_SOURCES = main.c
hell_LDADD = libhello.la
# Create an easier-to-debug version of hell.
hell_debug_SOURCES = main.c
hell_debug_LDADD = libhello.la
hell_debug_LDFLAGS = -static
The flags `-dlopen' or `-dlpreopen' (see Link mode) would fit better in the program_LDADD variable. Unfortunately, GNU automake, up to release 1.4, doesn't accept these flags in a program_LDADD variable, so you have the following alternatives:
program_LDADD = "-dlopen" libfoo.la
program_DEPENDENCIES = libfoo.la
You may use the `program_LDFLAGS' variable to stuff in any flags you want to pass to libtool while linking `program' (such as `-static' to avoid linking uninstalled shared libtool libraries).
Building a libtool library is almost as trivial... note the use of `libhello_la_LDFLAGS' to pass the `-version-info' (see Versioning) option to libtool:
# Build a libtool library, libhello.la for installation in libdir.
lib_LTLIBRARIES = libhello.la
libhello_la_SOURCES = hello.c foo.c
libhello_la_LDFLAGS = -version-info 3:12:1
The `-rpath' option is passed automatically by Automake (except for
libraries listed as noinst_LTLIBRARIES), so you
should not specify it.
See Building a Shared Library, for more information.
Libtool requires intimate knowledge of your compiler suite and operating system in order to be able to create shared libraries and link against them properly. When you install the libtool distribution, a system-specific libtool script is installed into your binary directory.
However, when you distribute libtool with your own packages (see Distributing), you do not always know which compiler suite and operating system are used to compile your package.
For this reason, libtool must be configured before it can be
used. This idea should be familiar to anybody who has used a GNU
configure script. configure runs a number of tests for
system features, then generates the Makefiles (and possibly a
config.h header file), after which you can run make and
build the package.
Libtool adds its own tests to your configure script in order to
generate a libtool script for the installer's host machine.
AC_PROG_LIBTOOL macroIf you are using GNU Autoconf (or Automake), you should add a call to
AC_PROG_LIBTOOL to your configure.in file. This macro
adds many new tests to the configure script so that the generated
libtool script will understand the characteristics of the host:
Add support for the `--enable-shared' and `--disable-shared'
configureflags.4AM_PROG_LIBTOOLwas the old name for this macro, and although supported at the moment is deprecated.By default, this macro turns on shared libraries if they are available, and also enables static libraries if they don't conflict with the shared libraries. You can modify these defaults by calling either the
AC_DISABLE_SHAREDorAC_DISABLE_STATICmacros:# Turn off shared libraries during beta-testing, since they # make the build process take too long. AC_DISABLE_SHARED AC_PROG_LIBTOOLThe user may specify modified forms of the configure flags `--enable-shared' and `--enable-static' to choose whether shared or static libraries are built based on the name of the package. For example, to have shared `bfd' and `gdb' libraries built, but not shared `libg++', you can run all three
configurescripts as follows:trick$ ./configure --enable-shared=bfd,gdbIn general, specifying `--enable-shared=pkgs' is the same as configuring with `--enable-shared' every package named in the comma-separated pkgs list, and every other package with `--disable-shared'. The `--enable-static=pkgs' flag behaves similarly, but it uses `--enable-static' and `--disable-static'. The same applies to the `--enable-fast-install=pkgs' flag, which uses `--enable-fast-install' and `--disable-fast-install'.
The package name `default' matches any packages which have not set their name in the
PACKAGEenvironment variable.This macro also sets the shell variable LIBTOOL_DEPS, that you can use to automatically update the libtool script if it becomes out-of-date. In order to do that, add to your configure.in:
AC_PROG_LIBTOOL AC_SUBST(LIBTOOL_DEPS)and, to Makefile.in or Makefile.am:
LIBTOOL_DEPS = @LIBTOOL_DEPS@ libtool: $(LIBTOOL_DEPS) $(SHELL) ./config.status --recheckIf you are using GNU automake, you can omit the assignment, as automake will take care of it. You'll obviously have to create some dependency on libtool.
Enable checking for dlopen support. This macro should be used if the package makes use of the `-dlopen' and `-dlpreopen' flags, otherwise libtool will assume that the system does not support dlopening. The macro must be called before
AC_PROG_LIBTOOL.
This macro should be used if the package has been ported to build clean dlls on win32 platforms. Usually this means that any library data items are exported with
__declspec(dllexport)and imported with__declspec(dllimport). If this macro is not used, libtool will assume that the package libraries are not dll clean and will build only static libraries on win32 hosts.This macro must be called before
AC_PROG_LIBTOOL, and provision must be made to pass `-no-undefined' tolibtoolin link mode from the packageMakefile. Naturally, if you pass `-no-undefined', you must ensure that all the library symbols really are defined at link time!
Change the default behaviour for
AC_PROG_LIBTOOLto disable optimization for fast installation. The user may still override this default, depending on platform support, by specifying `--enable-fast-install'.
Change the default behaviour for
AC_PROG_LIBTOOLto disable shared libraries. The user may still override this default by specifying `--enable-shared'.
Change the default behaviour for
AC_PROG_LIBTOOLto disable static libraries. The user may still override this default by specifying `--enable-static'.
The tests in AC_PROG_LIBTOOL also recognize the following
environment variables:
The C compiler that will be used by the generated
libtool. If this is not set,AC_PROG_LIBTOOLwill look forgccorcc.
Compiler flags used to generate standard object files. If this is not set,
AC_PROG_LIBTOOLwill not use any such flags. It affects only the wayAC_PROG_LIBTOOLruns tests, not the producedlibtool.
C preprocessor flags. If this is not set,
AC_PROG_LIBTOOLwill not use any such flags. It affects only the wayAC_PROG_LIBTOOLruns tests, not the producedlibtool.
The system linker to use (if the generated
libtoolrequires one). If this is not set,AC_PROG_LIBTOOLwill try to find out what is the linker used by CC.
The flags to be used by
libtoolwhen it links a program. If this is not set,AC_PROG_LIBTOOLwill not use any such flags. It affects only the wayAC_PROG_LIBTOOLruns tests, not the producedlibtool.
The libraries to be used by
AC_PROG_LIBTOOLwhen it links a program. If this is not set,AC_PROG_LIBTOOLwill not use any such flags. It affects only the wayAC_PROG_LIBTOOLruns tests, not the producedlibtool.
A command that creates a link of a program, a soft-link if possible, a hard-link otherwise.
AC_PROG_LIBTOOLwill check for a suitable program if this variable is not set.
Program to use rather than checking for
dlltool. Only meaningful for Cygwin/MS-Windows.
Program to use rather than checking for
objdump. Only meaningful for Cygwin/MS-Windows.
Program to use rather than checking for
as. Only used on Cygwin/MS-Windows at the moment.
When you invoke the libtoolize program (see Invoking libtoolize), it will tell you where to find a definition of
AC_PROG_LIBTOOL. If you use Automake, the aclocal program
will automatically add AC_PROG_LIBTOOL support to your
configure script.
Nevertheless, it is advisable to include a copy of libtool.m4 in
acinclude.m4, so that, even if aclocal.m4 and
configure are rebuilt for any reason, the appropriate libtool
macros will be used. The alternative is to hope the user will have a
compatible version of libtool.m4 installed and accessible for
aclocal. This may lead to weird errors when versions don't
match.
In order to use libtool, you need to include the following files with your package:
Note that the libtool script itself should not be included with your package. See Configuring.
You should use the libtoolize program, rather than manually
copying these files into your package. Note however, that install-sh
is not copied by libtoolize; if you use Automake, it will take care
of that, otherwise you may obtain a copy from the package data directory
of the installed Libtool. This may change in a future Libtool version.
libtoolize
The libtoolize program provides a standard way to add libtool
support to your package. In the future, it may implement better usage
checking, or other features to make libtool even easier to use.
The libtoolize program has the following synopsis:
libtoolize [option]...
and accepts the following options:
`libtoolize --automake' is used by Automake to add libtool files to
your package, when AC_PROG_LIBTOOL appears in your
configure.in.
less (or
more) or redirect to a file.
libtoolize won't
overwrite existing files.
libtoolize version information and exit.
If libtoolize detects an explicit call to
AC_CONFIG_AUX_DIR (see The Autoconf Manual) in your configure.in, it
will put the files in the specified directory.
libtoolize displays hints for adding libtool support to your
package, as well.
The Autoconf package comes with a few macros that run tests, then set a variable corresponding to the name of an object file. Sometimes it is necessary to use corresponding names for libtool objects.
Here are the names of variables that list libtool objects:
Substituted by
AC_FUNC_ALLOCA(see Particular Function Checks). Is either empty, or contains `alloca.lo'.
Substituted by
AC_REPLACE_FUNCS(see Generic Function Checks), and a few other functions.
Unfortunately, the stable release of Autoconf (2.13, at the time of
this writing) does not have any way for libtool to provide support for
these variables. So, if you depend on them, use the following code
immediately before the call to AC_OUTPUT in your
configure.in:
LTLIBOBJS=`echo "$LIBOBJS" | sed 's/\.[^.]* /.lo /g;s/\.[^.]*$/.lo/'`
AC_SUBST(LTLIBOBJS)
LTALLOCA=`echo "$ALLOCA" | sed 's/\.[^.]* /.lo /g;s/\.[^.]*$/.lo/'`
AC_SUBST(LTALLOCA)
AC_OUTPUT(...)
When you are developing a package, it is often worthwhile to configure
your package with the `--disable-shared' flag, or to override the
defaults for AC_PROG_LIBTOOL by using the
AC_DISABLE_SHARED Autoconf macro (see The AC_PROG_LIBTOOL macro). This prevents libtool from building
shared libraries, which has several advantages:
You may want to put a small note in your package README to let other developers know that `--disable-shared' can save them time. The following example note is taken from the GIMP5 distribution README:
The GIMP uses GNU Libtool in order to build shared libraries on a
variety of systems. While this is very nice for making usable
binaries, it can be a pain when trying to debug a program. For that
reason, compilation of shared libraries can be turned off by
specifying the `--disable-shared' option to configure.
The most difficult issue introduced by shared libraries is that of
creating and resolving runtime dependencies. Dependencies on programs
and libraries are often described in terms of a single name, such as
sed. So, one may say “libtool depends on sed,” and that is
good enough for most purposes.
However, when an interface changes regularly, we need to be more specific: “Gnus 5.1 requires Emacs 19.28 or above.” Here, the description of an interface consists of a name, and a “version number.”
Even that sort of description is not accurate enough for some purposes. What if Emacs 20 changes enough to break Gnus 5.1?
The same problem exists in shared libraries: we require a formal version system to describe the sorts of dependencies that programs have on shared libraries, so that the dynamic linker can guarantee that programs are linked only against libraries that provide the interface they require.
Interfaces for libraries may be any of the following (and more):
Note that static functions do not count as interfaces, because they are not directly available to the user of the library.
Libtool has its own formal versioning system. It is not as flexible as some, but it is definitely the simplest of the more powerful versioning systems.
Think of a library as exporting several sets of interfaces, arbitrarily represented by integers. When a program is linked against a library, it may use any subset of those interfaces.
Libtool's description of the interfaces that a program uses is simple: it encodes the least and the greatest interface numbers in the resulting binary (first-interface, last-interface).
The dynamic linker is guaranteed that if a library supports every interface number between first-interface and last-interface, then the program can be relinked against that library.
Note that this can cause problems because libtool's compatibility requirements are actually stricter than is necessary.
Say libhello supports interfaces 5, 16, 17, 18, and 19, and that libtool is used to link test against libhello.
Libtool encodes the numbers 5 and 19 in test, and the dynamic linker will only link test against libraries that support every interface between 5 and 19. So, the dynamic linker refuses to link test against libhello!
In order to eliminate this problem, libtool only allows libraries to declare consecutive interface numbers. So, libhello can declare at most that it supports interfaces 16 through 19. Then, the dynamic linker will link test against libhello.
So, libtool library versions are described by three integers:
-
age to current.
If two libraries have identical current and age numbers, then the dynamic linker chooses the library with the greater revision number.
If you want to use libtool's versioning system, then you must specify the version information to libtool using the `-version-info' flag during link mode (see Link mode).
This flag accepts an argument of the form `current[:revision[:age]]'. So, passing `-version-info 3:12:1' sets current to 3, revision to 12, and age to 1.
If either revision or age are omitted, they default to 0. Also note that age must be less than or equal to the current interface number.
Here are a set of rules to help you update your library version information:
Never try to set the interface numbers so that they correspond to the release number of your package. This is an abuse that only fosters misunderstanding of the purpose of library versions. Instead, use the `-release' flag (see Release numbers), but be warned that every release of your package will not be binary compatible with any other release.
Often, people want to encode the name of the package release into the shared library so that it is obvious to the user which package their programs are linked against. This convention is used especially on GNU/Linux:
trick$ ls /usr/lib/libbfd*
/usr/lib/libbfd.a /usr/lib/libbfd.so.2.7.0.2
/usr/lib/libbfd.so
trick$
On `trick', /usr/lib/libbfd.so is a symbolic link to libbfd.so.2.7.0.2, which was distributed as a part of `binutils-2.7.0.2'.
Unfortunately, this convention conflicts directly with libtool's idea of library interface versions, because the library interface rarely changes at the same time that the release number does, and the library suffix is never the same across all platforms.
So, in order to accommodate both views, you can use the `-release' flag in order to set release information for libraries which you do not want to use `-version-info'. For the libbfd example, the next release which uses libtool should be built with `-release 2.9.0', which will produce the following files on GNU/Linux:
trick$ ls /usr/lib/libbfd*
/usr/lib/libbfd-2.9.0.so /usr/lib/libbfd.a
/usr/lib/libbfd.so
trick$
In this case, /usr/lib/libbfd.so is a symbolic link to libbfd-2.9.0.so. This makes it obvious that the user is dealing with `binutils-2.9.0', without compromising libtool's idea of interface versions.
Note that this option causes a modification of the library name, so do not use it unless you want to break binary compatibility with any past library releases. In general, you should only use `-release' for package-internal libraries or for ones whose interfaces change very frequently.
Writing a good library interface takes a lot of practice and thorough understanding of the problem that the library is intended to solve.
If you design a good interface, it won't have to change often, you won't have to keep updating documentation, and users won't have to keep relearning how to use the library.
Here is a brief list of tips for library interface design, which may help you in your exploits:
This is essentially the same thing as using abstract data types and
inheritance in an object-oriented system.
static keyword (or equivalent) whenever possibleextern int foo[];. This is because
on i386 and some other SVR4/ELF systems, when an application
references data in a shared library the size of that data (whatever
its type) is included in the application executable. If you might
want to change the size of an array or string then provide a pointer
not the actual array.
Writing portable C header files can be difficult, since they may be read by different types of compilers:
extern "C" directive, so that the
names aren't mangled. See C++ libraries, for other issues relevant
to using C++ with libtool.
#included.
These complications mean that your library interface headers must use some C preprocessor magic in order to be usable by each of the above compilers.
foo.h in the demo subdirectory of the libtool distribution serves as an example for how to write a header file that can be safely installed in a system directory.
Here are the relevant portions of that file:
/* BEGIN_C_DECLS should be used at the beginning of your declarations,
so that C++ compilers don't mangle their names. Use END_C_DECLS at
the end of C declarations. */
#undef BEGIN_C_DECLS
#undef END_C_DECLS
#ifdef __cplusplus
# define BEGIN_C_DECLS extern "C" {
# define END_C_DECLS }
#else
# define BEGIN_C_DECLS /* empty */
# define END_C_DECLS /* empty */
#endif
/* PARAMS is a macro used to wrap function prototypes, so that
compilers that don't understand ANSI C prototypes still work,
and ANSI C compilers can issue warnings about type mismatches. */
#undef PARAMS
#if defined (__STDC__) || defined (_AIX) \
|| (defined (__mips) && defined (_SYSTYPE_SVR4)) \
|| defined(WIN32) || defined(__cplusplus)
# define PARAMS(protos) protos
#else
# define PARAMS(protos) ()
#endif
These macros are used in foo.h as follows:
#ifndef FOO_H
#define FOO_H 1
/* The above macro definitions. */
#include "..."
BEGIN_C_DECLS
int foo PARAMS((void));
int hello PARAMS((void));
END_C_DECLS
#endif /* !FOO_H */
Note that the #ifndef FOO_H prevents the body of foo.h from being read more than once in a given compilation.
Also the only thing that must go outside the
BEGIN_C_DECLS/END_C_DECLS pair are #include lines.
Strictly speaking it is only C symbol names that need to be protected,
but your header files will be more maintainable if you have a single
pair of of these macros around the majority of the header contents.
You should use these definitions of PARAMS, BEGIN_C_DECLS,
and END_C_DECLS into your own headers. Then, you may use them to
create header files that are valid for C++, ANSI, and non-ANSI
compilers6.
Do not be naive about writing portable code. Following the tips given above will help you miss the most obvious problems, but there are definitely other subtle portability issues. You may need to cope with some of the following issues:
void * generic
pointer type, and so need to use char * in its place.
const, inline and signed keywords are not
supported by some compilers, especially pre-ANSI compilers.
long double type is not supported by many compilers.
By definition, every shared library system provides a way for executables to depend on libraries, so that symbol resolution is deferred until runtime.
An inter-library dependency is one in which a library depends on
other libraries. For example, if the libtool library libhello
uses the cos function, then it has an inter-library dependency
on libm, the math library that implements cos.
Some shared library systems provide this feature in an internally-consistent way: these systems allow chains of dependencies of potentially infinite length.
However, most shared library systems are restricted in that they only allow a single level of dependencies. In these systems, programs may depend on shared libraries, but shared libraries may not depend on other shared libraries.
In any event, libtool provides a simple mechanism for you to declare
inter-library dependencies: for every library libname that
your own library depends on, simply add a corresponding
-lname option to the link line when you create your
library. To make an example of our
libhello that depends on libm:
burger$ libtool --mode=link gcc -g -O -o libhello.la foo.lo hello.lo \
-rpath /usr/local/lib -lm
burger$
When you link a program against libhello, you don't need to specify the same `-l' options again: libtool will do that for you, in order to guarantee that all the required libraries are found. This restriction is only necessary to preserve compatibility with static library systems and simple dynamic library systems.
Some platforms, such as AIX, do not even allow you this flexibility. In order to build a shared library, it must be entirely self-contained (that is, have references only to symbols that are found in the `.lo' files or the specified `-l' libraries), and you need to specify the `-no-undefined' flag. By default, libtool builds only static libraries on these kinds of platforms.
The simple-minded inter-library dependency tracking code of libtool releases prior to 1.2 was disabled because it was not clear when it was possible to link one library with another, and complex failures would occur. A more complex implementation of this concept was re-introduced before release 1.3, but it has not been ported to all platforms that libtool supports. The default, conservative behavior is to avoid linking one library with another, introducing their inter-dependencies only when a program is linked with them.
It can sometimes be confusing to discuss dynamic linking, because the term is used to refer to two different concepts:
dlopen,7 which load
arbitrary, user-specified modules at runtime. This type of dynamic
linking is explicitly controlled by the application.
To mitigate confusion, this manual refers to the second type of dynamic linking as dlopening a module.
The main benefit to dlopening object modules is the ability to access compiled object code to extend your program, rather than using an interprete