Go to the first, previous, next, last section, table of contents.


5 Integrating libtool with your own packages

This chapter describes how to integrate libtool with your packages so that your users can install hassle-free shared libraries.

5.1 Writing `Makefile' rules for libtool

Libtool is fully integrated with Automake (see section `Introduction' in The Automake Manual), 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:

  1. Download Automake (version 1.2 or later) from your nearest GNU mirror, install it, and start using it.
  2. Learn how to write `Makefile' rules by hand. They're sometimes complex, but if you're clever enough to write rules for compiling your old libraries, then you should be able to figure out new rules for libtool libraries (hint: examine the `Makefile.in' in the `demo' subdirectory of the libtool distribution... note especially that it was automatically generated from the `Makefile.am' by Automake).

5.2 Using Automake with libtool

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

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 section 6 Library interface versions) 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, so you should not specify it.

See section `The Automake Manual' in The Automake Manual, for more information.

5.3 Configuring libtool

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 section 5.4 Including libtool with your package), 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 has its own equivalent to the configure script, ltconfig.

5.3.1 Invoking ltconfig

ltconfig runs a series of configuration tests, then creates a system-specific libtool in the current directory. The ltconfig program has the following synopsis:

ltconfig [option]... ltmain [host]

and accepts the following options:

`--debug'
Dump a trace of shell script execution to standard output. This produces a lot of output, so you may wish to pipe it to more(1) or redirect to a file.
`--disable-shared'
Create a libtool that only builds static libraries.
`--disable-static'
Create a libtool that builds only shared libraries if they are available. If only static libraries can be built, then this flag has no effect.
`--help'
Display a help message and exit.
`--no-verify'
Do not use config.sub to verify that host is a valid canonical host system name.
`--output=file'
`-o file'
Instead of creating a libtool script called libtool, create one called file. This can be useful if you want to create libtool scripts for cross-compilers, or you want to have more than one libtool in the same directory.
`--quiet'
`--silent'
Do not print informational messages when running configuration tests.
`--srcdir=dir'
Look for config.guess and config.sub in dir.
`--version'
Print ltconfig version information and exit.
`--with-gcc'
Assume that the GNU C compiler will be used when invoking the created libtool to compile and link object files.

ltmain is the ltmain.sh shell script fragment that provides the basic libtool functionality (see section 5.4 Including libtool with your package).

host is the canonical host system name, which by default is guessed by running config.guess.

ltconfig also recognizes the following environment variables:

Variable: CC
The C compiler that will be used by the generated libtool.

Variable: CFLAGS
Compiler flags used to generate standard object files.

Variable: CPPFLAGS
C preprocessor flags.

Variable: LD
The system linker to use (if the generated libtool requires one).

Variable: RANLIB
Program to use rather than checking for ranlib.

5.3.2 Using ltconfig

Here is a simple example of using ltconfig to configure libtool on a NetBSD/i386 1.2 system:

burger$ ./ltconfig ltmain.sh
checking host system type... i386-unknown-netbsd1.2
checking for ranlib... ranlib
checking for gcc... gcc
checking whether we are using GNU C... yes
checking for gcc option to produce PIC... -fPIC -DPIC
checking for gcc option to statically link programs... -static
checking if ld is GNU ld... no
checking if ld supports shared libraries... yes
checking dynamic linker characteristics... netbsd1.2 ld.so
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
creating libtool
burger$

This example shows how to configure libtool for cross-compiling to a i486 GNU/Hurd 0.1 system (assuming compiler tools reside in `/local/i486-gnu/bin'):

burger$ export PATH=/local/i486-gnu/bin:$PATH
burger$ ./ltconfig ltmain.sh i486-gnu0.1
checking host system type... i486-unknown-gnu0.1
checking for ranlib... ranlib
checking for gcc... gcc
checking whether we are using GNU C... yes
checking for gcc option to produce PIC... -fPIC -DPIC
checking for gcc option to statically link programs... -static
checking if ld is GNU ld... yes
checking if GNU ld supports shared libraries... yes
checking dynamic linker characteristics... gnu0.1 ld.so
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
creating libtool
burger$

5.3.3 The AM_PROG_LIBTOOL macro

If you are using GNU Autoconf (or Automake), you should add a call to AM_PROG_LIBTOOL to your `configure.in' file. This macro offers seamless integration between the configure script and ltconfig:

Macro: AM_PROG_LIBTOOL
Add support for the `--enable-shared' and `--disable-shared' configure flags. Invoke ltconfig with the correct arguments to configure the package (see section 5.3.1 Invoking ltconfig).(3)

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 AM_DISABLE_SHARED or AM_DISABLE_STATIC macros:

# Turn off shared libraries during beta-testing, since they
# make the build process take too long.
AM_DISABLE_SHARED
AM_PROG_LIBTOOL

The user may specify modified forms of both the `--enable-shared' and `--enable-static' flags 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 configure scripts as follows:

trick$ ./configure --enable-shared=bfd,gdb

In general, specifying `--enable-shared=pkgs' is the same as specifying `--enable-shared' to every package named in the comma-separated pkgs list, and `--disable-shared' to every other package. The `--enable-static=pkgs' flag behaves similarly, but it uses `--enable-static' and `--disable-static'.

The package name `default' matches any packages which have not set their name in the PACKAGE environment variable.

Macro: AM_DISABLE_SHARED
Change the default behaviour for AM_PROG_LIBTOOL to disable shared libraries. The user may still override this default by specifying `--enable-shared'.

Macro: AM_DISABLE_STATIC
Change the default behaviour for AM_PROG_LIBTOOL to disable static libraries. The user may still override this default by specifying `--enable-static'.

When you invoke the libtoolize program (see section 5.4.1 Invoking libtoolize), it will tell you where to find a definition of AM_PROG_LIBTOOL. If you use Automake, the aclocal program will automatically add AM_PROG_LIBTOOL support to your configure script.

5.4 Including libtool with your package

In order to use libtool, you need to include the following files with your package:

`config.guess'
Attempt to guess a canonical system name.
`config.sub'
Canonical system name validation subroutine script.
`ltconfig'
Generate a libtool script for a given system.
`ltmain.sh'
A generic script implementing basic libtool functionality.

Note that the libtool script itself should not be included with your package. See section 5.3 Configuring libtool.

You should use the libtoolize program, rather than manually copying these files into your package.

5.4.1 Invoking 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:

`--automake'
Work silently, and assume that Automake libtool support is used. `libtoolize --automake' is used by Automake to add libtool files to your package, when AM_PROG_LIBTOOL appears in your `configure.in'.
`--copy'
`-c'
Copy files from the libtool data directory rather than creating symlinks.
`--debug'
Dump a trace of shell script execution to standard output. This produces a lot of output, so you may wish to pipe it to more(1) or redirect to a file.
`--dry-run'
`-n'
Don't run any commands that modify the file system, just print them out.
`--force'
`-f'
Replace existing libtool files. By default, libtoolize won't overwrite existing files.
`--help'
Display a help message and exit.
`--version'
Print libtoolize version information and exit.

If libtoolize detects an explicit call to AC_CONFIG_AUX_DIR (see section `The Autoconf Manual' in 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.

5.4.2 Autoconf `.o' macros

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:

Variable: LTALLOCA
Substituted by AC_FUNC_ALLOCA (see section `The Autoconf Manual' in The Autoconf Manual). Is either empty, or contains `alloca.lo'.

Variable: LTLIBOBJS
Substituted by AC_REPLACE_FUNCS (see section `The Autoconf Manual' in The Autoconf Manual), and a few other functions.

Unfortunately, the most recent version of Autoconf (2.12, 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/\.o/.lo/g'`
AC_SUBST(LTLIBOBJS)
LTALLOCA=`echo "$ALLOCA" | sed 's/\.o/.lo/g'`
AC_SUBST(LTALLOCA)
AC_OUTPUT(...)

5.5 Static-only libraries

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 AM_PROG_LIBTOOL by using the AM_DISABLE_SHARED Autoconf macro (see section 5.3.3 The AM_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 GIMP(4) 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'.


Go to the first, previous, next, last section, table of contents.