Skip to content

Commit

Permalink
Add BuildPackages.sh to files, since GAP refused.
Browse files Browse the repository at this point in the history
  • Loading branch information
culler committed Jun 14, 2023
1 parent 7ceb087 commit bb4e079
Show file tree
Hide file tree
Showing 2 changed files with 309 additions and 7 deletions.
8 changes: 1 addition & 7 deletions Sage_framework/build_sage_framework.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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.
Expand Down
308 changes: 308 additions & 0 deletions Sage_framework/files/BuildPackages.sh
Original file line number Diff line number Diff line change
@@ -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 [email protected] 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 <<GAPInput
Read("PackageInfo.g");
Print(GAPInfo.PackageInfoCurrent.PackageName);
GAPInput
)
local CONFIG_ARGS_FLAG_NAME="PACKAGE_CONFIG_ARGS_${PKG_NAME}"
echo_run ./configure --with-gaproot="$GAPROOT" $CONFIGFLAGS ${!CONFIG_ARGS_FLAG_NAME}
# hack: run `make clean` in case the package was built before with different settings
echo_run "$MAKE" clean
else
echo_run ./configure "$GAPROOT"
# hack: run `make clean` in case the package was built before with different settings
echo_run "$MAKE" clean
# hack: in browse and edim, `make clean` removes `Makefile` so run configure
# again to ensure we can actually build them (we could restrict this hack to
# the two offending packages, but since non-autoconf configure is super cheap,
# there seems little reason to bother)
echo_run ./configure "$GAPROOT"
fi
echo_run "$MAKE"
else
notice "No building required for $PKG"
fi
}

build_one_package() {
# requires one argument which is the package directory
PKG="$1"
[[ $GITHUB_ACTIONS = true ]] && echo "::group::$PKG"
echo ""
date
echo ""
notice "==== Checking $PKG"
( # start subshell
set -e
cd "$CURDIR/$PKG"
if [[ -x prerequisites.sh ]]
then
./prerequisites.sh "$GAPROOT"
fi
run_configure_and_make
) &&
( # start subshell
if [[ $GITHUB_ACTIONS = true ]]
then
echo "::endgroup::"
fi
) || build_fail
}

date >> "$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
# <wait -n> is available) or for all to finish (if only <wait> 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"

0 comments on commit bb4e079

Please sign in to comment.