1#!/usr/local/bin/bash 2 3# This script attempts to build all GAP packages contained in the current 4# directory. Normally, you should run this script from the 'pkg' 5# subdirectory of your GAP installation. 6 7# You can also run it from other locations, but then you need to tell the 8# script where your GAP root directory is, by passing it as an argument 9# to the script with '--with-gaproot='. By default, the script assumes that 10# the parent of the current working directory is the GAP root directory. 11 12# If arguments are added, then they are considered packages. In that case 13# only these packages will be built, and all others are ignored. 14 15# You need at least 'gzip', GNU 'tar', a C compiler, sed, pdftex to run this. 16# Some packages also need a C++ compiler. 17 18# Contact support@gap-system.org for questions and complaints. 19 20# Note, that this isn't and is not intended to be a sophisticated script. 21# Even if it doesn't work completely automatically for you, you may get 22# an idea what to do for a complete installation of GAP. 23 24set -e 25 26# Is someone trying to run us from inside the 'bin' directory? 27if [[ -f gapicon.bmp ]] 28then 29 error "This script must be run from inside the pkg directory" \ 30 "Type: cd ../pkg; ../bin/BuildPackages.sh" 31fi 32 33CURDIR="$(pwd)" 34GAPROOT="$(cd .. && pwd)" 35COLORS=yes 36STRICT=no # exit with non-zero exit code when encountering any failures 37PACKAGES=() 38 39# If output does not go into a terminal (but rather into a log file), 40# turn off colors. 41[[ -t 1 ]] || COLORS=no 42 43while [[ "$#" -ge 1 ]]; do 44 option="$1" ; shift 45 case "$option" in 46 --with-gaproot) GAPROOT="$1"; shift ;; 47 --with-gaproot=*) GAPROOT=${option#--with-gaproot=}; ;; 48 49 --no-color) COLORS=no ;; 50 --color) COLORS=yes ;; 51 52 --no-strict) STRICT=no ;; 53 --strict) STRICT=yes ;; 54 --add-package-config-*) typeset PACKAGE_CONFIG_ARGS_${option:21}="$1"; shift ;; 55 56 -*) echo "ERROR: unsupported argument $option" ; exit 1;; 57 *) PACKAGES+=("$option") ;; 58 esac 59done 60 61# If user specified no packages to build, build all packages in subdirectories. 62if [[ ${#PACKAGES[@]} == 0 ]] 63then 64 # Put package directory names into a bash array to avoid issues with 65 # spaces in filenames. This code will still break if there are newlines 66 # in the name. 67 old_IFS=$IFS 68 IFS=$'\n' PACKAGES=($(find . -maxdepth 2 -type f -name PackageInfo.g)) 69 IFS=$old_IFS 70 PACKAGES=( "${PACKAGES[@]%/PackageInfo.g}" ) 71fi 72 73# Some helper functions for printing user messages 74if [[ "x$COLORS" = xyes ]] 75then 76 # print notices in green, warnings in yellow, errors in read 77 notice() { printf "\033[32m%s\033[0m\n" "$@" ; } 78 warning() { printf "\033[33mWARNING: %s\033[0m\n" "$@" ; } 79 error() { printf "\033[31mERROR: %s\033[0m\n" "$@" ; exit 1 ; } 80 std_error() { printf "\033[31m%s\033[0m\n" "$@" ; } 81else 82 notice() { printf "%s\n" "$@" ; } 83 warning() { printf "WARNING: %s\n" "$@" ; } 84 error() { printf "ERROR: %s\n" "$@" ; exit 1 ; } 85 std_error() { printf "%s\n" "$@" ; } 86fi 87 88 89notice "Using GAP root $GAPROOT" 90 91# Check whether $GAPROOT is valid 92if [[ ! -f "$GAPROOT/sysinfo.gap" ]] 93then 94 error "$GAPROOT is not the root of a gap installation (no sysinfo.gap)" \ 95 "Please provide the absolute path of your GAP root directory as" \ 96 "first argument with '--with-gaproot=' to this script." 97fi 98 99# read in sysinfo 100source "$GAPROOT/sysinfo.gap" 101 102# detect whether GAP was built in 32bit mode 103# TODO: once all packages have adapted to the new build system, 104# this should no longer be necessary, as package build systems should 105# automatically adjust to 32bit mode. 106case "$GAP_ABI" in 107 32) 108 notice "Building with 32-bit ABI" 109 CONFIGFLAGS="CFLAGS=-m32 LDFLAGS=-m32 LOPTS=-m32 CXXFLAGS=-m32" 110 ;; 111 64) 112 notice "Building with 64-bit ABI" 113 CONFIGFLAGS="" 114 ;; 115 *) 116 error "Unsupported GAP ABI '$GAParch_abi'." 117 ;; 118esac 119 120 121LOGDIR=log 122mkdir -p "$LOGDIR" 123 124 125# Many package require GNU make. So use gmake if available, 126# for improved compatibility with *BSD systems where "make" 127# is BSD make, not GNU make. 128if hash gmake 2> /dev/null 129then 130 MAKE=gmake 131else 132 MAKE=make 133fi 134 135notice \ 136"Attempting to build GAP packages." \ 137"Note that many GAP packages require extra programs to be installed," \ 138"and some are quite difficult to build. Please read the documentation for" \ 139"packages which fail to build correctly, and only worry about packages" \ 140"you require!" 141 142# print the given command plus arguments, single quoted, then run it 143echo_run() { 144 # when printf is given a format string with only one format specification, 145 # it applies that format string to each argument in sequence 146 notice "Running $(printf "'%s' " "$@")" 147 "$@" 148} 149 150build_fail() { 151 echo "" 152 warning "Failed to build $PKG" 153 echo "$PKG" >> "$LOGDIR/fail.log" 154 if [[ $STRICT = yes ]] 155 then 156 exit 1 157 fi 158} 159 160run_configure_and_make() { 161 # We want to know if this is an autoconf configure script 162 # or not, without actually executing it! 163 if [[ -f autogen.sh && ! -f configure ]] 164 then 165 ./autogen.sh 166 fi 167 if [[ -f "configure" ]] 168 then 169 if grep Autoconf ./configure > /dev/null 170 then 171 local PKG_NAME=$($GAPROOT/gap -q -T -A <<GAPInput 172Read("PackageInfo.g"); 173Print(GAPInfo.PackageInfoCurrent.PackageName); 174GAPInput 175) 176 local CONFIG_ARGS_FLAG_NAME="PACKAGE_CONFIG_ARGS_${PKG_NAME}" 177 echo_run ./configure --with-gaproot="$GAPROOT" $CONFIGFLAGS ${!CONFIG_ARGS_FLAG_NAME} 178 echo_run "$MAKE" clean 179 else 180 echo_run ./configure "$GAPROOT" 181 echo_run "$MAKE" clean 182 echo_run ./configure "$GAPROOT" 183 fi 184 echo_run "$MAKE" 185 else 186 notice "No building required for $PKG" 187 fi 188} 189 190build_one_package() { 191 # requires one argument which is the package directory 192 PKG="$1" 193 echo "" 194 date 195 echo "" 196 notice "==== Checking $PKG" 197 ( # start subshell 198 set -e 199 cd "$CURDIR/$PKG" 200 case "$PKG" in 201 # All but the last lines should end by '&&', otherwise (for some reason) 202 # some packages that fail to build will not get reported in the logs. 203 atlasrep*) 204 chmod 1777 datagens dataword 205 ;; 206 207 NormalizInterface*) 208 ./build-normaliz.sh "$GAPROOT" && \ 209 run_configure_and_make 210 ;; 211 212 pargap*) 213 echo_run ./configure --with-gap="$GAPROOT" && \ 214 echo_run "$MAKE" && \ 215 cp bin/pargap.sh "$GAPROOT/bin" && \ 216 rm -f ALLPKG 217 ;; 218 219 xgap*) 220 echo_run ./configure --with-gaproot="$GAPROOT" && \ 221 echo_run "$MAKE" && \ 222 rm -f "$GAPROOT/bin/xgap.sh" && \ 223 cp bin/xgap.sh "$GAPROOT/bin" 224 ;; 225 226 simpcomp*) 227 # Old versions of simpcomp were not setting the executable 228 # bit for some files; they also were not copying the bistellar 229 # executable to the right place 230 (chmod a+x configure depcomp install-sh missing || :) && \ 231 run_configure_and_make && \ 232 mkdir -p bin && test -x bin/bistellar || mv bistellar bin 233 ;; 234 235 *) 236 run_configure_and_make 237 ;; 238 esac 239 ) || build_fail 240} 241 242date >> "$LOGDIR/fail.log" 243for PKG in "${PACKAGES[@]}" 244do 245 # cut off the ending slash (if exists) 246 PKG="${PKG%/}" 247 # cut off everything before the first slash to only keep the package name 248 # (these two commands are mainly to accomodate the logs better, 249 # as they make no difference with changing directories) 250 PKG="${PKG##*/}" 251 if [[ -e "$CURDIR/$PKG/PackageInfo.g" ]] 252 then 253 (build_one_package "$PKG" \ 254 > >(tee "$LOGDIR/$PKG.out") \ 255 2> >(while read line 256 do \ 257 std_error "$line" 258 done \ 259 > >(tee "$LOGDIR/$PKG.err" >&2) \ 260 ) \ 261 )> >(tee "$LOGDIR/$PKG.log" ) 2>&1 262 263 # remove superfluous log files if there was no error message 264 if [[ ! -s "$LOGDIR/$PKG.err" ]] 265 then 266 rm -f "$LOGDIR/$PKG.err" 267 rm -f "$LOGDIR/$PKG.out" 268 fi 269 270 # remove log files if package needed no compilation 271 if [[ "$(grep -c 'No building required for' $LOGDIR/$PKG.log)" -ge 1 ]] 272 then 273 rm -f "$LOGDIR/$PKG.err" 274 rm -f "$LOGDIR/$PKG.out" 275 rm -f "$LOGDIR/$PKG.log" 276 fi 277 else 278 echo 279 warning "$PKG does not seem to be a package directory, skipping" 280 fi 281done 282 283echo "" >> "$LOGDIR/fail.log" 284echo "" 285notice "Packages which failed to build are in ./$LOGDIR/fail.log" 286