Copyright (C) 1996-2008 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.2 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 2.2.
See Reporting bugs, for information on how to report problems with gnu Libtool.
--- The Detailed Node Listing ---
Introduction
Using libtool
Invoking libtool
Integrating libtool with your package
Configuring libtool
Including libtool in your package
Using libtool with other languages
Library interface versions
Tips for interface design
Dlopened modules
Using libltdl
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 that 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.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, usually named 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 and uses separate library object files (the PIC one lives in the ‘.libs’ subdirectory and the static one lives in the current directory). On systems without shared libraries, the PIC library object files are not created, whereas on systems where all code is PIC, such as AIX, the static ones are not created.
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 -o foo.o
a23$ libtool --mode=compile gcc -g -O -c hello.c
gcc -g -O -c hello.c -o hello.o
a23$
Note that libtool silently creates an additional control file on each ‘compile’ invocation. The ‘.lo’ file is the libtool object, which Libtool uses to determine what object file may be built into a shared library. On ‘a23’, only static libraries are supported so the library objects look like this:
# foo.lo - a libtool object file
# Generated by ltmain.sh (GNU libtool) 2.2
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# Name of the PIC object.
pic_object=none
# Name of the non-PIC object.
non_pic_object='foo.o'
On shared library systems, libtool automatically generates an additional PIC object by inserting the appropriate PIC generation flags into the compilation command:
burger$ libtool --mode=compile gcc -g -O -c foo.c
mkdir .libs
gcc -g -O -c foo.c -fPIC -DPIC -o .libs/foo.o
gcc -g -O -c foo.c -o foo.o >/dev/null 2>&1
burger$
Note that Libtool automatically created ‘.libs’ directory upon its first execution, where PIC library object files will be stored.
Since ‘burger’ supports shared libraries, and requires PIC objects to build them, Libtool has compiled a PIC object this time, and made a note of it in the libtool object:
# foo.lo - a libtool object file
# Generated by ltmain.sh (GNU libtool) 2.2
#
# Please DO NOT delete this file!
# It is necessary for linking the library.
# Name of the PIC object.
pic_object='.libs/foo.o'
# Name of the non-PIC object.
non_pic_object='foo.o'
Notice that the second run of GCC has its output discarded. This is done so that compiler warnings aren't annoyingly duplicated. If you need to see both sets of warnings (you might have conditional code inside ‘#ifdef PIC’ for example), you can turn off suppression with the -no-suppress option to libtool's compile mode:
burger$ libtool --mode=compile gcc -no-suppress -g -O -c hello.c
gcc -g -O -c hello.c -fPIC -DPIC -o .libs/hello.o
gcc -g -O -c hello.c -o hello.o
burger$
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 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 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
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 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.
Again, you may want to have a look at the ‘.la’ file in order 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 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
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. Notice that Libtool also remembered that libhello.la depends on -lm, so even though we didn't specify -lm on the libtool command line3 Libtool has added it to the gcc link line for us.
On ‘burger’ Libtool links against the uninstalled shared library:
burger$ libtool --mode=link gcc -g -O -o hell main.o libhello.la
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 -lm
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?
Notice that the executable, hell, was actually created in the
.libs subdirectory. Then, a wrapper script was created
in the current directory.
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.
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
GNU gdb 5.3 (i386-unknown-netbsd)
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License,
and you are welcome to change it and/or 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) 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.0'
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
GNU gdb 5.3 (i386-unknown-netbsd)
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License,
and you are welcome to change it and/or 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) 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:4
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 finish libdir’ can give you further hints on what to do (see Finish mode):
burger# libtool -n 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 --mode=install -c hell /usr/local/bin/hell
install -c hell /usr/local/bin/hell
a23#
On shared library systems that require wrapper scripts, libtool just ignores the wrapper script and installs the correct binary:
burger# libtool --mode=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 libraries. You can create a “convenience library” out of those objects, and link against that with the other libraries, instead of listing all the object files every time.
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 using gnu Libtool, though you probably don't want to and hence gnu Automake doesn't allow you to do so.
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.
The key is remembering that a convenience library contains pic objects, and can be linked where a list of pic objects makes sense; i.e. into a shared library. A static convenience library contains non-pic objects, so can be linked into an old static library, or a program.
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.
The libtool program has the following synopsis:
libtool [option]... [mode-arg]...
and accepts the following options:
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.
The following components of mode-args are treated specially:
libtool --mode=compile 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
preloaded symbol lists. If file is force Libtool will
make sure that a preloaded symbol list 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:
# 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) most of the time.
For systems where fast installation can not be turned on, relinking
may be needed. In this case, a ‘DESTDIR’ install will fail.
Currently it is not generally possible to install into a temporary staging area that contains needed third-party libraries which are not yet visible at their final location.
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 uses a number of macros to interrogate the host system when it is being built, and you can use some of them yourself too. Although there are a great many other macros in the libtool installed m4 files, these do not form part of the published interface, and are subject to change between releases.
Macros in the ‘LT_CMD_’ namespace check for various shell commands:
Finds the longest command line that can be safely passed to ‘$SHELL’ without being truncated, and store in the shell variable ‘$max_cmd_len’. It is only an approximate value, but command lines of this length or shorter are guaranteed not to be truncated.
Macros in the ‘LT_FUNC_’ namespace check characteristics of library functions:
‘AC_DEFINE’ the preprocessor symbol ‘DLSYM_USCORE’ if we have to add an underscore to symbol-names passed in to ‘dlsym’.
Macros in the ‘LT_LIB_’ namespace check characteristics of system libraries:
This is the macro used by ‘libltdl’ to determine which dlloaders to use on this machine, if any. Several shell variables are set (and ‘AC_SUBST’ed) depending on the dlload interfaces are available on this machine. ‘LT_DLLOADERS’ contains a list of libtool libraries that can be used, and if necessary also sets ‘LIBADD_DLOPEN’ if additional system libraries are required by the ‘dlopen’ loader, and ‘LIBADD_SHL_LOAD’ if additional system libraries are required by the ‘shl_load’ loader, respectively. Finally some symbols are set in config.h depending on the loaders that are found to work: ‘HAVE_LIBDL’, ‘HAVE_SHL_LOAD’, ‘HAVE_DYLD’, ‘HAVE_DLD’.
Macros in the ‘LT_PATH_’ namespace search the system for the full path to particular system commands:
Add a --with-gnu-ld option to configure. Try to find the path to the linker used by ‘$CC’, and whether it is the gnu linker. The result is stored in the shell variable ‘$LD’, which is
AC_SUBSTed.
Try to find a bsd compatible nm or a ms compatible dumpbin command on this machine. The result is stored in the shell variable ‘$NM’, which is
AC_SUBSTed.
Macros in the ‘LT_SYS_’ namespace probe for system characteristics:
Tests whether a program can dlopen itself, and then also whether the same program can still dlopen itself when statically linked. Results are stored in the shell variables ‘$enable_dlopen_self’ and ‘enable_dlopen_self_static’ respectively.
Define the preprocessor symbol ‘LTDL_DLOPEN_DEPLIBS’ if the os needs help to load dependent libraries for ‘dlopen’ (or equivalent).
Define the preprocessor symbol ‘LT_DLSEARCH_PATH’ to the system default library search path.
Define the preprocessor symbol ‘LT_MODULE_EXT’ to the extension used for runtime loadable modules. If you use libltdl to open modules, then you can simply use the libtool library extension, ‘.la’.
Define the preprocessor symbol ‘LT_MODULE_PATH_VAR’ to the name of the shell environment variable that determines the run-time module search path.
Set the shell variable ‘sys_symbol_underscore’ to ‘no’ unless the compiler prefixes global symbols with an underscore.
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, 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’5 variable:
bin_PROGRAMS = hell hell_static
# Build hell from main.c and libhello.la
hell_SOURCES = main.c
hell_LDADD = libhello.la
# Create a statically linked version of hell.
hell_static_SOURCES = main.c
hell_static_LDADD = libhello.la
hell_static_LDFLAGS = -static
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 the compiler suite and operating system that 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.
LT_INIT macroIf you are using gnu Autoconf (or Automake), you should add a call to
LT_INIT to your configure.ac file. This macro
adds many new tests to the configure script so that the generated
libtool script will understand the characteristics of the host. It's the
most important of a number of macros defined by Libtool:
Ensure that a recent enough version of Libtool is being used. If the version of Libtool used for
LT_INITis earlier than version, print an error message to the standard error output and exit with failure (exit status is 63). For example:LT_PREREQ([2.2])
Add support for the --enable-shared and --disable-shared
configureflags.6AC_PROG_LIBTOOLandAM_PROG_LIBTOOLare deprecated names for older versions of this macro;autoupdatewill upgrade your configure.ac files.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 passing either
disable-sharedordisable-staticin the option list toLT_INIT, or usingAC_DISABLE_SHAREDorAC_DISABLE_STATIC.# Turn off shared libraries during beta-testing, since they # make the build process take too long. LT_INIT([disable-shared])The 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 that 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.ac:
LT_INIT 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.
Aside from
disable-staticanddisable-shared, there are other options that you can pass toLT_INITto modify its behaviour. Here is a full list:
- ‘dlopen’
- Enable checking for dlopen support. This option should be used if the package makes use of the -dlopen and -dlpreopen libtool flags, otherwise libtool will assume that the system does not support dlopening.
- ‘win32-dll’
- This option 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.Provision must be made to pass -no-undefined to
libtoolin 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!- ‘disable-fast-install’
- Change the default behaviour for
LT_INITto disable optimization for fast installation. The user may still override this default, depending on platform support, by specifying --enable-fast-install to configure.- ‘shared’
- Change the default behaviour for
LT_INITto enable shared libraries. This is the default on all systems where Libtool knows how to create shared libraries. The user may still override this default by specifying --disable-shared to configure.- ‘disable-shared’
- Change the default behaviour for
LT_INITto disable shared libraries. The user may still override this default by specifying --enable-shared to configure.- ‘static’
- Change the default behaviour for
LT_INITto enable static libraries. This is the default on all systems where shared libraries have been disabled for some reason, and on most systems where shared libraries have been enabled. If shared libraries are enabled, the user may still override this default by specifying --disable-static to configure.- ‘disable-static’
- Change the default behaviour for
LT_INITto disable static libraries. The user may still override this default by specifying --enable-static to configure.- ‘pic-only’
- Change the default behaviour for libtool to try to use only pic objects. The user may still override this default by specifying --without-pic to configure.
- ‘no-pic’
- Change the default behaviour of libtool to try to use only non-pic objects. The user may still override this default by specifying --with-pic to configure.
Enable libtool support for the language given if it has not yet already been enabled. Languages accepted are “C++”, “Fortran 77”, “Java” and “Windows Resource”.
If Autoconf language support macros such as
AC_PROG_CXXare used in your configure.ac, Libtool language support will automatically be enabled.Conversely using
LT_LANGto enable language support for Libtool will automatically enable Autoconf language support as well.Both of the following examples are therefore valid ways of adding C++ language support to Libtool.
LT_INIT LT_LANG([C++])LT_INIT AC_PROG_CXX
This macro is deprecated, the ‘dlopen’ option to
LT_INITshould be used instead.
This macro is deprecated, the ‘win32-dll’ option to
LT_INITshould be used instead.
This macro is deprecated, the ‘disable-fast-install’ option to
LT_INITshould be used instead.
Change the default behaviour for
LT_INITto disable shared libraries. The user may still override this default by specifying ‘--enable-shared’. The option ‘disable-shared’ toLT_INITis a shorthand for this.AM_DISABLE_SHAREDis a deprecated alias forAC_DISABLE_SHARED.
Change the default behaviour for
LT_INITto enable shared libraries. This is the default on all systems where Libtool knows how to create shared libraries. The user may still override this default by specifying ‘--disable-shared’. The option ‘shared’ toLT_INITis a shorthand for this.AM_ENABLE_SHAREDis a deprecated alias forAC_ENABLE_SHARED.
Change the default behaviour for
LT_INITto disable static libraries. The user may still override this default by specifying ‘--enable-static’. The option ‘disable-static’ toLT_INITis a shorthand for this.AM_DISABLE_STATICis a deprecated alias forAC_DISABLE_STATIC.
Change the default behaviour for
LT_INITto enable static libraries. This is the default on all systems where shared libraries have been disabled for some reason, and on most systems where shared libraries have been enabled. If shared libraries are enabled, the user may still override this default by specifying ‘--disable-static’. The option ‘static’ toLT_INITis a shorthand for this.AM_ENABLE_STATICis a deprecated alias forAC_ENABLE_STATIC.
The tests in LT_INIT also recognize the following
environment variables:
The C compiler that will be used by the generated
libtool. If this is not set,LT_INITwill look for gcc or cc.
Compiler flags used to generate standard object files. If this is not set,
LT_INITwill not use any such flags. It affects only the wayLT_INITruns tests, not the producedlibtool.
C preprocessor flags. If this is not set,
LT_INITwill not use any such flags. It affects only the wayLT_INITruns tests, not the producedlibtool.
The system linker to use (if the generated
libtoolrequires one). If this is not set,LT_INITwill 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,LT_INITwill not use any such flags. It affects only the wayLT_INITruns tests, not the producedlibtool.
The libraries to be used by
LT_INITwhen it links a program. If this is not set,LT_INITwill not use any such flags. It affects only the wayLT_INITruns tests, not the producedlibtool.
A command that creates a link of a program, a soft-link if possible, a hard-link otherwise.
LT_INITwill 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.
With 1.3 era libtool, if you wanted to know any details of what
libtool had discovered about your architecture and environment, you
had to run the script with --config and grep through the
results. This idiom was supported up to and including 1.5.x era
libtool, where it was possible to call the generated libtool script
from configure.ac as soon as LT_INIT had
completed. However, one of the features of libtool 1.4 was that the
libtool configuration was migrated out of a separate ltconfig
file, and added to the LT_INIT macro (nee AC_PROG_LIBTOOL),
so the results of the configuration tests were available directly to code in
configure.ac, rendering the call out to the generated libtool
script obsolete.
Starting with libtool 2.0, the multipass generation of the libtool script has been consolidated into a single config.status pass, which happens after all the code in configure.ac has completed. The implication of this is that the libtool script does not exist during execution of code from configure.ac, and so obviously it cannot be called for --config details anymore. If you are upgrading projects that used this idiom to libtool 2.0 or newer, you should replace those calls with direct references to the equivalent Autoconf shell variables that are set by the configure time tests before being passed to config.status for inclusion in the generated libtool script.
By default, the configured libtool script is generated by the call to
AC_OUTPUTcommand, and there is rarely any need to use libtool from configure. However, sometimes it is necessary to run configure time compile and link tests using libtool. You can addLT_OUTPUTto your configure.ac any time afterLT_INITand anyLT_LANGcalls; that done, libtool will be created by a specially generated config.lt file, and available for use in later tests.Also, when
LT_OUTPUTis used, for backwards compatibility with Automake regeneration rules, config.status will call config.lt to regenerate libtool, rather than generating the file itself.
When you invoke the libtoolize program (see Invoking libtoolize), it will tell you where to find a definition of
LT_INIT. If you use Automake, the aclocal program
will automatically add LT_INIT support to your
configure script when it sees the invocation of LT_INIT
in configure.ac.
Because of these changes, and the runtime version compatibility checks
Libtool now executes, we now advise against including a copy of
libtool.m4 (and brethren) in acinclude.m4. Instead,
you should set your project macro directory with
AC_CONFIG_MACRO_DIR. When you libtoolize your
project, a copy of the relevant macro definitions will be placed in
your AC_CONFIG_MACRO_DIR, where aclocal can reference
them directly from aclocal.m4.
While Libtool tries to hide as many platform-specific features as possible, some have to be taken into account when configuring either the Libtool package or a libtoolized package.
LDFLAGS=-Wl,-brtl for the latter style.
AR=/usr/bin/ar LD=/usr/bin/ld NM='/usr/bin/nm -B'.
CONFIG_SHELL=/bin/bash; export $CONFIG_SHELL
$CONFIG_SHELL ./configure [...]
CXX='pgCC --one_instantiation_per_object' and avoid parallel make.
CC='cc -Hnocopyr'.
lt_cv_sys_lib_search_path_spec and
lt_cv_sys_lib_dlsearch_path_spec respectively to the correct search
paths.
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.
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: