The easiest way to create a (mostly) complete configure.ac file is to run the autoscan
utility, which is part of the autoconf package. This utility examines the contents of a project directory and generates the basis for a configure.ac file (which autoscan
names configure.scan) using existing makefiles and source files.
Let's see how well autoscan
does on the Jupiter project. First, I'll clean up the droppings from my earlier experiments, and then run autoscan
in the jupiter directory. Note that I'm not deleting my original configure.ac file—I'll just let autoscan
tell me how to improve it. In less than a second, I have a few new files in the top-level directory:
$rm -rf autom4te.cache build
$rm configure config.* Makefile src/Makefile src/jupiter
$ls −1p
configure.ac Makefile.in src/ $ $autoscan
❶ configure.ac: warning: missing AC_CHECK_HEADERS([stdlib.h]) wanted by: src/main.c:2 configure.ac: warning: missing AC_PREREQ wanted by: autoscan configure.ac: warning: missing AC_PROG_CC wanted by: src/main.c configure.ac: warning: missing AC_PROG_INSTALL wanted by: Makefile.in:18 $ $ls −1p
autom4te.cache/ autoscan.log configure.ac configure.scan Makefile.in src/ $
The autoscan
utility examines the project directory hierarchy and creates two files called configure.scan and autoscan.log. The project may or may not already be instrumented for Autotools—it doesn't really matter, because autoscan
is decidedly non-destructive. It will never alter any existing files in a project.
The autoscan
utility generates a warning message for each problem it discovers in an existing configure.ac file. In this example, autoscan
noticed that configure.ac should be using the Autoconf-provided AC_CHECK_HEADERS
, AC_PREREQ
, AC_PROG_CC
, and AC_PROG_INSTALL
macros. It made these assumptions based on information gleaned from the existing Makefile.in templates and from the C-language source files, as you can see by the comments after the warning statements beginning at ❶. You can always see these messages (in even greater detail) by examining the autoscan.log file.
The notices you receive from autoscan
and the contents of your configure.ac file may differ slightly from mine, depending on the version of Autoconf you have installed. I have version 2.64 of GNU Autoconf installed on my system (the latest, as of this writing). If your version of autoscan
is older (or newer), you may see some minor differences.
Looking at the generated configure.scan file, I note that autoscan
has added more text to this file than was in my original configure.ac file. After looking it over to ensure that I understand everything, I see that it's probably easiest for me to overwrite configure.ac with configure.scan and then change the few bits of information that are specific to Jupiter:
$mv configure.scan configure.ac
$cat configure.ac
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.64]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_HEADERS([config.h]) # Checks for programs. AC_PROG_CC AC_PROG_INSTALL # Checks for libraries. # Checks for header files. AC_CHECK_HEADERS([stdlib.h]) # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT $
My first modification involves changing the AC_INIT
macro parameters for Jupiter, as illustrated in Example 3-11.
Example 3-11. configure.ac: Tweaking the AC_INIT
macro generated by autoscan
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.64]) AC_INIT([Jupiter
], [1.0
], [jupiter-bugs@example.org
]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_HEADERS([config.h]) ...
The autoscan
utility does a lot of the work for you. The GNU Autoconf Manual[45] states that you should modify this file to meet the needs of your project before you use it, but there are only a few key issues to worry about (besides those related to AC_INIT
). I'll cover each of these issues in turn, but first, let's take care of a few administrative details.
Before autoreconf
came along, maintainers passed around a short shell script, often named autogen.sh
or bootstrap.sh
, which would run all of the Autotools required for their projects in the proper order. The autogen.sh
script can be fairly sophisticated, but to solve the problem of the missing install-sh
script (see MISSING REQUIRED FILES IN AUTOCONF in The Proverbial autogen.sh Script), I'll just add a simple temporary autogen.sh
script to the project root directory, as shown in Example 3-12.
Example 3-12. autogen.sh
: A temporary bootstrap script that executes the required Autotools
#!/bin/sh autoreconf --install ❶ automake --add-missing --copy >/dev/null 2>&1
The automake --add-missing
option copies the required missing utility scripts into the project, and the --copy
option indicates that true copies should be made (otherwise, symbolic links are created that refer to the files where they're installed with the Automake package).[46]
When make dist
generates a distribution archive, it creates true copies in the image directory, so the use of symlinks causes no real problems, as long as you (the maintainer) don't move your work area to another host.
We don't need to see the warnings from automake
, so I've redirected the stderr
and stdout
streams to /dev/null on the automake
command line at ❶ in this script. In Chapter 5, we'll remove autogen.sh
and simply run autoreconf --install
, but for now, this will solve our missing file problems.
Let's execute autogen.sh
and see what we end up with:
$ sh autogen.sh
$ ls −1p
autogen.sh
autom4te.cache/
❶ config.h.in
configure
configure.ac
❷ install-sh
Makefile.in
src/
$
We know from the file list at ❶ that config.h.in has been created, so we know that autoreconf
has executed autoheader
. We also see the new install-sh
script at ❷ that was created when we executed automake
in autogen.sh
. Anything provided or generated by the Autotools should be copied into the archive directory so that it can be shipped with release tarballs. Therefore, we'll add cp
commands for these two files to the $(distdir)
target in the top-level Makefile.in template. Note that we don't need to copy the autogen.sh
script because it's purely a maintainer tool—users should never need to execute it from a tarball distribution.
Example 3-13 illustrates the required changes to the $(distdir)
target in the top-level Makefile.in template.
Example 3-13. Makefile.in: Additional files needed in the distribution archive image directory
...
$(distdir): FORCE
mkdir -p $(distdir)/src
cp $(srcdir)/configure.ac $(distdir)
cp $(srcdir)/configure $(distdir)
cp $(srcdir)/config.h.in $(distdir)
cp $(srcdir)/install-sh $(distdir)
cp $(srcdir)/Makefile.in $(distdir)
cp $(srcdir)/src/Makefile.in $(distdir)/src
cp $(srcdir)/src/main.c $(distdir)/src
...
If you're beginning to think that this could become a maintenance problem, then you're right. I mentioned earlier that the $(distdir)
target was painful to maintain. Luckily, the distcheck
target still exists and still works as designed. It would have caught this problem, because attempts to build from the tarball will fail without these additional files—and the check
target certainly won't succeed if the build fails. When we discuss Automake in Chapter 5, we will clear up much of this maintenance mess.
[45] See the Free Software Foundation's GNU Autoconf Manual at http://www.gnu.org/software/autoconf/manual/index.html.
[46] The automake
--add-missing option copies in the missing required utility scripts, and the --copy
option indicates that true copies should be made—otherwise, symbolic links are created to the files where the automake
package has installed them. This isn't as bad as it sounds, because when make dist generates a distribution archive, it creates true copies in the image directory. Therefore, links work just fine, as long as you (the maintainer) don't move your work area to another host. Note that automake
provides a --copy option, but autoreconf provides just the opposite: a --symlink
option. Thus, if you execute automake --add-missing
and you wish to actually copy the files, you should pass --copy
as well. If you execute autoreconf --install
, --copy
will be assumed and passed to automake
by autoreconf
.
[47] Worse still, the GNU Autoconf Manual that I was using at the time told me that "Autoconf comes with a copy of install-sh
that you can use"—but it's really Automake and Libtool that come with copies of install-sh
.
[48] When I presented this problem on the Autoconf mailing list, I was told several times that autoconf
has no business copying install-sh
into a project directory, thus there is no installmissing-file functionality accessible from the autoconf
command line. If this is indeed the case, then autoconf
has no business complaining about the missing file, either!