From bb4e0792a34e708692317b31ae2991beda3b9afe Mon Sep 17 00:00:00 2001 From: Marc Culler Date: Wed, 14 Jun 2023 12:39:35 -0500 Subject: [PATCH] Add BuildPackages.sh to files, since GAP refused. --- Sage_framework/build_sage_framework.sh | 8 +- Sage_framework/files/BuildPackages.sh | 308 +++++++++++++++++++++++++ 2 files changed, 309 insertions(+), 7 deletions(-) create mode 100644 Sage_framework/files/BuildPackages.sh diff --git a/Sage_framework/build_sage_framework.sh b/Sage_framework/build_sage_framework.sh index efb3d83..29d1989 100644 --- a/Sage_framework/build_sage_framework.sh +++ b/Sage_framework/build_sage_framework.sh @@ -76,6 +76,7 @@ cp ${FILES}/sagedoc.py ${VERSION_DIR}/${VENV_PYLIB}/site-packages/sage/misc/sage cp -p ${FILES}/tkinter/__init__.py ${VERSION_DIR}/${VENV_PYLIB}/tkinter/__init__.py echo cp ${FILES}/osx.py ${INPUT_HOOKS} cp ${FILES}/osx.py ${INPUT_HOOKS} +cp -p ${FILES}/BuildPackages.sh ${VERSION_DIR}/local/lib/gap/bin # Fix illegal symlinks that point outside of the bundle # rm ${VERSION_DIR}/local/share/gap/{gac,gap} @@ -119,13 +120,6 @@ popd > /dev/null # Remove xattrs (must be done before signing!) xattr -rc ${BUILD}/Sage.framework -# Replace primecount binaries with working versions -# I have no idea why we need to do this. -#echo "Fixing primecount ..." -#cp primecount/bin/primecount ${VERSION_DIR}/local/bin -#cp primecount/lib/libprimecount.7.4.dylib ${VERSION_DIR}/local/lib -#cp primecount/lib/libprimesieve.10.0.0.dylib ${VERSION_DIR}/local/lib - # Remove byte code find ${BUILD}/Sage.framework -name '*.pyc' -delete # Sign the framework. diff --git a/Sage_framework/files/BuildPackages.sh b/Sage_framework/files/BuildPackages.sh new file mode 100644 index 0000000..8a9f641 --- /dev/null +++ b/Sage_framework/files/BuildPackages.sh @@ -0,0 +1,308 @@ +#!/usr/bin/env bash + +# This script attempts to build all GAP packages contained in the current +# directory. Normally, you should run this script from the 'pkg' +# subdirectory of your GAP installation. + +# You can also run it from other locations, but then you need to tell the +# script where your GAP root directory is, by passing it as an argument +# to the script with '--with-gaproot='. By default, the script assumes that +# the parent of the current working directory is the GAP root directory. + +# If arguments are added, then they are considered packages. In that case +# only these packages will be built, and all others are ignored. + +# You need at least 'gzip', GNU 'tar', a C compiler, sed, pdftex to run this. +# Some packages also need a C++ compiler. + +# Contact support@gap-system.org for questions and complaints. + +# Note, that this isn't and is not intended to be a sophisticated script. +# Even if it doesn't work completely automatically for you, you may get +# an idea what to do for a complete installation of GAP. + +set -e + +CURDIR="$(pwd)" +GAPROOT="$(cd .. && pwd)" +COLORS=yes +STRICT=no # exit with non-zero exit code when encountering any failures +PARALLEL=no +PACKAGES=() + +# If output does not go into a terminal (but rather into a log file), +# turn off colors. +[[ -t 1 ]] || COLORS=no + +while [[ "$#" -ge 1 ]]; do + option="$1" ; shift + case "$option" in + --with-gaproot) GAPROOT="$1"; shift ;; + --with-gaproot=*) GAPROOT=${option#--with-gaproot=}; ;; + --parallel) PARALLEL=yes; ;; + + --with-gap) GAP_EXE="$1"; shift ;; + --with-gap=*) GAP_EXE=${option#--with-gap=}; ;; + + --no-color) COLORS=no ;; + --color) COLORS=yes ;; + + --no-strict) STRICT=no ;; + --strict) STRICT=yes ;; + --add-package-config-*) typeset PACKAGE_CONFIG_ARGS_${option:21}="$1"; shift ;; + + -*) echo "ERROR: unsupported argument $option" ; exit 1;; + *) PACKAGES+=("$option") ;; + esac +done + +# Some helper functions for printing user messages +if [[ "x$COLORS" = xyes ]] +then + # print notices in green, warnings in yellow, errors in read + notice() { printf "\033[32m%s\033[0m\n" "$@" ; } + warning() { printf "\033[33mWARNING: %s\033[0m\n" "$@" ; } + error() { printf "\033[31mERROR: %s\033[0m\n" "$@" ; exit 1 ; } + std_error() { printf "\033[31m%s\033[0m\n" "$@" ; } +else + notice() { printf "%s\n" "$@" ; } + warning() { printf "WARNING: %s\n" "$@" ; } + error() { printf "ERROR: %s\n" "$@" ; exit 1 ; } + std_error() { printf "%s\n" "$@" ; } +fi + +# Is someone trying to run us from inside the 'bin' directory? +if [[ -f BuildPackages.sh ]] +then + error "This script must be run from inside the pkg directory" \ + "Type: cd ../pkg; ../bin/BuildPackages.sh" +fi + +if [ "x$PARALLEL" = "xyes" ] && [ "x$STRICT" = "xyes" ]; then + error "The options --strict and --parallel cannot be used simultaneously" +fi + +if [ "x$PARALLEL" = "xyes" ]; then + export MAKEFLAGS="${MAKEFLAGS:--j3}" +fi; + +# If user specified no packages to build, build all packages in subdirectories. +if [[ ${#PACKAGES[@]} == 0 ]] +then + # Put package directory names into a bash array to avoid issues with + # spaces in filenames. This code will still break if there are newlines + # in the name. + old_IFS=$IFS + IFS=$'\n' PACKAGES=($(find . -maxdepth 2 -type f -name PackageInfo.g | sort -f)) + IFS=$old_IFS + PACKAGES=( "${PACKAGES[@]%/PackageInfo.g}" ) +fi + +notice "Using GAP root $GAPROOT" + +# Check whether $GAPROOT is valid +if [[ ! -f "$GAPROOT/sysinfo.gap" ]] +then + error "$GAPROOT is not the root of a gap installation (no sysinfo.gap)" \ + "Please provide the absolute path of your GAP root directory as" \ + "first argument with '--with-gaproot=' to this script." +fi + +# read in sysinfo +source "$GAPROOT/sysinfo.gap" + +# determine the GAP executable to call: +# - if the user specified one explicitly via the `--gap` option, then +# GAP_EXE is set and we should use that +# - otherwise if sysinfo.gap set the GAP variable, use that +# - otherwise fall back to $GAPROOT/bin/gap.sh +if [[ -n $GAP_EXE ]] +then + GAP="$GAP_EXE" +else + GAP="${GAP:-$GAPROOT/bin/gap.sh}" +fi + + + +# detect whether GAP was built in 32bit mode +# TODO: once all packages have adapted to the new build system, +# this should no longer be necessary, as package build systems should +# automatically adjust to 32bit mode. +case "$GAP_ABI" in + 32) + notice "Building with 32-bit ABI" + CONFIGFLAGS="CFLAGS=-m32 LDFLAGS=-m32 LOPTS=-m32 CXXFLAGS=-m32" + ;; + 64) + notice "Building with 64-bit ABI" + CONFIGFLAGS="" + ;; + *) + error "Unsupported GAP ABI '$GAParch_abi'." + ;; +esac + + +LOGDIR=log +mkdir -p "$LOGDIR" + + +# Many package require GNU make. So use gmake if available, +# for improved compatibility with *BSD systems where "make" +# is BSD make, not GNU make. +if hash gmake 2> /dev/null +then + MAKE=gmake +else + MAKE=make +fi + +notice \ +"Attempting to build GAP packages." \ +"Note that many GAP packages require extra programs to be installed," \ +"and some are quite difficult to build. Please read the documentation for" \ +"packages which fail to build correctly, and only worry about packages" \ +"you require!" + +# print the given command plus arguments, single quoted, then run it +echo_run() { + # when printf is given a format string with only one format specification, + # it applies that format string to each argument in sequence + notice "Running $(printf "'%s' " "$@")" + "$@" +} + +build_fail() { + echo "" + warning "Failed to build $PKG" + echo "$PKG" >> "$LOGDIR/fail.log" + if [[ $STRICT = yes ]] + then + exit 1 + fi +} + +run_configure_and_make() { + # We want to know if this is an autoconf configure script + # or not, without actually executing it! + if [[ -x autogen.sh && ! -x configure ]] + then + ./autogen.sh + fi + if [[ -x configure ]] + then + if grep Autoconf ./configure > /dev/null + then + local PKG_NAME=$($GAP -q -T -A -r -M --bare <> "$LOGDIR/fail.log" +for PKG in "${PACKAGES[@]}" +do + ( # start a background process + # cut off the ending slash (if exists) + PKG="${PKG%/}" + # cut off everything before the first slash to only keep the package name + # (these two commands are mainly to accommodate the logs better, + # as they make no difference with changing directories) + PKG="${PKG##*/}" + if [[ -e "$CURDIR/$PKG/PackageInfo.g" ]] + then + (build_one_package "$PKG" \ + > >(tee "$LOGDIR/$PKG.out") \ + 2> >(while read line + do \ + std_error "$line" + done \ + > >(tee "$LOGDIR/$PKG.err" >&2) \ + ) \ + )> >(tee "$LOGDIR/$PKG.log" ) 2>&1 + + # remove superfluous log files if there was no error message + if [[ ! -s "$LOGDIR/$PKG.err" ]] + then + rm -f "$LOGDIR/$PKG.err" + rm -f "$LOGDIR/$PKG.out" + fi + + # remove log files if package needed no compilation + if [[ "$(grep -c 'No building required for' $LOGDIR/$PKG.log)" -ge 1 ]] + then + rm -f "$LOGDIR/$PKG.err" + rm -f "$LOGDIR/$PKG.out" + rm -f "$LOGDIR/$PKG.log" + fi + else + echo + warning "$PKG does not seem to be a package directory, skipping" + fi + ) & + BUILD_PID=$! + if [ "x$PARALLEL" = "xyes" ]; then + # If more than 4 background jobs are running, wait for one to finish (if + # is available) or for all to finish (if only is available) + if [[ $(jobs -r -p | wc -l) -gt 4 ]]; then + wait -n 2>&1 >/dev/null || wait + fi + else + # wait for this package to finish building + if ! wait $BUILD_PID && [[ $STRICT = yes ]] + then + exit 1 + fi + fi; +done +# Wait until all packages are built, if in parallel +wait + +echo "" >> "$LOGDIR/fail.log" +echo "" +notice "Packages which failed to build are in ./$LOGDIR/fail.log"