Introducing GNU Libtool

Libtool takes care of all the peculiarities of creating, linking and loading shared and static libraries across a great number of platforms, providing a uniform command line interface to the developer. By using Libtool to manage your project libraries, you only need to concern yourself with Libtool's interface: when someone else builds your project on a platform with a different library architecture, Libtool invokes that platform's compiler and linker with the correct environment and command line switches. It will install libraries and library using binaries according to the conventions of the host platform, and follows that platform's rules for library versioning and library interdependencies.

Libtool empowers you to treat a library as an implementation of a well defined interface of your choosing. This Libtool library may be manifest as a collection of compiler objects, a static ar archive, or a position independent runtime loadable object. By definition, native libraries are fully supported by Libtool since they are an implementation detail of the Libtool library abstraction. It's just that until Libtool achieves complete world domination, you might need to bear in mind what is going on behind the command line interface when you first add Libtool support to your project.
 The sheer number of uses of the word `library' in this
book could easily be very confusing.  In this chapter and throughout
the rest of the book, I will refer to various kinds of low level
libraries as `native', that is, libraries provided by the host
architecture.  The kind of library built by Libtool, we call a `Libtool
library' - this encompasses both the shared and static native
components of the implementation of the named library.  The high level
.la file produced by Libtool is called the
`pseudo-library' - it is not a library in its own right, but is treated
as if it were from outside the Libtool interface.  Additionally, when I
talk about static libraries in the context of
Libtool, I am referring to a Libtool library which has no shared
archive component.  On  the other hand, when I talk about static
archives in the context of Libtool, I am referring
to the static component of a Libtool library.  The distinction is
subtle, but important.

Many developers use Libtool as a black box which requires adding a few macros to configure.in and tweaking a project's Makefile.am. The next chapter addresses that school of thought in more detail. In this chapter I will talk a little about the inner workings of Libtool, and show you how it can be used directly from your shell prompt - how to build various kinds of library, and how those libraries can be used by an application. Before you can do any of this, you need to create a libtool script that is tailored to the platform you are using it from.

Creating libtool

When you install a distribution of Libtool on your development machine, a host specific libtool program is installed. The examples in the rest of this chapter use this installed instance of libtool.

When you start to use Libtool in the build process of your own projects, you shouldn't require that libtool be installed on the user's machine, particularly since they may have a different libtool version to the one used to develop your project. Instead, distribute some of the files installed by the Libtool distribution along with your project, and custom build a libtool script on the user's machine before invoking ./libtool to build any objects. If you use Aotoconf and Automake, these details are taken care of automatically (see the chapter called Using GNU Libtool with configure.in and Makefile.am). Otherwise you should copy the following files from your own Libtool installation into the source tree of your own project:
     $ ls /usr/local/share/libtool
     config.guess   config.sub   libltdl   ltconfig   ltmain.in     $ cp /usr/local/share/libtool/config.* /usr/local/share/libtool/lt* .
     $ ls
     config.guess   config.sub   ltconfig   ltmain.in

You must then arrange for your project build process to create an instance of libtool on the user's machine, so that it is dependent on their target system and not your development machine. The creation process requires the four files you just added to your project. Let's create a libtool instance by hand, so that you can see what is involved:
     $ ./config.guess
     hppa1.1-hp-hpux10.20     $ ./ltconfig --disable-static --with-gcc ./ltmain.sh hppa1.1-hp-hpux10.20
     checking host system type... hppa1.1-hp-hpux10.20
     checking build system type... hppa1.1-hp-hpux10.20
     checking whether ln -s works... yes
     checking for ranlib... ranlib
     checking for BSD-compatible nm... /usr/bin/nm -p
     checking for strip... strip
     checking for gcc... gcc
     checking whether we are using GNU C... yes
     checking for objdir... .libs
     checking for object suffix... o
     checking for executable suffix... no
     checking for gcc option to produce PIC... -fPIC
     checking if gcc PIC flag -fPIC works... yes
     checking if gcc static flag -static works... yes
     checking if gcc supports -c -o file.o... yes
     checking if gcc supports -c -o file.lo... yes
     checking if gcc supports -fno-rtti -fno-exceptions ... no
     checking for ld used by GCC... /opt/gcc-lib/hp821/2.7.0/ld
     checking if the linker (/opt/gcc-lib/hp821/2.7.0/ld) is GNU ld... no
     checking whether the linker (/opt/gcc-lib/hp821/2.7.0/ld) supports \
     shared libraries... yes
     checking how to hardcode library paths into programs... relink
     checking whether stripping libraries is possible... yes
     checking for /opt/gcc-lib/hp821/2.7.0/ld option to reload object \
     files... -r
     checking dynamic linker characteristics... hpux10.20 dld.sl
     checking command to parse /usr/bin/nm -p output... ok
     checking if libtool supports shared libraries... yes
     checking whether to build shared libraries... yes
     checking whether to build static libraries... yes
     creating libtool     $ ls
     config.guess   config.sub   ltconfig
     config.log     libtool      ltmain.sh     $ ./libtool --version
     ltmain.sh (GNU libtool) 1.3c (1.629 1999/11/02 12:33:04)

The examples in this chapter are all performed on a HP-UX system, but the principles depicted are representative of any of the platforms to which Libtool has been ported (see the chapter called PLATFORMS).

Often you don't need to specify any options, and if you omit the configuration triplet (see the section called Configuration Names in the chapter called How to run configure and make), ltconfig will run config.guess itself. There are several options you can specify which affect the generated libtool, See Invoking ltconfig: (Libtool)Configuring Libtool. Unless your project has special requirements, you can usually use the simplified:
     $ ./ltconfig ./ltmain.sh
      

With the current release of Libtool, you must be careful that $CC is set to the same value when you call ltconfig as when you invoke the libtool it generates, otherwise libtool will use the compiler specified in $CC currently, but with the semantics probed by ltconfig for the compiler specified in $CC at the time it was executed.