Using GNU Libtool with configure.in and Makefile.am

Although Libtool is usable by itself, either from the command line or from a non-make driven build system, it is also tightly integrated into Autoconf and Automake. This chapter discusses how to use Libtool with Autoconf and Automake and explains how to set up the files you write (Makefile.am and configure.in) to take advantage of libtool. For a more in depth discussion of the workings of Libtool, particularly its command line interface, See the chapter called Introducing GNU Libtool. Using libtool for dynamic runtime loading is described in See the chapter called Using GNU libltdl.

Using libtool to build the libraries in a project, requires declaring your use of libtool inside the project's configure.in and adding the Libtool support scripts to the distribution. You will also need to amend the build rules in either Makefile.am or Makefile.in, depending on whether you are using Automake.

Integration with configure.in

Declaring your use of libtool in the project's configure.in is a simple matter of adding the AC_PROG_LIBTOOL [1] somewhere near the top of the file. I always put it immediately after the other AC_PROG_... macros. If you are converting an old project to use libtool, then you will also need to remove any calls to AC_PROG_RANLIB. Since Libtool will be handling all of the libraries, it will decide whether or not to call ranlib as appropriate for the build environment.
 The code generated by
AC_PROG_LIBTOOL relies on the shell variable
$top_builddir to hold the relative path to the
directory which contains the configure script.  If
you are using Automake, $top_builddir is set in the
environment by the generated Makefile.  If you use
Autoconf without  Automake then you must ensure that
$top_builddir is set before the call to
AC_PROG_LIBTOOL in configure.in.     Adding the following code to configure.in is
often sufficient:
          
          for top_builddir in . .. ../.. $ac_auxdir $ac_auxdir/..; do
            test -f $top_builddir/configure && break
          done     

Having made these changes to add libtool support to your project, you will need to regenerate the aclocal.m4 file to pick up the macro definitions required for AC_PROG_LIBTOOL, and then rebuild your configure script with these new definitions in place. After you have done that, there will be some new options available from configure:
     $ aclocal
     $ autoconf
     $ ./configure --help
     ...
     --enable and --with options recognized:
       --enable-shared[=PKGS]  build shared libraries [yes]
       --enable-static[=PKGS]  build static libraries [yes]
       --enable-fast-install[=PKGS]  optimize for fast installation [yes]
       --with-gnu-ld           assume the C compiler uses GNU ld [no]
       --disable-libtool-lock  avoid locking (might break parallel builds)
       --with-pic              try to use only PIC/non-PIC objects [both]

These new options allow the end user of your project some control over how they want to build the project's libraries. The opposites of each of these switches are also accepted, even though they are not listed by configure --help. You can equally pass, --disable-fast-install or --without-gnu-ld for example.

Extra Configure Options

What follows is a list that describes the more commonly used options that are automatically added to configure, by virtue of using AC_PROG_LIBTOOL in your configure.in. The Libtool Manual distributed with Libtool releases always contains the most up to date information about libtool options:

--enable-shared, --enable-static

More often invoked as --disable-shared or equivalently --enable-shared=no these switches determine whether libtool should build shared and/or static libraries in this package. If the installer is short of disk space, they might like to build entirely without static archives. To do this they would use:
          $ ./configure --disable-static
           

Sometimes it is desirable to configure several related packages with the same command line. From a scheduled build script or where subpackages with their own configure scripts are present, for example. The --enable-shared and --enable-static switches also accept a list of package names, causing the option to be applied to packages whose name is listed, and the opposite to be applied to those not listed.

By specifying:
          $ ./configure --enable-static=libsnprintfv,autoopts
           

libtool would pass --enable-static to only the packages named libsnprintfv and autoopts in the current tree. Any other packages configured would effectively be passed --disable-static. Note that this doesn't necessarily mean that the packages must honour these options. Enabling static libraries for a package which consists of only dynamic modules makes no sense, and the package author would probably have decided to ignore such requests, See the section called Extra Macros for Libtool.

--enable-fast-install

On some machines, libtool has to relink executables when they are installed, See the section called Installing an Executable in the chapter called Introducing GNU Libtool. Normally, when an end user builds your package, they will probably type:
          $ ./configure
          $ make
          $ make install
           

libtool will build executables suitable for copying into their respective installation destinations, obviating the need for relinking them on those hosts which would have required it. Whenever libtool links an executable which uses shared libraries, it also creates a wrapper script which ensures that the environment is correct for loading the correct libraries, See the section called Executing Uninstalled Binaries in the chapter called Introducing GNU Libtool. On those hosts which require it, the wrapper script will also relink the executable in the build tree if you attempt to run it from there before installation.

Sometimes this behaviour is not what you want, particularly if you are developing the package and not installing between test compilations. By passing --disable-fast-install, the default behaviour is reversed; executables will be built so that they can be run from the build tree without relinking, but during installation they may be relinked.

You can pass a list of executables as the argument to --enable-fast-install to determine which set of executables will not be relinked at installation time (on the hosts that require it). By specifying:
          $ ./configure --enable-fast-install=autogen
           

The autogen executable will be linked for fast installation (without being relinked), and any other executables in the build tree will be linked for fast execution from their build location. This is useful if the remaining executables are for testing only, and will never be installed.

Most machines do not require that executables be relinked in this way, and in these cases libtool will link each executable once only, no matter whether --disable-fast-install is used.

--with-gnu-ld

This option is used to inform libtool that the C compiler is using GNU ld as its linker. It is more often used in the opposite sense when both gcc and GNU ld are installed, but gcc was built to use the native linker. libtool will probe the system for GNU ld, and assume that it is used by gcc if found, unless --without-gnu-ld is passed to configure.

--disable-libtool-lock

In normal operation, libtool will build two objects for every source file in a package, one PIC [2] and one non-PIC. With gcc and some other compilers, libtool can specify a different output location for the PIC object:
          $ libtool gcc -c shell.c
          gcc -c -pic -DPIC shell.c -o .libs/shell.lo
          gcc -c foo.c -o shell.o >/dev/null 2>&1     

When using a compiler that doesn't accept both -o and -c in the same command, libtool must compile first the PIC and then the non-PIC object to the same destination file and then move the PIC object before compiling the non-PIC object. This would be a problem for parallel builds, since one file might overwrite the other. libtool uses a simple shell locking mechanism to avoid this eventuality.

If you find yourself building in an environment that has such a compiler, and not using parallel make, then the locking mechanism can be safely turned off by using --disable-libtool-lock to gain a little extra speed in the overall compilation.

--with-pic

In normal operation, Libtool will build shared libraries from PIC objects and static archives from non-PIC objects, except where one or the other is not provided by the target host. By specifying --with-pic you are asking libtool to build static archives from PIC objects, and similarly by specifying --without-pic you are asking libtool to build shared libraries from non-PIC objects.

libtool will only honour this flag where it will produce a working library, otherwise it reverts to the default.

Extra Macros for Libtool

There are several macros which can be added to configure.in which will change the default behaviour of libtool. If they are used they must appear before the call to the AC_PROG_LIBTOOL macro. Note that these macros only change the default behaviour, and options passed in to configure on the command line will always override the defaults. The most up to date information about these macros is available from the Libtool Manual.

AC_DISABLE_FAST_INSTALL

This macro tells libtool that on platforms which require relinking at install time, it should build executables so that they can be run from the build tree at the expense of relinking during installation, as if --disable-fast-install had been passed on the command line.

AC_DISABLE_SHARED, AC_DISABLE_STATIC

These macros tell libtool to not try and build either shared or static libraries respectively. libtool will always try to build something however, so even if you turn off static library building in configure.in, building your package for a target host without shared library support will fallback to building static archives.

The time spent waiting for builds during development can be reduced a little by including these macros temporarily. Don't forget to remove them before you release the project though!

In addition to the macros provided with AC_PROG_LIBTOOL, there are a few shell variables that you may need to set yourself, depending on the structure of your project:

LTLIBOBJS

If your project uses the AC_REPLACE_FUNCS macro, or any of the other macros which add object names to the LIBOBJS variable, you will also need to provide an equivalent LTLIBOBJS definition. At the moment, you must do it manually, but needing to do that is considered to be a bug and will fixed in a future release of Autoconf. The manual generation of LTLIBOBJS is a simple matter of replacing the names of the objects mentioned in LIBOBJS with equivalent .lo suffixed Libtool object names. The easiest way to do this is to add the following snippet to your configure.in near the end, just before the call to AC_OUTPUT.
          Xsed="sed -e s/^X//"
          LTLIBOBJS=`echo X"$LIBOBJS"|\
                     [$Xsed -e "s,\.[^.]* ,.lo ,g;s,\.[^.]*$,.lo,"]`
          AC_SUBST(LTLIBOBJS)     

The Xsed is not usually necessary, though it can prevent problems with the echo command in the event that one of the LIBOBJS files begins with a - character. It is also a good habit to write shell code like this, as it will avoid problems in your programs.

LTALLOCA

If your project uses the AC_FUNC_ALLOCA macro, you will need to provide a definition of LTALLOCA equivalent to the ALLOCA value provided by the macro.
          Xsed="sed -e s/^X//"
          LTALLOCA=`echo X"$ALLOCA"|[$Xsed -e "s,\.$[^.]*,.lo,g"]`
          AC_SUBST(LTALLOCA)     

Obviously you don't need to redefine Xsed if you already use it for LTLIBOBJS above.

LIBTOOL_DEPS

To help you write make rules for automatic updating of the Libtool configuration files, you can use the value of LIBTOOL_DEPS after the call to AC_PROG_LIBTOOL:
          AC_PROG_LIBTOOL
          AC_SUBST(LIBTOOL_DEPS)     

Then add the following to the top level Makefile.in:
          libtool: @LIBTOOL_DEPS@
                  cd $(srcdir) && \
                    $(SHELL) ./config.status --recheck     

If you are using automake in your project, it will generate equivalent rules automatically. You don't need to use this except in circumstances where you want to use libtool and autoconf, but not automake.

Notes

[1]

@samp{AM_PROG_LIBTOOL} if you have an older @command{automake} or @command{libtool} installation.

[2]

Position Independent Code -- suitable for shared libraries which might be loaded to different addresses when linked by the runtime loader.