Noeud:Simple Uses of Autoconf, Noeud « Next »:, Noeud « Previous »:What is Autoconf, Noeud « Up »:Autoconf



Simple Uses of Autoconf

Autoconf is merely an M4 library, a set of macros specialized in testing for libraries, programs and so on. Since pure M4 is a bit too low level and since Autoconf aims at producing Bourne shell scripts, it is on top of M4sh, itself atop M4sugar ((FIXME: Ref.)). As a consequence it has the same syntax: # introduces comments, the square brackets quote etc. Similarly, you can use autom4te --language=autoconf to expand Autoconf source files, but for historical reasons and because of the momentum of tradition, everybody runs autoconf.

Any Autoconf script must start with AC_INIT:

AC_INIT (package, version, [bug-report-address]) Macro

Process any command-line arguments and perform various initializations and verifications. Set the name of the package and its version. The optional argument bug-report-address should be the email to which users should send bug reports.

The simplest Autoconf script is therefore:

     $ cat auditor.ac
     AC_INIT(Auditor, 1.0)
     $ autom4te -l autoconf -o auditor auditor.ac
     $ ./auditor
     $ ./auditor --version
     Auditor configure 1.0
     generated by GNU Autoconf 2.52g
     
     Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
     Free Software Foundation, Inc.
     This configure script is free software; the Free Software Foundation
     gives unlimited permission to copy, distribute and modify it.
     

Most packages contain C sources, and therefore need a compiler; AC_PROG_CC looks for it:

     $ cat auditor.ac
     AC_INIT(Auditor, 1.1)
     AC_PROG_CC
     $ autom4te -l autoconf -o auditor auditor.ac
     $ ./auditor
     checking for gcc... gcc
     checking for C compiler default output... a.out
     checking whether the C compiler works... yes
     checking whether we are cross compiling... no
     checking for executable suffix...
     checking for object suffix... o
     checking whether we are using the GNU C compiler... yes
     checking whether gcc accepts -g... yes
     

It does work, but how can you exploit the results of this system audit? In Autoconf, this is always performed by the creation of new files out of templates. For instance, once your system fully examined, all the Makefile.in templates will be instantiated for your system into the Makefile. This is called configuring the package, and it is a mandatory tradition to name your configuring script configure, created by autoconf from configure.ac.

Transforming a simple auditor into a configuring script requires two additional macro invocations:

AC_CONFIG_FILES (file..., [command]) Macro

Declare file must be created by copying an input file (by default file.in), substituting the output variable values. file is then named an output file, or configuration file. If FOO is an output variable which value is Bar, then all the occurrences of @FOO@ in file.in will be replaced with Bar in file.

If given, run the shell command once the file is created.

AC_OUTPUT Macro

Perform all the outputs (create the output files, output headers, etc.).

For instance:

     $ cat which-cc.in
     #! @SHELL@
     echo "cc is @CC@"
     $ cat configure.ac
     AC_INIT(Sample, 1.0)
     AC_PROG_CC
     AC_CONFIG_FILE([which-cc], [chmod +x which-cc])
     AC_OUTPUT
     $ autoconf
     $ ./configure
     checking for gcc... gcc
     checking for C compiler default output... a.out
     checking whether the C compiler works... yes
     checking whether we are cross compiling... no
     checking for executable suffix...
     checking for object suffix... o
     checking whether we are using the GNU C compiler... yes
     checking whether gcc accepts -g... yes
     configure: creating ./config.status
     config.status: creating which-cc
     $ ./which-cc
     cc is gcc
     $ cat which-cc
     #! /bin/sh
     echo "cc is gcc"
     

You may wonder what this config.status file is... As a matter of fact, configure is really an auditor, an inspector: it does not perform any configuration action itself, it creates an instantiator, config.status, and runs it.

Output files are not the only form of output: there is also a special form dedicated to providing the results of the audit to a C program. This information is a simple list of CPP symbols defined with #define, grouped together in a output header.

AC_CONFIG_HEADERS (file..., [command]) Macro

Declare the output header file must be created by copying its template (by default file.in), defining the CPP output symbols.

The traditional name for file is config.h. Therefore its default template is config.h.in, which causes problems on platforms so severely broken that they cannot handle two periods in a file name. To help people using operating systems of the previous Millennium, many maintainers use config.hin or config-h.in as a template. To this end, invoke AC_CONFIG_HEADERS(config.h:config.hin) or AC_CONFIG_HEADERS(config.h:config-h.in).

If given, run the shell command once the file is created.

Typical packages have a single place where their name and version are defined: configure.ac. Nevertheless, to provide an accurate answer to --help, the main program must know the current name and version. This is performed via the configuration header:

     $ cat configure.ac
     AC_INIT(Audit, 1.1, audit-bugs@audit.org)
     AC_CONFIG_HEADERS(config.h)
     AC_OUTPUT
     $ cat config.h.in
     /* Define to the address where bug reports for this package
        should be sent. */
     #undef PACKAGE_BUGREPORT
     
     /* Define to the full name of this package. */
     #undef PACKAGE_NAME
     
     /* Define to the full name and version of this package. */
     #undef PACKAGE_STRING
     
     /* Define to the one symbol short name of this package. */
     #undef PACKAGE_TARNAME
     
     /* Define to the version of this package. */
     #undef PACKAGE_VERSION
     $ autoconf
     $ ./configure
     $ cat config.h
     /* config.h.  Generated by configure.  */
     /* Define to the address where bug reports for this package
        should be sent. */
     #define PACKAGE_BUGREPORT "audit-bugs@audit.org"
     
     /* Define to the full name of this package. */
     #define PACKAGE_NAME "Audit"
     
     /* Define to the full name and version of this package. */
     #define PACKAGE_STRING "Audit 1.1"
     
     /* Define to the one symbol short name of this package. */
     #define PACKAGE_TARNAME "audit"
     
     /* Define to the version of this package. */
     #define PACKAGE_VERSION "1.1"
     

Fortunately, the content of the configuration header template, config.h.in, can easily be inferred from configure.ac: look for all the possibly defined CPP output symbols, put an #undef before them, paste a piece of standard comment, and spit it. This is just what autoheader does:

     $ rm config.h.in
     $ autoheader
     autoheader: `config.h.in' is created
     $ cat config.h.in
     /* config.h.in.  Generated from configure.ac by autoheader.  */
     
     /* Define to the address where bug reports for this package
        should be sent. */
     #undef PACKAGE_BUGREPORT
     
     /* Define to the full name of this package. */
     #undef PACKAGE_NAME
     
     /* Define to the full name and version of this package. */
     #undef PACKAGE_STRING
     
     /* Define to the one symbol short name of this package. */
     #undef PACKAGE_TARNAME
     
     /* Define to the version of this package. */
     #undef PACKAGE_VERSION
     

"Simple Uses of Autoconf"... Yet there are two programs to run! Does the order matter? (No, it doesn't.) When do I have to run them? (Each time configure.ac or one of its almost invisible dependencies changes.) Will there be other programs to run like this? (Sure, automake, libtoolize, gettextize, aclocal...) Will the order matter? (Yes, it becomes essential.)

"Simple Uses of Autoconf" ought to be named "Simple Uses of autoreconf": the latter is a program that knows each of these programs, when they are needed, when they ought to be run etc. I encourage you to forget about autoconf, automake and so on: just run autoreconf:

     $ rm configure config.h config.h.in
     $ cat configure.ac
     AC_INIT(Audit, 1.1, audit-bugs@audit.org)
     AC_CONFIG_HEADERS(config.h)
     AC_OUTPUT
     $ autoreconf --verbose
     autoreconf: working in `.'
     autoreconf: running: aclocal  --output=aclocal.m4t
     autoreconf: configure.ac: not using Gettext
     autoreconf: configure.ac: not using Libtool
     autoreconf: configure.ac: not using Automake
     autoreconf: running: autoconf
     autoreconf: running: autoheader
     autoheader: `config.h.in' is created
     $ ./configure
     configure: creating ./config.status
     config.status: creating config.h