when your configure script is run, even if you have no intention of
ever cross-compiling your program.
- If you are using Automake, the auxiliary scripts your configure script
- needs will be added to your source tree by ‘autoreconf --install’ or
- ‘automake --add-missing’, and will be automatically included in your
- distribution tarball. If you are not using Automake, you will need
- to add them yourself. See the “Input” section of the manual for
+ autoreconf will issue an error if any auxiliary scripts are needed but
+ cannot be found. (It is not currently possible to make autoconf
+ itself issue this error.)
+
+ ‘autoreconf --install’ will add ‘config.sub’, ‘config.guess’, and
+ ‘install-sh’ to your source tree if they are needed. If you are
+ using Automake, scripts added to your tree by ‘autoreconf --install’
+ will automatically be included in the tarball produced by ‘make dist’;
+ otherwise, you will need to arrange for them to be distributed
+ yourself.
+
+ See the “Input” section of the manual for more detail, including
where to get the auxiliary scripts that may be needed by autoconf macros.
*** Older versions of automake and aclocal (< 1.8) are no longer supported.
use strict;
use warnings FATAL => 'all';
+my $buildauxdir;
BEGIN
{
my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '@pkgdatadir@';
unshift @INC, $pkgdatadir;
+ $buildauxdir = $ENV{'autom4te_buildauxdir'} || $pkgdatadir . '/build-aux';
+
# Override SHELL. On DJGPP SHELL may not be set to a shell
# that can handle redirection and quote arguments correctly,
# e.g.: COMMAND.COM. For DJGPP always use the shell that configure
# Do not use Cwd::chdir, since it might hang.
use Cwd qw (cwd);
+use File::Copy qw (copy);
+use File::Temp ();
use Autom4te::ChannelDefs;
use Autom4te::Channels;
}
+## ----------------------- ##
+## Handling of aux files. ##
+## ----------------------- ##
+
+# find_missing_aux_files
+# ----------------------
+# Look in $aux_dir (or, if that is empty, ., .., and ../..) for all of the
+# files in @$aux_files; return a list of those that do not exist.
+sub find_missing_aux_files
+{
+ my ($aux_files, $aux_dir) = @_;
+ my @aux_dirs;
+ if ($aux_dir)
+ {
+ push @aux_dirs, $aux_dir;
+ }
+ else
+ {
+ @aux_dirs = qw(. .. ../..);
+ }
+
+ # If we find all the aux files in _some_ directory in @aux_dirs, we're
+ # good. But if we don't find all of them in any directory in @aux_dirs,
+ # return the set of missing files from the _first_ directory in @aux_dirs;
+ # this will be less confusing in the common case where AC_CONFIG_AUX_DIR
+ # wasn't used and the parent directories don't provide any aux files.
+ my @missing_aux_files;
+ my @first_missing_aux_files;
+
+ for my $dir (@aux_dirs)
+ {
+ @missing_aux_files = ();
+ for my $file (@{$aux_files})
+ {
+ push @missing_aux_files, $file
+ unless -e "${dir}/${file}";
+ }
+
+ return () if !@missing_aux_files;
+
+ @first_missing_aux_files = @missing_aux_files
+ unless @first_missing_aux_files;
+ }
+
+ return @first_missing_aux_files;
+}
+
+# can_install_aux_files
+# ---------------------
+# Report whether all of the files listed in @_ exist in $buildauxdir,
+# which means we could install them.
+sub can_install_aux_files
+{
+ local $_;
+ for (@_)
+ {
+ return 0 unless -f "${buildauxdir}/$_";
+ }
+ return 1;
+}
+
+# try_install_aux_files
+# ---------------------
+# Install each of the aux files listed in @$auxfiles, that we are able
+# to install, into $destdir.
+# Remove the files we were able to install from @$auxfiles.
+sub try_install_aux_files
+{
+ my ($auxfiles, $destdir) = @_;
+ my @unable;
+ for my $f (@$auxfiles)
+ {
+ my $src = "${buildauxdir}/$f";
+ if (-f $src)
+ {
+ install_aux_file ($destdir, $f, $src);
+ }
+ else
+ {
+ push @unable, $f;
+ }
+ }
+ @$auxfiles = @unable;
+}
+
+# install_aux_file
+# ----------------
+# Install the file $src as $destdir/$f, honoring --symlink and --force.
+sub install_aux_file
+{
+ my ($destdir, $f, $src) = @_;
+ my $dest = "${destdir}/$f";
+ if ($symlink)
+ {
+ if ($force || ! -l $dest || readlink $dest != $src)
+ {
+ if (-e $dest)
+ {
+ unlink $dest
+ or fatal "rm -f $dest: $!\n";
+ }
+ verb "linking $dest to $src";
+ symlink $src, $dest
+ or fatal "ln -s $src $dest: $!\n";
+ }
+ }
+ else
+ {
+ if (-e $dest && ! -f $dest)
+ {
+ unlink $dest
+ or fatal "rm -f $dest: $!\n";
+ }
+ my $temp = new File::Temp (UNLINK => 0, DIR => $destdir);
+ copy ($src, $temp)
+ or fatal "copying $src to $temp: $!\n";
+ make_executable ($temp) if -x $src;
+ update_file ($temp, $dest, $force);
+ }
+}
+
+# make_executable
+# ---------------
+# Make the file $f be executable by all users it is currently readable by.
+sub make_executable
+{
+ my $f = shift;
+ my $perm = (stat $f)[2] & 07777;
+ $perm |= 0100 if ($perm & 0400);
+ $perm |= 0010 if ($perm & 0040);
+ $perm |= 0001 if ($perm & 0004);
+ chmod $perm, $f
+ or fatal "chmod $f: $!\n";
+}
+
+
+## -------------------------- ##
+## Per-directory operations. ##
+## -------------------------- ##
+
# &autoreconf_current_directory
# -----------------------------
sub autoreconf_current_directory ($)
# Perform a single trace reading to avoid --force forcing a rerun
# between two --trace, that's useless. If there is no AC_INIT, then
- # we are not interested: it looks like a Cygnus thingy.
+ # it's not an Autoconf script; ignore it.
# Suppress all warnings from this invocation; they may be spurious
# due to out-of-date files, and in any case they'll duplicate warnings
# from the final autoconf invocation.
my $aux_dir;
+ my @aux_files;
my $uses_gettext_via_traces;
my $uses_libtool;
my $uses_intltool;
'AC_CONFIG_HEADERS',
'AC_CONFIG_SUBDIRS',
'AC_INIT',
+ 'AC_REQUIRE_AUX_FILE',
'AC_PROG_LIBTOOL',
'AM_PROG_LIBTOOL',
'LT_INIT',
'LT_CONFIG_LTDL_DIR',
'AM_GNU_GETTEXT',
'AM_INIT_AUTOMAKE',
- 'IT_PROG_INTLTOOL',
'GTK_DOC_CHECK',
+ 'IT_PROG_INTLTOOL',
)
. ' |');
}
chomp;
my ($macro, @args) = split (/::/);
$aux_dir = $args[0] if $macro eq "AC_CONFIG_AUX_DIR";
+ push @aux_files, $args[0] if $macro eq "AC_REQUIRE_AUX_FILE";
$uses_autoconf = 1 if $macro eq "AC_INIT";
$uses_gettext_via_traces = 1 if $macro eq "AM_GNU_GETTEXT";
$uses_libtool = 1 if $macro eq "AC_PROG_LIBTOOL"
}
# Gettext consistency checks...
- error "$configure_ac: AM_GNU_GETTEXT is used, but not AM_GNU_GETTEXT_VERSION"
+ error $configure_ac, "AM_GNU_GETTEXT is used, but not AM_GNU_GETTEXT_VERSION"
if $uses_gettext_via_traces && ! $uses_gettext;
- error "$configure_ac: AM_GNU_GETTEXT_VERSION is used, but not AM_GNU_GETTEXT"
+ error $configure_ac, "AM_GNU_GETTEXT_VERSION is used, but not AM_GNU_GETTEXT"
if $uses_gettext && ! $uses_gettext_via_traces;
# repository with hand written code only (there is not even a need
# for a Makefile.am!).
- if (defined $aux_dir && ! -d $aux_dir)
+ if ($install && defined $aux_dir && ! -d $aux_dir)
{
verb "$configure_ac: creating directory $aux_dir";
mkdir $aux_dir, 0755
xsystem ($automake);
}
+ # ---------------------------------------------------- #
+ # Installing aux files and checking for missing ones. #
+ # ---------------------------------------------------- #
+ my @missing_aux_files = find_missing_aux_files (\@aux_files, $aux_dir);
+ if (@missing_aux_files)
+ {
+ try_install_aux_files (\@missing_aux_files, $aux_dir || '.') if $install;
+
+ for (0 .. $#missing_aux_files)
+ {
+ my $f = $missing_aux_files[$_];
+ if ($_ == $#missing_aux_files)
+ {
+ # Offer some advice if --install wasn't given and has a
+ # chance of helping.
+ my $trailer = "";
+ $trailer = "\n try running autoreconf --install"
+ if (!$install
+ && ($uses_automake
+ || $uses_libtool
+ || $uses_intltool
+ || $uses_gtkdoc
+ || can_install_aux_files @missing_aux_files));
+
+ error $configure_ac, "required file '$f' not found$trailer";
+ }
+ else
+ {
+ error $configure_ac, "required file '$f' not found";
+ }
+ }
+ }
# -------------- #
# Running make. #
autoreconf ($directory);
}
+exit $exit_code;
+
### Setup "GNU" style for perl-mode and cperl-mode.
## Local Variables:
## perl-indent-level: 2
script they need.
@end defmac
-Some third-party tools can install and update auxiliary scripts in your
-source tree for you; for instance, Automake's @option{--add-missing}
-mode does this for many commonly-needed scripts, including
-@file{install-sh}, @file{config.sub}, and @file{config.guess}.
-If you are only using Autoconf, however, you will need to add auxiliary
-scripts to your source tree yourself, and arrange for them to be
-included in release tarballs.
-@command{configure} will report any missing scripts when run.
-
-The scripts needed by Autoconf core macros are included with the
-Autoconf source tree. @file{install-sh} can be downloaded from
+@command{configure} checks for all the auxiliary scripts it needs on
+startup, and exits with an error if any are missing.
+
+@command{autoreconf} also detects missing auxiliary scripts. When used
+with the @option{--install} option, @command{autoreconf} will try to add
+missing scripts to the directory specified by @code{AC_CONFIG_AUX_DIR},
+or to the top level of the source tree if @code{AC_CONFIG_AUX_DIR} was
+not used. It can always do this for the scripts needed by Autoconf core
+macros: @file{install-sh}, @file{config.sub}, and @file{config.guess}.
+Many other commonly-needed scripts are installed by the third-party
+tools that @command{autoreconf} knows how to run, such as @file{missing}
+for Automake and @file{ltmain.sh} for Libtool.
+
+If you are using Automake, auxiliary scripts will automatically be
+included in the tarball created by @command{make dist}. If you are
+not using Automake you will need to arrange for auxiliary scripts to
+be included in tarballs yourself. Auxiliary scripts should normally
+@emph{not} be checked into a version control system, for the same
+reasons that @command{configure} shouldn't be.
+
+The scripts needed by Autoconf core macros can be found in
+@file{$(datadir)/autoconf/build-aux} of the Autoconf installation
+(@pxref{Installation Directory Variables}).
+@file{install-sh} can be downloaded from
@url{https://git.savannah.gnu.org/cgit/automake.git/plain/lib/install-sh}.
@file{config.sub} and @file{config.guess} can be downloaded from
@url{https://git.savannah.gnu.org/cgit/config.git/tree/}.
target directory in a single invocation.
Autoconf comes with a copy of @file{install-sh} that you can use.
-If you use @code{AC_PROG_INSTALL}, you must include @file{install-sh}
-in your distribution; otherwise @command{configure} produces an error
-message saying it can't find it---even if the system you're on has a
-good @command{install} program. This check is a safety measure to
-prevent you from accidentally leaving that file out, which would prevent
-your package from installing on systems that don't have a BSD-compatible
-@command{install} program.
+If you use @code{AC_PROG_INSTALL}, you must include @file{install-sh} in
+your distribution; otherwise @command{autoreconf} and @command{configure}
+will produce an error message saying they can't find it---even if the
+system you're on has a good @command{install} program. This check is a
+safety measure to prevent you from accidentally leaving that file out,
+which would prevent your package from installing on systems that don't
+have a BSD-compatible @command{install} program.
If you need to use your own installation program because it has features
not found in standard @command{install} programs, there is no reason to use
args: --preselect AC_CONFIG_MACRO_DIR_TRACE
args: --preselect AC_CONFIG_SUBDIRS
args: --preselect AC_INIT
+args: --preselect AC_REQUIRE_AUX_FILE
args: --preselect AC_PROG_LIBTOOL
args: --preselect AM_PROG_LIBTOOL
-args: --preselect GTK_DOC_CHECK
-args: --preselect IT_PROG_INTLTOOL
args: --preselect LT_INIT
args: --preselect LT_CONFIG_LTDL_DIR
args: --preselect AM_GNU_GETTEXT
+args: --preselect GTK_DOC_CHECK
+args: --preselect IT_PROG_INTLTOOL
end-language: "Autoreconf-preselections"
forbidden_patterns_files += $(dist_autotestlib_DATA)
lib/autotest/autotest.m4f: $(autotest_m4f_dependencies)
+
+## --------------------------- ##
+## Install auxiliary scripts. ##
+## --------------------------- ##
+
+buildauxdir = $(pkgdatadir)/build-aux
+dist_buildaux_SCRIPTS = \
+ build-aux/config.guess \
+ build-aux/config.sub \
+ build-aux/install-sh
## ------------------------- ##
AT_SETUP([Missing auxiliary files])
+AT_KEYWORDS([autoreconf])
AT_DATA([configure.ac],
[[AC_INIT([GNU foo], [1.0])
]])
AT_CHECK_AUTOCONF
+
+# Both configure and autoreconf should detect the missing files.
AT_CHECK_CONFIGURE([], [1], [ignore],
[configure: error: cannot find required auxiliary files: config.guess config.sub
])
+AT_CHECK([autoreconf], 1, [],
+[configure.ac: error: required file 'config.sub' not found
+configure.ac: error: required file 'config.guess' not found
+configure.ac: try running autoreconf --install
+])
+
+# If only one file is missing, the error messages should only report
+# that one. Also, the above invocation of autoreconf should _not_
+# have created build-aux, because it wasn't called with --install.
+AT_CHECK([test ! -e build-aux])
+mkdir build-aux
: > build-aux/config.guess
AT_CHECK_CONFIGURE([], [1], [ignore],
[configure: error: cannot find required auxiliary files: config.sub
])
+AT_CHECK([autoreconf], 1, [],
+[configure.ac: error: required file 'config.sub' not found
+configure.ac: try running autoreconf --install
+])
+
+# Missing aux files should not interfere with --help and --version.
+AT_CHECK_CONFIGURE([--help], [0], [ignore], [ignore])
+AT_CHECK_CONFIGURE([--version], [0], [ignore], [ignore])
+
+# autoreconf --install should be able to install config.sub and config.guess.
+rm build-aux/config.guess
+AT_CHECK([autoreconf --install])
+
+AT_CHECK([test -x build-aux/config.guess])
+AT_CHECK([test -x build-aux/config.sub])
+AT_CHECK([test ! -e build-aux/install-sh])
+
+AT_CHECK_CONFIGURE
+
+# Repeat all the above tests with a configure script that _doesn't_
+# need config.{sub,guess} but does need install-sh.
+
+rm build-aux/config.guess
+rm build-aux/config.sub
+rmdir build-aux
+
AT_DATA([configure.ac],
[[AC_INIT([GNU foo], [1.0])
AC_CONFIG_AUX_DIR([build-aux])
AC_OUTPUT
]])
+
AT_CHECK_AUTOCONF
AT_CHECK_CONFIGURE([], [1], [ignore],
[configure: error: cannot find required auxiliary files: install-sh
])
+AT_CHECK([autoreconf], 1, [],
+[configure.ac: error: required file 'install-sh' not found
+configure.ac: try running autoreconf --install
+])
+AT_CHECK([test ! -e build-aux])
+
+AT_CHECK_CONFIGURE([--help], [0], [ignore], [ignore])
+AT_CHECK_CONFIGURE([--version], [0], [ignore], [ignore])
+
+AT_CHECK([autoreconf --install])
+
+AT_CHECK([test ! -e build-aux/config.guess])
+AT_CHECK([test ! -e build-aux/config.sub])
+AT_CHECK([test -x build-aux/install-sh])
+
+AT_CHECK_CONFIGURE
+
AT_CLEANUP
AUTOHEADER=autoheader
AUTOM4TE=autom4te
AUTOM4TE_CFG='@abs_top_builddir@/lib/autom4te.cfg'
+autom4te_buildauxdir='@abs_top_srcdir@/build-aux'
autom4te_perllibdir='@abs_top_srcdir@/lib'
trailer_m4='@abs_top_srcdir@/lib/autoconf/trailer.m4'
-export AUTOCONF AUTOHEADER AUTOM4TE AUTOM4TE_CFG autom4te_perllibdir trailer_m4
+export AUTOCONF AUTOHEADER AUTOM4TE AUTOM4TE_CFG
+export autom4te_buildauxdir autom4te_perllibdir trailer_m4
case '@wrap_program@' in
ifnames)