autoconf/bootstrap

259 lines
7.6 KiB
Plaintext
Raw Normal View History

Add a bootstrap script like Automake has. The bootstrap script generates the same files ‘autoreconf -vi’ would, in a normal package, but it uses autoconf *from the git sources* to do it. This means people building from git do not need autoconf to be installed already. More importantly, it eliminates the extra steps when building from git, of re-generating autoconf’s own configure script with the just-built autoconf, then rebuilding the entire tree. (This process still requires Automake to be installed already, and Automake’s bootstrap script requires Autoconf to be installed already, so there is still a dependency loop between Autoconf and Automake when building from git—you need at least one of them installed from a tarball to get started.) The bootstrap script works by creating a partial installation tree in a temporary directory, containing bin/autoconf, bin/autom4te, and just enough of the usual contents of $(pkgdatadir) for autoconf and autom4te to work. It then runs a hardcoded list of commands, corresponding to what ‘autoreconf -i -Wall,error’ would run, but setting environment variables AUTOCONF and AUTOM4TE to ensure the bootstrap versions of these tools are used. (We have to create both, because automake runs autoconf, not autom4te, to trace configure.ac.) The ‘Autom4te’, ‘autoconf’, and ‘m4sugar’ subdirectories of the partial installation tree are symlinked back to the source tree; this is why version.m4 needed to be moved out of the m4sugar subdirectory, so the bootstrap script can create it without scribbling on the source tree. autom4te is run in --melt mode, so we don’t need to create freeze files in any subdirectories either. All of the substitution variables that are needed for autoconf and autom4te to both run, and create the same output that they would have if fully configured, are honored (unfortunately this does involve digging around in configure.ac with sed expressions).
2021-02-05 02:11:28 +08:00
#! /bin/sh
# This script helps bootstrap autoconf, when checked out from git.
#
# Copyright (C) 2021-2024 Free Software Foundation, Inc.
Add a bootstrap script like Automake has. The bootstrap script generates the same files ‘autoreconf -vi’ would, in a normal package, but it uses autoconf *from the git sources* to do it. This means people building from git do not need autoconf to be installed already. More importantly, it eliminates the extra steps when building from git, of re-generating autoconf’s own configure script with the just-built autoconf, then rebuilding the entire tree. (This process still requires Automake to be installed already, and Automake’s bootstrap script requires Autoconf to be installed already, so there is still a dependency loop between Autoconf and Automake when building from git—you need at least one of them installed from a tarball to get started.) The bootstrap script works by creating a partial installation tree in a temporary directory, containing bin/autoconf, bin/autom4te, and just enough of the usual contents of $(pkgdatadir) for autoconf and autom4te to work. It then runs a hardcoded list of commands, corresponding to what ‘autoreconf -i -Wall,error’ would run, but setting environment variables AUTOCONF and AUTOM4TE to ensure the bootstrap versions of these tools are used. (We have to create both, because automake runs autoconf, not autom4te, to trace configure.ac.) The ‘Autom4te’, ‘autoconf’, and ‘m4sugar’ subdirectories of the partial installation tree are symlinked back to the source tree; this is why version.m4 needed to be moved out of the m4sugar subdirectory, so the bootstrap script can create it without scribbling on the source tree. autom4te is run in --melt mode, so we don’t need to create freeze files in any subdirectories either. All of the substitution variables that are needed for autoconf and autom4te to both run, and create the same output that they would have if fully configured, are honored (unfortunately this does involve digging around in configure.ac with sed expressions).
2021-02-05 02:11:28 +08:00
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# Autoconf's own configure script is generated using Autoconf. This
# script does what running `autoreconf -i` in an Autoconf git checkout
# would do, except that it uses autoconf from the source tree we are
# preparing, not any version of autoconf that might or might not be
# installed already. Note that automake, Perl, and GNU M4 _are_
# required to be installed already.
# Don't ignore failures.
set -e
(set -o pipefail 2> /dev/null) && set -o pipefail
# Avoid problems due to various shell wrinkles.
# We assume we have a shell new enough to implement unset correctly.
(set -o posix 2> /dev/null) && set -o posix
PS1='$ '
PS2='> '
PS4='+ '
unset BASH_ENV CDPATH ENV IFS MAIL MAILPATH POSIXLY_CORRECT
unset LANG LANGUAGE LC_ADDRESS LC_COLLATE LC_CTYPE LC_IDENTIFICATION
unset LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER
unset LC_TELEPHONE LC_TIME
LC_ALL=C
export LC_ALL
# Set program basename.
me=${0##*/}
usage="usage: $me [options]
Prepare to build a git checkout of autoconf.
Functionally equivalent to \`autoreconf -i\`, but uses autoconf code
from the git checkout itself to create \`configure\`.
Options:
-f, --force consider all files to be obsolete
-v, --verbose verbosely report processing (repeat for more detail)
"
# Options.
verbose=
subverbose=
force=
while [ $# -gt 0 ]; do
case "$1" in
(-v | --verbose)
if [ -n "$verbose" ]; then
subverbose=--verbose
else
verbose=--verbose
fi
;;
(-f | --force)
force=--force
;;
(-h | --help)
printf '%s' "$usage"
exit 0
;;
(*)
printf '%s' "$usage" >&2
exit 1
;;
esac
shift
done
# Let the user choose which version of aclocal, automake, m4, and perl to use.
: ${ACLOCAL=aclocal}
: ${AUTOMAKE=automake}
: ${M4=m4}
: ${PERL=perl}
export ACLOCAL AUTOMAKE M4 PERL
# Allow 'ln -s' to be overridden by the user.
: ${LN_S="ln -s"}
export LN_S
Add a bootstrap script like Automake has. The bootstrap script generates the same files ‘autoreconf -vi’ would, in a normal package, but it uses autoconf *from the git sources* to do it. This means people building from git do not need autoconf to be installed already. More importantly, it eliminates the extra steps when building from git, of re-generating autoconf’s own configure script with the just-built autoconf, then rebuilding the entire tree. (This process still requires Automake to be installed already, and Automake’s bootstrap script requires Autoconf to be installed already, so there is still a dependency loop between Autoconf and Automake when building from git—you need at least one of them installed from a tarball to get started.) The bootstrap script works by creating a partial installation tree in a temporary directory, containing bin/autoconf, bin/autom4te, and just enough of the usual contents of $(pkgdatadir) for autoconf and autom4te to work. It then runs a hardcoded list of commands, corresponding to what ‘autoreconf -i -Wall,error’ would run, but setting environment variables AUTOCONF and AUTOM4TE to ensure the bootstrap versions of these tools are used. (We have to create both, because automake runs autoconf, not autom4te, to trace configure.ac.) The ‘Autom4te’, ‘autoconf’, and ‘m4sugar’ subdirectories of the partial installation tree are symlinked back to the source tree; this is why version.m4 needed to be moved out of the m4sugar subdirectory, so the bootstrap script can create it without scribbling on the source tree. autom4te is run in --melt mode, so we don’t need to create freeze files in any subdirectories either. All of the substitution variables that are needed for autoconf and autom4te to both run, and create the same output that they would have if fully configured, are honored (unfortunately this does involve digging around in configure.ac with sed expressions).
2021-02-05 02:11:28 +08:00
# $PERL needs to be an absolute path because we're going to substitute it
# into #! lines.
set fnord $PERL
shift
PERL=$(command -v $1)
shift
if [ $# -gt 0 ]; then
PERL="$PERL $*"
fi
# Override SHELL. This is required on DJGPP so that Perl's system()
# uses bash, not COMMAND.COM which doesn't quote arguments properly.
# It's not used otherwise.
if test -n "$DJDIR"; then
BOOTSTRAP_SHELL=/dev/env/DJDIR/bin/bash.exe
else
BOOTSTRAP_SHELL=/bin/sh
fi
# Determine whether we have a usable version of M4.
# This rule is pickier than the rule in autoconf's actual configure script.
m4_version="$($M4 --version | head -1)"
case "$m4_version" in
( *\ 0.* \
| *\ 1.[0123] \
| *\ 1.[0123].* \
| *\ 1.4.[0123456789] \
| *\ 1.4.1[012345] \
)
printf '%s\n' "$me: $M4 ($m4_version) is too old" >&2
exit 1
;;
esac
# Substitutions related to the version of M4 available.
M4_DEBUGFILE=
M4_GNU=
m4_help=$($M4 --help)
case "$m4_help" in
(*--debugfile*)
M4_DEBUGFILE=--debugfile ;;
(*--error-output*)
M4_DEBUGFILE=--error-output ;;
esac
case "$m4_help" in
(*--gnu*)
M4_GNU=--gnu ;;
esac
# Autoconf's version number and identifiers.
RELEASE_YEAR=$(sed -ne 's/^RELEASE_YEAR=\([0-9][0-9]*\)$/\1/p' configure.ac)
VERSION=$(build-aux/git-version-gen .tarball-version)
# PACKAGE_NAME and PACKAGE_BUGREPORT from the bootstrap autoconf can
# get copied into the generated configure script, so we need to get them
# right. Caution: there is a hard tab in one of the regexes below.
PACKAGE_NAME=$(sed -n < configure.ac \
-e 's/^m4_define(\[autoconf_PACKAGE_NAME], \[\([^]]*\)])$/\1/p')
Add a bootstrap script like Automake has. The bootstrap script generates the same files ‘autoreconf -vi’ would, in a normal package, but it uses autoconf *from the git sources* to do it. This means people building from git do not need autoconf to be installed already. More importantly, it eliminates the extra steps when building from git, of re-generating autoconf’s own configure script with the just-built autoconf, then rebuilding the entire tree. (This process still requires Automake to be installed already, and Automake’s bootstrap script requires Autoconf to be installed already, so there is still a dependency loop between Autoconf and Automake when building from git—you need at least one of them installed from a tarball to get started.) The bootstrap script works by creating a partial installation tree in a temporary directory, containing bin/autoconf, bin/autom4te, and just enough of the usual contents of $(pkgdatadir) for autoconf and autom4te to work. It then runs a hardcoded list of commands, corresponding to what ‘autoreconf -i -Wall,error’ would run, but setting environment variables AUTOCONF and AUTOM4TE to ensure the bootstrap versions of these tools are used. (We have to create both, because automake runs autoconf, not autom4te, to trace configure.ac.) The ‘Autom4te’, ‘autoconf’, and ‘m4sugar’ subdirectories of the partial installation tree are symlinked back to the source tree; this is why version.m4 needed to be moved out of the m4sugar subdirectory, so the bootstrap script can create it without scribbling on the source tree. autom4te is run in --melt mode, so we don’t need to create freeze files in any subdirectories either. All of the substitution variables that are needed for autoconf and autom4te to both run, and create the same output that they would have if fully configured, are honored (unfortunately this does involve digging around in configure.ac with sed expressions).
2021-02-05 02:11:28 +08:00
PACKAGE_BUGREPORT=$(sed -n < configure.ac \
-e 's/^m4_define(\[autoconf_PACKAGE_BUGREPORT], \[\([^]]*\)])$/\1/p')
Add a bootstrap script like Automake has. The bootstrap script generates the same files ‘autoreconf -vi’ would, in a normal package, but it uses autoconf *from the git sources* to do it. This means people building from git do not need autoconf to be installed already. More importantly, it eliminates the extra steps when building from git, of re-generating autoconf’s own configure script with the just-built autoconf, then rebuilding the entire tree. (This process still requires Automake to be installed already, and Automake’s bootstrap script requires Autoconf to be installed already, so there is still a dependency loop between Autoconf and Automake when building from git—you need at least one of them installed from a tarball to get started.) The bootstrap script works by creating a partial installation tree in a temporary directory, containing bin/autoconf, bin/autom4te, and just enough of the usual contents of $(pkgdatadir) for autoconf and autom4te to work. It then runs a hardcoded list of commands, corresponding to what ‘autoreconf -i -Wall,error’ would run, but setting environment variables AUTOCONF and AUTOM4TE to ensure the bootstrap versions of these tools are used. (We have to create both, because automake runs autoconf, not autom4te, to trace configure.ac.) The ‘Autom4te’, ‘autoconf’, and ‘m4sugar’ subdirectories of the partial installation tree are symlinked back to the source tree; this is why version.m4 needed to be moved out of the m4sugar subdirectory, so the bootstrap script can create it without scribbling on the source tree. autom4te is run in --melt mode, so we don’t need to create freeze files in any subdirectories either. All of the substitution variables that are needed for autoconf and autom4te to both run, and create the same output that they would have if fully configured, are honored (unfortunately this does involve digging around in configure.ac with sed expressions).
2021-02-05 02:11:28 +08:00
if [ -z "$RELEASE_YEAR" ]; then
echo "$me: error: could not extract RELEASE_YEAR from configure.ac" >&2
exit 1
fi
if [ -z "$VERSION" ]; then
echo "$me: error: could not compute VERSION" >&2
exit 1
fi
if [ -z "$PACKAGE_NAME" ]; then
echo "$me: error: could not extract PACKAGE_NAME from configure.ac" >&2
exit 1
fi
if [ -z "$PACKAGE_BUGREPORT" ]; then
echo "$me: error: could not extract PACKAGE_BUGREPORT from configure.ac" >&2
exit 1
fi
# PACKAGE_TARNAME and PACKAGE_URL from the bootstrap autoconf should not
# get copied into the configure script.
PACKAGE_URL='<<not available>>'
PACKAGE_TARNAME='<<not available>>'
# Root for temporary partial installation tree.
ACBOOTDIR=$(mktemp -d acboot.XXXXXXXXXX)
ACBOOTDIR=$(realpath $ACBOOTDIR)
Add a bootstrap script like Automake has. The bootstrap script generates the same files ‘autoreconf -vi’ would, in a normal package, but it uses autoconf *from the git sources* to do it. This means people building from git do not need autoconf to be installed already. More importantly, it eliminates the extra steps when building from git, of re-generating autoconf’s own configure script with the just-built autoconf, then rebuilding the entire tree. (This process still requires Automake to be installed already, and Automake’s bootstrap script requires Autoconf to be installed already, so there is still a dependency loop between Autoconf and Automake when building from git—you need at least one of them installed from a tarball to get started.) The bootstrap script works by creating a partial installation tree in a temporary directory, containing bin/autoconf, bin/autom4te, and just enough of the usual contents of $(pkgdatadir) for autoconf and autom4te to work. It then runs a hardcoded list of commands, corresponding to what ‘autoreconf -i -Wall,error’ would run, but setting environment variables AUTOCONF and AUTOM4TE to ensure the bootstrap versions of these tools are used. (We have to create both, because automake runs autoconf, not autom4te, to trace configure.ac.) The ‘Autom4te’, ‘autoconf’, and ‘m4sugar’ subdirectories of the partial installation tree are symlinked back to the source tree; this is why version.m4 needed to be moved out of the m4sugar subdirectory, so the bootstrap script can create it without scribbling on the source tree. autom4te is run in --melt mode, so we don’t need to create freeze files in any subdirectories either. All of the substitution variables that are needed for autoconf and autom4te to both run, and create the same output that they would have if fully configured, are honored (unfortunately this does involve digging around in configure.ac with sed expressions).
2021-02-05 02:11:28 +08:00
# dosubst options infile outfile -- performs the substitutions that
# config.status would perform on INFILE, creating OUTFILE. INFILE is
# relative to the source directory, OUTFILE is relative to $ACBOOTDIR.
# If OPTIONS is the letter 'x', OUTFILE is made executable after creation.
dosubst ()
{
in=${2##*/}
out="$ACBOOTDIR/$3"
if [ -n "$verbose" ]; then
printf '%s: creating %s\n' "$me" "$out"
fi
rm -f "$out"
sed -e "s%@configure_input@%Generated from $in; do not edit by hand.%g" \
-e "s%@M4@%$M4%g" \
-e "s%@M4_DEBUGFILE@%$M4_DEBUGFILE%g" \
-e "s%@M4_GNU@%$M4_GNU%g" \
-e "s%@PACKAGE_BUGREPORT@%$PACKAGE_BUGREPORT%g" \
-e "s%@PACKAGE_NAME@%$PACKAGE_NAME%g" \
-e "s%@PACKAGE_STRING@%$PACKAGE_NAME $VERSION%g" \
-e "s%@PACKAGE_TARNAME@%$PACKAGE_TARNAME%g" \
-e "s%@PACKAGE_URL@%$PACKAGE_URL%g" \
-e "s%@PACKAGE_VERSION@%$VERSION%g" \
-e "s%@PERL@%$PERL%g" \
-e "s%@PERL_FLOCK@%0%g" \
-e "s%@RELEASE_YEAR@%$RELEASE_YEAR%g" \
-e "s%@SHELL@%$BOOTSTRAP_SHELL%g" \
-e "s%@VERSION@%$VERSION%g" \
-e "s%@pkgdatadir@%$ACBOOTDIR/lib%g" \
"$2" > "$out"
if [ "$1" = "x" ]; then
chmod +x "$out"
fi
}
# Create the bootstrap installation.
mkdir "$ACBOOTDIR"/bin "$ACBOOTDIR"/lib "$ACBOOTDIR"/tmp
(
cd "$ACBOOTDIR"/lib
for sub in Autom4te autoconf m4sugar ; do
if [ -n "$verbose" ]; then
printf '%s: creating %s\n' "$me" "$ACBOOTDIR/lib/$sub"
fi
$LN_S ../../lib/$sub .
Add a bootstrap script like Automake has. The bootstrap script generates the same files ‘autoreconf -vi’ would, in a normal package, but it uses autoconf *from the git sources* to do it. This means people building from git do not need autoconf to be installed already. More importantly, it eliminates the extra steps when building from git, of re-generating autoconf’s own configure script with the just-built autoconf, then rebuilding the entire tree. (This process still requires Automake to be installed already, and Automake’s bootstrap script requires Autoconf to be installed already, so there is still a dependency loop between Autoconf and Automake when building from git—you need at least one of them installed from a tarball to get started.) The bootstrap script works by creating a partial installation tree in a temporary directory, containing bin/autoconf, bin/autom4te, and just enough of the usual contents of $(pkgdatadir) for autoconf and autom4te to work. It then runs a hardcoded list of commands, corresponding to what ‘autoreconf -i -Wall,error’ would run, but setting environment variables AUTOCONF and AUTOM4TE to ensure the bootstrap versions of these tools are used. (We have to create both, because automake runs autoconf, not autom4te, to trace configure.ac.) The ‘Autom4te’, ‘autoconf’, and ‘m4sugar’ subdirectories of the partial installation tree are symlinked back to the source tree; this is why version.m4 needed to be moved out of the m4sugar subdirectory, so the bootstrap script can create it without scribbling on the source tree. autom4te is run in --melt mode, so we don’t need to create freeze files in any subdirectories either. All of the substitution variables that are needed for autoconf and autom4te to both run, and create the same output that they would have if fully configured, are honored (unfortunately this does involve digging around in configure.ac with sed expressions).
2021-02-05 02:11:28 +08:00
done
)
# automake invokes autoconf, and autoconf and aclocal both invoke autom4te,
# so we need to create both of them.
dosubst x bin/autoconf.in bin/autoconf
dosubst x bin/autom4te.in bin/autom4te
dosubst . lib/autom4te.in lib/autom4te.cfg
dosubst . lib/version.in lib/version.m4
AUTOCONF="$ACBOOTDIR"/bin/autoconf
AUTOM4TE="$ACBOOTDIR/bin/autom4te -M -C $ACBOOTDIR/tmp/autom4te.cache"
export AUTOCONF AUTOM4TE
# We can now do what autoreconf would have done.
# Order is critical -- first aclocal, then autoconf, then automake.
run ()
{
if [ -n "$verbose" ]; then
printf '%s: running %s\n' "$me" "$*"
fi
"$@"
}
run $ACLOCAL -I m4 -Wall -Werror $subverbose $force
run $AUTOCONF -Wall -Werror $subverbose $force
run $AUTOMAKE --add-missing --copy -Wall -Werror $subverbose $force
# Clean up.
rm -rf "$ACBOOTDIR"