#!/bin/sh
########################################################################
# Regenerate auto-generated files (e.g. configure)
#
# If the -s option is given, save the autogenerated scripts in
# $SAGE_ROOT/upstream/configure-$CONFVERSION.tar.gz where CONFVERSION
# is the sha1 of HEAD `git rev-parse HEAD`
#
# If optional argument -d is given and bootstrapping failed, instead
# extract the files from a local configure tarball, downloading it if
# needed. If -D is given, don't try to bootstrap and always extract or
# download.
#
# If optional argument -u <URL> is given download the configure
# tarball from that base url. That is, "bootstrap -u http://host/path"
# will download http://host/path/configure-$CONFVERSION.tar.gz to
# upstream/configure-$CONFVERSION.tar.gz. This is used by the buildbot
# to download tarballs that are not published.
#
# The -q (quiet) flag hides all "informational" output.
#
########################################################################
# Set SAGE_ROOT to the path to this file and then cd into it
SAGE_ROOT="$(cd "$(dirname "$0")" && pwd -P)"
export SAGE_ROOT
cd "$SAGE_ROOT"
export PATH="$SAGE_ROOT/build/bin:$PATH"
MAKE="${MAKE:-make}"
bootstrap () {
for pkgname in cypari cysignals cython gmpy2 jupyter_core memory_allocator numpy pkgconfig pplpy setuptools wheel; do
# Write the version_requirements.txt files for dependencies declared in pyproject.toml
target=build/pkgs/${pkgname}/version_requirements.txt
if [ "${BOOTSTRAP_QUIET}" = "no" ]; then
echo "bootstrap:$LINENO: installing '"$target"'"
fi
echo "# Generated by SAGE_ROOT/bootstrap based on pyproject.toml; do not edit directly" > $target
sage-get-system-packages install-requires ${pkgname} >> $target
done
for a in m4/sage_spkg_configures.m4 m4/sage_spkg_versions.m4 m4/sage_spkg_versions_toml.m4; do
if [ "${BOOTSTRAP_QUIET}" = "no" ]; then
echo "bootstrap:$LINENO: installing '"$a"'"
fi
rm -f $a
echo "# Generated by SAGE_ROOT/bootstrap; do not edit" > $a
done
for a in m4/sage_spkg_versions.m4 m4/sage_spkg_versions_toml.m4; do
echo 'changequote(`>>>'"'"', `<<<'"')dnl" >> $a
done
eval $(sage-package properties --format=shell :all:)
spkg_configures=""
# initialize SAGE_ENABLE... options for standard packages
for pkgname in $(sage-package list :standard:); do
spkg_configures="$spkg_configures
AS_VAR_SET_IF([SAGE_ENABLE_$pkgname], [], [AS_VAR_SET([SAGE_ENABLE_$pkgname], [yes])])"
done
# --enable-SPKG options
for pkgname in $(sage-package list :optional: :experimental:); do
eval DIR=\$path_$pkgname pkgtype=\$type_$pkgname pkgsource=\$source_$pkgname
case "$pkgname:$pkgsource" in
*:pip)
# Issue #29629: Temporary solution for Sage 9.1: Do not provide
# --enable-SPKG options for installing pip packages
;;
_*:*)
# Issue #29124: Do not provide --enable-_recommended and similar
;;
*:none)
# Issue #31163: Just an optional dummy package
spkg_configures="$spkg_configures
AC_SUBST(SAGE_ENABLE_$pkgname, [if_installed])"
;;
*:*)
spkg_configures="$spkg_configures
AC_SUBST(SAGE_ENABLE_$pkgname, [if_installed])"
spkg_configures="$spkg_configures
SAGE_SPKG_ENABLE([$pkgname], [$pkgtype], [$(grep -v ^= "$DIR/SPKG.rst" | head -n1 2>/dev/null || echo $pkgname)])"
;;
esac
done
cat >> m4/sage_spkg_configures.m4 <<EOF
SAGE_SPKG_COLLECT_INIT([$(echo $(sage-package list))])
EOF
for pkgname in $(sage-package list --has-file spkg-configure.m4); do
eval DIR=\$path_$pkgname
echo "m4_sinclude([$DIR/spkg-configure.m4])"
config="SAGE_SPKG_CONFIGURE_$(echo ${pkgname} | tr '[a-z]' '[A-Z]')"
if grep -q SAGE_PYTHON_PACKAGE_CHECK "$DIR/spkg-configure.m4"; then
spkg_configures_python="$spkg_configures_python
$config"
else
spkg_configures="$spkg_configures
$config"
fi
done >> m4/sage_spkg_configures.m4
for pkgname in $(sage-package list); do
eval DIR=\$path_$pkgname pkgtype=\$type_$pkgname SPKG_SOURCE=\$source_$pkgname SPKG_TREE_VAR=\$trees_$pkgname
if test -f "$DIR/requirements.txt" -o -f "$DIR/version_requirements.txt"; then
# A Python package
echo "define(>>>SPKG_INSTALL_REQUIRES_${pkgname}<<<, >>>$(echo $(sage-get-system-packages install-requires ${pkgname}))<<<)dnl" >> m4/sage_spkg_versions.m4
INSTALL_REQUIRES_TOML=
echo "define(>>>SPKG_INSTALL_REQUIRES_${pkgname}<<<, >>>$(echo $(sage-get-system-packages install-requires-toml ${pkgname}))<<<)dnl" >> m4/sage_spkg_versions_toml.m4
echo "m4_define([SPKG_INSTALL_REQUIRES_${pkgname}], [[$(echo $(sage-get-system-packages install-requires-toml ${pkgname} | sed 's/"/\\"/g'))]])dnl" >> m4/sage_spkg_configures.m4
fi
spkg_finalizes="$spkg_finalizes
SAGE_SPKG_FINALIZE([$pkgname], [$pkgtype], [$SPKG_SOURCE], [$SPKG_TREE_VAR])"
done
for a in m4/sage_spkg_versions.m4 m4/sage_spkg_versions_toml.m4; do
echo 'changequote(>>>`<<<, >>>'"'"'<<<)dnl' >> $a
done
cat >> m4/sage_spkg_configures.m4 <<EOF
$spkg_configures
$spkg_configures_python
$spkg_finalizes
EOF
for pkgname in $(sage-package list --has-file bootstrap "$@"); do
eval DIR=\$path_$pkgname
(cd "$DIR" && if [ -x bootstrap ]; then ./bootstrap; else echo >&2 "bootstrap:$LINENO: Nothing to do for $pkgname"; fi) || exit 1
done
if [ $# != 0 ]; then
return
fi
# Default to no filter if "-q" was not passed.
QUIET_SED_FILTER=""
if [ "${BOOTSTRAP_QUIET}" = "yes" ]; then
# Otherwise, this filters the expected output from automake.
QUIET_SED_FILTER='/configure\.ac:[0-9][0-9]*: installing /d'
fi
# The insanity with automake's descriptors is intended to filter
# ONLY stderr, and to re-output the results back to stderr leaving
# stdout alone. Basically we swap the two descriptors using a
# third, filter, and then swap them back.
aclocal -I m4 && \
automake --add-missing --copy build/make/Makefile-auto 3>&1 1>&2 2>&3 \
| sed "${QUIET_SED_FILTER}" 3>&1 1>&2 2>&3 && \
autoconf
st=$?
case $st in
0) # Success
mv configure real_configure
cp configure_wrapper configure;;
179|16|17|63|127) # no m4 for pkg-config|autotools not installed|or version too old
if [ $DOWNLOAD = yes ]; then
echo >&2 "Bootstrap failed, downloading required files instead."
bootstrap_download || exit $?
else
if [ $st -eq 127 ]; then
verb="install"
elif [ $st -eq 16 ]; then
verb="install pkg-config m4 macros for"
elif [ $st -eq 17 ]; then
verb="install pkg-config, a.k.a. as pkgconf"
else
verb="upgrade"
fi
echo >&2 "Bootstrap failed. Either $verb autotools; or run bootstrap with"
echo >&2 "the -d option to download the auto-generated files instead."
SYSTEM=$(build/bin/sage-guess-package-system)
if test $SYSTEM != unknown; then
SYSTEM_PACKAGES=$(build/bin/sage-get-system-packages $SYSTEM _bootstrap)
if test -n "$SYSTEM_PACKAGES"; then
PRINT_SYS="build/bin/sage-print-system-package-command $SYSTEM --verbose=\" \" --prompt=\" \$ \" --sudo"
COMMAND=$(eval "$PRINT_SYS" update && eval "$PRINT_SYS" install $SYSTEM_PACKAGES && SAGE_ROOT="$SAGE_ROOT" eval "$PRINT_SYS" setup-build-env )
echo >&2
echo >&2 "hint: On your system ($SYSTEM), you can install the required system packages as follows:"
echo >&2 "$COMMAND"
echo >&2
fi
fi
exit $st
fi;;
*) exit $st;; # Failure
esac
}
# Bootstrap by downloading the auto-generated files
bootstrap_download () {
SAGE_DL_LOGLEVEL=""
[ "${BOOTSTRAP_QUIET}" = "yes" ] && SAGE_DL_LOGLEVEL="--log=WARNING"
CONFBALL=$(sage-package download $SAGE_DL_LOGLEVEL configure)
if [ $? -ne 0 ]; then
echo >&2 "Error: downloading configure tarball failed"
exit 1
fi
# The "m" option to tar ensures that timestamps are set to the
# current time, not taken from the tarball.
# We need these files to be more recent than the input files
# like configure.ac, otherwise "make" gets confused.
tar xzmf $CONFBALL || exit $?
}
save () {
set -e
# Check that config.guess is sufficiently recent
if ! grep '^timestamp=.*20\(1[5-9]\|2[0-9]\)' config/config.guess >/dev/null; then
echo >&2 "Error: config.guess is outdated:"
grep >&2 '^timestamp=' config/config.guess
echo >&2 "You should update the 'gnuconfig' or 'automake' package and try again"
exit 63
fi
NEWCONFVERSION=`git rev-parse HEAD`
NEWCONFBALL="upstream/configure-$NEWCONFVERSION.tar.gz"
# Create configure tarball
if [ "${BOOTSTRAP_QUIET}" = "no" ]; then
echo "Creating $NEWCONFBALL..."
fi
mkdir -p upstream
tar zcf "$NEWCONFBALL" \
configure real_configure configure_wrapper \
config/install-sh config/compile config/config.guess config/config.sub config/missing \
build/make/Makefile-auto.in \
src/doc/en/installation/*.txt \
$(find src/doc/en/reference/spkg -maxdepth 1 -name index.rst -prune -o -name "*.rst" -print) \
environment-3.1[0-9]-*.yml \
pyproject.toml \
build/pkgs/cypari/version_requirements.txt \
build/pkgs/cysignals/version_requirements.txt \
build/pkgs/cython/version_requirements.txt \
build/pkgs/gmpy2/version_requirements.txt \
build/pkgs/jupyter_core/version_requirements.txt \
build/pkgs/memory_allocator/version_requirements.txt \
build/pkgs/meson/version_requirements.txt \
build/pkgs/numpy/version_requirements.txt \
build/pkgs/pkgconfig/version_requirements.txt \
build/pkgs/pplpy/version_requirements.txt \
build/pkgs/setuptools/version_requirements.txt \
build/pkgs/wheel/version_requirements.txt
# Update version; this re-computes the checksum
sage-package update configure "$NEWCONFVERSION"
}
usage () {
echo >&2 "Usage: $0 [-d|-D|-s] [-u <URL>] [-h] [-q] [SPKG...]"
echo >&2 ""
echo >&2 "Options:"
echo >&2 " -d fall back to downloading (released versions only)"
echo >&2 " or using a pre-generated configure script"
echo >&2 " -D download and use a pre-generated configure script"
echo >&2 " (released versions only); overrides -d"
echo >&2 " -s save the generated configure script under upstream/"
echo >&2 " for later use with -d or -D"
echo >&2 " -u <URL> like -D, but downloads from the specified base URL"
echo >&2 " -h display this help and exit"
echo >&2 " -q hide informational output (be quiet)"
}
# Parse options
SAVE=no
DOWNLOAD=no
ALWAYSDOWNLOAD=no
CONFTARBALL_URL=""
BOOTSTRAP_QUIET=no
while getopts "Ddsu:hq" OPTION
do
case "$OPTION" in
D) ALWAYSDOWNLOAD=yes; DOWNLOAD=yes;;
d) DOWNLOAD=yes;;
s) SAVE=yes;;
u) CONFTARBALL_URL="$OPTARG"; ALWAYSDOWNLOAD=yes; DOWNLOAD=yes;;
h) usage; exit 0;;
q) BOOTSTRAP_QUIET=yes;;
?) usage; exit 2;;
esac
done
shift $(($OPTIND - 1))
export BOOTSTRAP_QUIET
if [ $DOWNLOAD$SAVE = yesyes ]; then
echo >&2 "$0: refusing to download and save."
usage
exit 2
fi
if [ $# != 0 -a $DOWNLOAD$ALWAYSDOWNLOAD$SAVE != nonono ]; then
echo >&2 "$0: Cannot combine -d, -D, -s, -u with SPKG arguments"
usage
exit 2
fi
# Start cleanly when a full bootstrap is happening (it's not a problem if this fails)
# POSIX supports two separate incompatible formats for the MAKEFLAGS
# variable, so instead of guessing, we simply define our own variable
# to optionally pass an "-s" (silent) flag to Make.
if [ $# = 0 ]; then
MAKE_SILENT=""
[ "${BOOTSTRAP_QUIET}" = "yes" ] && MAKE_SILENT="-s"
$MAKE ${MAKE_SILENT} bootstrap-clean 2>/dev/null
fi
mkdir -p config 2>/dev/null
if [ $ALWAYSDOWNLOAD = yes ]; then
if [ -n "$CONFTARBALL_URL" ]; then
CONFTARBALL=$(sage-package tarball configure)
URL="$CONFTARBALL_URL"/"$CONFTARBALL"
SAGE_DL_LOGLEVEL=""
[ "${BOOTSTRAP_QUIET}" = "yes" ] && SAGE_DL_LOGLEVEL="--log=WARNING"
sage-download-file ${SAGE_DL_LOGLEVEL} "$URL" upstream/"$CONFTARBALL"
if [ $? -ne 0 ]; then
echo >&2 "Error: downloading $CONFTARBALL from $CONFTARBALL_URL failed"
exit 1
fi
echo >&2 "Downloaded $CONFTARBALL from $CONFTARBALL_URL "
else
bootstrap_download || exit $?
fi
else
bootstrap "$@"
fi
if [ $SAVE = yes ]; then
save
fi