Autoconf, Automake, and Libtool
Авторы :
1.1 О чем эта книга
Эта книга - учебник по Autoconf, Automake и Libtool.
GNU-шные мануалы рассматривают каждый из этих инструментов в отдельности .
Нет руководств , которые рассматривают эту работу вместе .
Эти инструменты развиваются , и все это сопровождается небольшим количеством документации .
Например , кто может сказать , почему некоторые Autoconf-макросы нужно оформлять так :
| if test "x$var" = xbar; then
echo yes 1>&5
fi
|
а не так:
| if [ $var = bar ]; then
echo yes 1>&5
fi
|
В силу этих и подобных причин эта книга и написана.
Оригинал можно найти на http://www.andamooka.org/
2.2 The First Configure Programs
By 1992, four different systems had been developed to help with source
code portability:
-
The Metaconfig program, by Larry Wall, Harlan Stenn, and
Raphael Manfredi.
-
The Cygnus `configure' script, by K. Richard Pixley, and the
original GCC `configure' script, by Richard Stallman. These
are quite similar, and the developers communicated regularly. GCC
is the GNU Compiler Collection, formerly the GNU C compiler.
-
The GNU Autoconf package, by David MacKenzie.
-
Imake, part of the X Window system.
These systems all split building a program into two steps: a
configuration step, and a build step. For all the systems, the build
step used the standard Unix make program. The make
program reads a set of rules in a `Makefile', and uses them to
build a program. The configuration step would generate
`Makefile's, and perhaps other files, which would then be used
during the build step.
Metaconfig and Autoconf both use feature tests to
determine the capabilities of the system. They use Bourne shell scripts
(all variants of Unix support the Bourne shell in one form or another)
to run various tests to see what the system can support.
The Cygnus `configure' script and the original GCC
`configure' script are also Bourne shell scripts. They rely on
little configuration files for each system variant, both header files
and `Makefile' fragments. In early versions, the user compiling
the program had to tell the script which type of system the program
should be built for; they were later enhanced with a shell script
written by Per Bothner which determines the system type based on the
standard Unix uname program and other information.
Imake is a portable C program. Imake can be
customized for a particular system, and run as part of building a
package. However, it is more normally distributed with a package,
including all the configuration information needed for supported
systems.
Metaconfig and Autoconf are programs used by program
authors. They produce a shell script which is distributed with the
program's source code. A user who wants to build the program runs the
shell script in order to configure the source code for the particular
system on which it is to be built.
The Cygnus and GCC `configure' scripts, and imake ,
do not have this clear distinction between use by the developer and use
by the user.
The Cygnus and GCC `configure' scripts included features to
support cross development, both to support building a cross-compiler
which compiles code to be run on another system, and to support building
a program using a cross-compiler.
Autoconf, Metaconfig and Imake did not
have these features (they were later added to Autoconf); they
only worked for building a program on the system on which it was to run.
The scripts generated by Metaconfig are interactive by
default: they ask questions of the user as they go along. This permits
them to determine certain characteristics of the system which it is
difficult or impossible to test, such as the behavior of setuid
programs.
The Cygnus and GCC `configure' scripts, and the scripts
generated by autoconf , and the imake program, are
not interactive: they determine everything themselves. When using
Autoconf, the package developer normally writes the script to accept
command line options for features which can not be tested for, or
sometimes requires the user to edit a header file after the
`configure' script has run.
2.3 Configure Development
The Cygnus `configure' script and the original GCC
`configure' script both had to be updated for each new Unix variant
they supported. This meant that packages which used them were
continually out of date as new Unix variants appeared. It was not hard
for the developer to add support for a new system variant; however, it
was not something which package users could easily do themselves.
The same was true of Imake as it was commonly used. While it
was possible for a user to build and configure Imake for a
particular system, it was not commonly done. In practice, packages such
as the X window system which use Imake are shipped with
configuration information detailed for specific Unix variants.
Because Metaconfig and Autoconf used feature tests,
the scripts they generated were often able to work correctly on new Unix
variants without modification. This made them more flexible and easier
to work with over time, and led to the wide adoption of Autoconf.
In 1994, David MacKenzie extended Autoconf to incorporate the features
of the Cygnus `configure' script and the original GCC
`configure' script. This included support for using system
specified header file and makefile fragments, and support for
cross-compilation.
GCC has since been converted to use Autoconf, eliminating the
GCC `configure' script. Most programs which use the Cygnus
`configure' script have also been converted, and no new programs
are being written to use the Cygnus `configure' script.
The metaconfig program is still used today to configure Perl
and a few other programs. imake is still used to configure
the X window system. However, these tools are not generally used for
new packages.
2.4 Automake Development
By 1994, Autoconf was a solid framework for handling the differences
between Unix variants. However, program developers still had to write
large `Makefile.in' files in order to use it. The `configure'
script generated by autoconf would transform the
`Makefile.in' file into a `Makefile' used by the
make program.
A `Makefile.in' file has to describe how to build the program. In
the Imake equivalent of a `Makefile.in', known as an
`Imakefile', it is only necessary to describe which source files
are used to build the program. When Imake generates a
`Makefile', it adds the rules for how to build the program itself.
Later versions of the BSD make program also include
rules for building a program.
Since most programs are built in much the same way, there was a great
deal of duplication in `Makefile.in' files. Also, the GNU
project developed a reasonably complex set of standards for
`Makefile's, and it was easy to get some of the details wrong.
These factors led to the development of Automake. automake ,
like autoconf , is a program run by a developer. The developer
writes files named `Makefile.am'; these use a simpler syntax than
ordinary `Makefile's. automake reads the
`Makefile.am' files and produces `Makefile.in' files. The
idea is that a script generated by autoconf converts these
`Makefile.in' files into `Makefile's.
As with Imake and BSD make , the `Makefile.am'
file need only describe the files used to build a program.
automake automatically adds the necessary rules when it
generates the `Makefile.in' file. automake also adds any
rules required by the GNU `Makefile' standards.
The first version of Automake was written by David MacKenzie in 1994.
It was completely rewritten in 1995 by Tom Tromey.
2.5 Libtool Development
Over time, Unix systems added support for shared libraries.
Conventional libraries, or static libraries, are linked into a program
image. This means that each program which uses a static library
includes some or all of the library in the program binary on disk.
Shared libraries, on the other hand, are a separate file. A program
which uses a shared library does not include a copy of the library; it
only includes the name of the library. Many programs can use a single
shared library.
Using a shared library reduces disk space requirements. Since the
system can generally share a single executable instance of the shared
library among many programs, it also reduces swap space requirements at
run time. Another advantage is that it is possible to fix a bug by
updating the single shared library file on disk, without requiring all
the programs which use the library to be rebuilt.
The first Unix shared library implementation was in System V release 3
from AT&T. The idea was rapidly adopted by other Unix
vendors, appearing in SunOS, HP-UX, AIX, and Digital Unix
among others. Unfortunately, each implementation differed in the
creation and use of shared libraries and in the specific features which
were supported.
Naturally, packages distributed as source code which included libraries
wanted to be able to build their own shared libraries. Several
different implementations were written in the Autoconf/Automake
framework.
In 1996, Gordon Matzigkeit began work on a package known as Libtool.
Libtool is a collection of shell scripts which handle the differences
between shared library generation and use on different systems. It is
closely tied to Automake, although it is possible to use it
independently.
Over time, Libtool has been enhanced to support more Unix variants and
to provide an interface for standardizing shared library features.
3. How to run configure and make
A package constructed using Autoconf will come with a `configure'
script. A user who wants to build and install the package must run this
script in order to prepare their source tree in order to build it on
their particular system. The actual build process is performed using
the make program.
The `configure' script tests system features. For example, it
might test whether the C library defines the time_t data type for
use by the time() C library function. The `configure'
script then makes the results of those tests available to the program
while it is being built.
This chapter explains how to invoke a `configure' script from the
perspective of a user--someone who just wants to take your package and
compile it on their system with a minimum of fuss. It is because
Autoconf works as well as it does that it is usually possible to build a
package on any kind of machine with a simple configure; make
command line. The topics covered in this chapter include how to invoke
configure , the files that configure generates and
the most useful `Makefile' targets--actions that you want
make to perform--that will be available when compiling the
package
3.1 Configuring
A `configure' script takes a large number of command line options.
The set of options can vary from one package to the next, although a
number of basic options are always present. The available options can
be discovered by running `configure' with the `--help'
option. Although many of these options are esoteric, it's worthwhile
knowing of their existence when configuring packages with special
installation requirements. Each option will be briefly described below:
- `--cache-file=file'
- `configure' runs tests on your system to determine the availability
of features (or bugs!). The results of these tests can be stored in a
cache file to speed up subsequent invocations of
configure . The presence of a well primed cache file makes a
big improvement when configuring a complex tree which has
`configure' scripts in each subtree.
- `--help'
- Outputs a help message. Even experienced users of `configure' need
to use `--help' occasionally, as complex projects will include
additional options for per-project configuration. For example,
`configure' in the GCC package allows you to control whether
the GNU assembler will be built and used by GCC in preference
to a vendor's assembler.
- `--no-create'
- One of the primary functions of `configure' is to generate output
files. This option prevents `configure' from generating such
output files. You can think of this as a kind of dry run,
although the cache will still be modified.
- `--quiet'
- `--silent'
- As `configure' runs its tests, it outputs brief messages telling
the user what the script is doing. This was done because
`configure' can be slow. If there was no such output, the user
would be left wondering what is happening. By using this option, you
too can be left wondering!
- `--version'
- Prints the version of Autoconf that was used to generate the
`configure' script.
- `--prefix=prefix'
- The --prefix option is one of the most frequently used. If generated
`Makefile's choose to observe the argument you pass with this
option, it is possible to entirely relocate the architecture-independent
portion of a package when it is installed. For example, when installing
a package like Emacs, the following command line will cause the Emacs
Lisp files to be installed in `/opt/gnu/share':
| $ ./configure --prefix=/opt/gnu
|
It is important to stress that this behavior is dependent on the
generated files making use of this information. For developers writing
these files, Automake simplifies this process a great deal. Automake is
introduced in .
- `--exec-prefix=eprefix'
- Similar to `--prefix', except that it sets the location of
installed files which are architecture-dependent. The compiled
`emacs' binary is such a file. If this option is not given, the
default `exec-prefix' value inserted into generated files is set to
the same values at the `prefix'.
- `--bindir=dir'
- Specifies the location of installed binary files. While there may be
other generated files which are binary in nature, binary files here are
defined to be programs that are run directly by users.
- `--sbindir=dir'
- Specifies the location of installed superuser binary files. These are
programs which are usually only run by the superuser.
- `--libexecdir=dir'
- Specifies the location of installed executable support files.
Contrasted with `binary files', these files are never run directly by
users, but may be executed by the binary files mentioned above.
- `--datadir=dir'
- Specifies the location of generic data files.
- `--sysconfdir=dir'
- Specifies the location of read-only data used on a single machine.
- `--sharedstatedir=dir'
- Specifies the location of data which may be modified, and which may be
shared across several machines.
- `--localstatedir=dir'
- Specifies the location of data which may be modified, but which is
specific to a single machine.
- `--libdir=dir'
- Specifies where object code library should be installed.
- `--includedir=dir'
- Specifies where C header files should be installed. Header files for
other languages such as C++ may be installed here also.
- `--oldincludedir=dir'
- Specifies where C header files should be installed for compilers other
than GCC.
- `--infodir=dir'
- Specifies where Info format documentation files should be installed.
Info is the documentation format used by the GNU project.
- `--mandir=dir'
- Specifies where manual pages should be installed.
- `--srcdir=dir'
- This option does not affect installation. Instead, it tells
`configure' where the source files may be found. It is normally
not necessary to specify this, since the configure script is normally in
the same directory as the source files.
- `--program-prefix=prefix'
- Specifies a prefix which should be added to the name of a program when
installing it. For example, using `--program-prefix=g' when
configuring a program normally named `tar' will cause the installed
program to be named `gtar' instead. As with the other installation
options, this `configure' option only works if it is utilized by
the `Makefile.in' file.
- `--program-suffix=suffix'
- Specifies a suffix which should be appended to the name of a program
when installing it.
- `--program-transform-name=program'
- Here, program is a
sed script. When a program is
installed, its name will be run through `sed -e script' to
produce the installed name.
- `--build=build'
- Specifies the type of system on which the package will be built. If
not specified, the default will be the same configuration name as the host.
- `--host=host'
- Specifies the type of system on which the package will run--or be
hosted. If not specified, the host triplet is determined by executing
`config.guess'.
- `--target=target'
- Specifies the type of system which the package is to be targeted to.
This makes the most sense in the context of programming language tools
like compilers and assemblers. If not specified, the default will be
the same configuration name as the host.
- `--disable-feature'
- Some packages may choose to provide compile-time configurability for
large-scale options such as using the Kerberos authentication system or
an experimental compiler optimization pass. If the default is to
provide such features, they may be disabled with
`--disable-feature', where feature is the feature's
designated name. For example:
| $ ./configure --disable-gui
|
- `--enable-feature[=arg]'
- Conversely, some packages may provide features which are disabled by
default. To enable them, use `--enable-feature', where
feature is the feature's designated name. A feature may accept an
optional argument. For example:
| $ ./configure --enable-buffers=128
|
Using `--enable-feature=no' is synonymous with
`--disable-feature', described above.
- `--with-package[=arg]'
- In the free software community, there is a healthy tendency to reuse
existing packages and libraries where possible. At the time when a
source tree is configured by `configure', it is possible to
provide hints about other installed packages. For example, the BLT
widget toolkit relies on Tcl and Tk. To configure BLT, it may be
necessary to give `configure' some hints about where you have
installed Tcl and Tk:
| $ ./configure --with-tcl=/usr/local --with-tk=/usr/local
|
Using `--with-package=no' is synonymous with
`--without-package' which is described below.
- `--without-package'
- Sometimes you may not want your package to inter-operate with some
pre-existing package installed on your system. For example, you might
not want your new compiler to use GNU
ld . You can prevent
this by using an option such as:
| $ ./configure --without-gnu-ld
|
- `--x-includes=dir'
- This option is really a specific instance of a `--with-package'
option. At the time when Autoconf was initially being developed, it was
common to use `configure' to build programs to run on the X Window
System as an alternative to Imake. The `--x-includes' option
provides a way to guide the configure script to the directory containing
the X11 header files.
- `--x-libraries=dir'
- Similarly, the --x-libraries option provides a way to guide
`configure' to the directory containing the X11 libraries.
It is unnecessary, and often undesirable, to run `configure' from
within the source tree. Instead, a well-written `Makefile'
generated by `configure' will be able to build packages whose
source files reside in another tree. The advantages of building derived
files in a separate tree to the source code are fairly obvious: the
derived files, such as object files, would clutter the source tree.
This would also make it impossible to build those same object files on a
different system or with a different configuration. Instead, it is
recommended to use three trees: a source tree, a build tree and an
install tree. Here is a closing example of how to build the
GNU malloc package in this way:
|
$ gtar zxf mmalloc-1.0.tar.gz
$ mkdir build && cd build
$ ../mmalloc-1.0/configure
creating cache ./config.cache
checking for gcc... gcc
checking whether the C compiler (gcc ) works... yes
checking whether the C compiler (gcc ) is a cross-compiler... no
checking whether we are using GNU C... yes
checking whether gcc accepts -g... yes
checking for a BSD compatible install... /usr/bin/install -c
checking host system type... i586-pc-linux-gnu
checking build system type... i586-pc-linux-gnu
checking for ar... ar
checking for ranlib... ranlib
checking how to run the C preprocessor... gcc -E
checking for unistd.h... yes
checking for getpagesize... yes
checking for working mmap... yes
checking for limits.h... yes
checking for stddef.h... yes
updating cache ../config.cache
creating ./config.status
|
Now that this build tree is configured, it is possible to go on and
build the package and install it into the default location of
`/usr/local':
3.2 Files generated by configure
After you have invoked `configure', you will discover a number of
generated files in your build tree. The build directory structure
created by `configure' and the number of files will vary from
package to package. Each of the generated files are described below and
their relationships are shown in C. Generated File Dependencies:
- `config.cache'
- `configure' can cache the results of system tests that have been
performed to speed up subsequent tests. This file contains the cache
data and is a plain text file that can be hand-modified or removed if
desired.
- `config.log'
- As `configure' runs, it outputs a message describing each test it
performs and the result of each test. There is substantially more
output produced by the shell and utilities that `configure'
invokes, but it is hidden from the user to keep the output
understandable. The output is instead redirected to
`config.log'. This file is the first place to look when
`configure' goes hay-wire or a test produces a nonsense result. A
common scenario is that `configure', when run on a Solaris system,
will tell you that it was unable to find a working C compiler. An
examination of `config.log' will show that Solaris' default
`/usr/ucb/cc' is a program that informs the user that the optional
C compiler is not installed.
- `config.status'
- `configure' generates a shell script called `config.status'
that may be used to recreate the current configuration. That is, all
generated files will be regenerated. This script can also be used to
re-run `configure' if the `--recheck' option is given.
- `config.h'
- Many packages that use `configure' are written in C or C++. Some
of the tests that `configure' runs involve examining variability in
the C and C++ programming languages and implementations thereof. So
that source code can programmatically deal with these differences,
#define preprocessor directives can be optionally placed in a
config header, usually called `config.h', as
`configure' runs. Source files may then include the
`config.h' file and act accordingly:
|
#if HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
#if HAVE_UNISTD_H
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
|
We recommend always using a config header.
- `Makefile'
- One of the common functions of `configure' is to generate
`Makefile's and other files. As it has been stressed, a
`Makefile' is just a file often generated by `configure' from
a corresponding input file (usually called `Makefile.in'). The
following section will describe how you can use
make to
process this `Makefile'. There are other cases where generating
files in this way can be helpful. For instance, a Java developer might
wish to make use of a `defs.java' file generated from
`defs.java.in'.
3.3 The most useful Makefile targets
By now `configure' has generated the output files such as a
`Makefile'. Most projects include a `Makefile' with a basic
set of well-known targets
target is a name of a task that you want make to perform --
usually it is to build all of the programs belonging to your package
(commonly known as the all target). From your build directory,
the following commands are likely to work for a configured package:
make all
- Builds all derived files sufficient to declare the package built.
make check
- Runs any self-tests that the package may have.
make install
- Installs the package in a predetermined location.
make clean
- Removes all derived files.
There are other less commonly used targets which are likely to be
recognized, particularly if the package includes a `Makefile' which
conforms to the GNU `Makefile' standard or is generated by
automake . You may wish to inspect the generated
`Makefile' to see what other targets have been included.
3.4 Configuration Names
The GNU Autotools name all types of computer systems using a
configuration name. This is a name for the system in a
standardized format.
Some example configuration names are `sparc-sun-solaris2.7',
`i586-pc-linux-gnu', or `i386-pc-cygwin'.
All configuration names used to have three parts, and in some
documentation they are still called configuration triplets. A
three part configuration name is
cpu-manufacturer-operating_system. Currently
configuration names are permitted to have four parts on systems which
distinguish the kernel and the operating system, such as GNU/Linux. In
these cases, the configuration name is
cpu-manufacturer-kernel-operating_system.
When using a configuration name in an option to a tool such as
configure , it is normally not necessary to specify an entire
name. In particular, the middle field (manufacturer, described
below) is often omitted, leading to strings such as `i386-linux' or
`sparc-sunos'. The shell script `config.sub' is used to
translate these shortened strings into the canonical form.
On most Unix variants, the shell script `config.guess' will print
the correct configuration name for the system it is run on. It does
this by running the standard `uname' program, and by examining
other characteristics of the system. On some systems,
`config.guess' requires a working C compiler or an assembler.
Because `config.guess' can normally determine the configuration
name for a machine, it is only necessary for a user or developer to
specify a configuration name in unusual cases, such as when building a
cross-compiler.
Here is a description of each field in a configuration name:
- cpu
- The type of processor used on the system. This is typically something
like `i386' or `sparc'. More specific variants are used as
well, such as `mipsel' to indicate a little endian MIPS processor.
- manufacturer
- A somewhat freeform field which indicates the manufacturer of the
system. This is often simply `unknown'. Other common strings are
`pc' for an IBM PC compatible system, or the name of a workstation
vendor, such as `sun'.
- operating_system
- The name of the operating system which is run on the system. This will
be something like `solaris2.5' or `winnt4.0'. There is no
particular restriction on the version number, and strings like
`aix4.1.4.0' are seen.
Configuration names may be used to describe all sorts of systems,
including embedded systems which do not run any operating system. In
this case, the field is normally used to indicate the object file
format, such as `elf' or `coff'.
- kernel
- This is used mainly for GNU/Linux systems. A typical GNU/Linux
configuration name is `i586-pc-linux-gnulibc1'. In this case the
kernel, `linux', is separated from the operating system,
`gnulibc1'.
`configure' allows fine control over the format of binary files. It
is not necessary to build a package for a given kind of machine on that
machine natively--instead, a cross-compiler can be used. Moreover, if
the package you are trying to build is itself capable of operating in a
cross configuration, then the build system need not be the same kind of
machine used to host the cross-configured package once the package is
built! Consider some examples:
- Compiling a simple package for a GNU/Linux system.
- host = build = target = `i586-pc-linux-gnu'
- Cross-compiling a package on a GNU/Linux system that is intended to
- run on an IBM AIX machine:
build = `i586-pc-linux-gnu', host = target =
`rs6000-ibm-aix3.2'
- Building a Solaris-hosted MIPS-ECOFF cross-compiler on a GNU/Linux
- system.
build = `i586-pc-linux-gnu', host =
`sparc-sun-solaris2.4', target = `mips-idt-ecoff'
|