Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- readonly SBCL_REPO="git://sbcl.git.sourceforge.net/gitroot/sbcl/sbcl.git"
- readonly BASE_DIR="/tmp/sbcl-git-build"
- readonly SOURCE_DIR="$BASE_DIR/src"
- readonly BUILD_DIR="$BASE_DIR/build"
- readonly CROSS_COMPILE_HOST="sbcl --disable-debugger --no-userinit --no-sysinit"
- ########################################################################
- ## SCRIPT
- readonly PROGNAME=$(basename $0)
- readonly PROGDIR=$(readlink -m $(dirname $0))
- readonly ARGS="$@"
- readonly DEFAULT_ACTIONS=(download prepare build install install-sources);
- readonly DEFAULT_ENABLED_FEATURES=":sb-thread :sb-safepoint :sb-thruption :sb-wtimer :sb-core-compression"
- readonly DEFAULT_DISABLED_FEATURES=":largefile :sb-ldb"
- readonly DEFAULT_DYNAMIC_SPACE_SIZE="1Gb"
- readonly DEFAULT_INSTALL_TARGET="/usr/local"
- usage() {
- cat <<- EOF
- usage: $PROGNAME options
- Easily build and install SBCL from source.
- Sources are downloaded to $SOURCE_DIR
- fetching them from $SBCL_REPO
- and building them in $BUILD_DIR
- OPTIONS:
- -a --actions Specify the actions to perform, should be a
- space delimited string of the following choices:
- download prepare build test build-docs install install-sources cleanup
- Defaults to "${DEFAULT_ACTIONS[@]}"
- if -a, -b, and -i are not specified.
- -b --build Adds "download prepare build" to the actions.
- -d --disable Disable certain SBCL features.
- Defaults to "$DEFAULT_DISABLED_FEATURES"
- -e --enable Enable certain SBCL features.
- Defaults to "$DEFAULT_ENABLED_FEATURES"
- -i --install Adds "install install-sources" to the actions.
- -t --target Specify the directory to install SBCL to.
- Defaults to "$DEFAULT_INSTALL_TARGET"
- -h --help Display this help.
- EOF
- }
- contains_element() {
- local e
- for e in "${@:2}"; do
- [ "$e" = "$1" ] && return 0;
- done
- return 1
- }
- status() {
- echo -e "\n\e[0;33m>> \e[0;32m" $@ "\e[0m"
- sleep 1
- }
- eexit() {
- echo -e "\n\e[0;33m>> \e[0;31mError: " $@ "\e[0m"
- exit 1
- }
- try_run() {
- echo "$1" | bash \
- || eexit "$2"
- }
- try_run_sudo() {
- echo "$1" | sudo bash \
- || eexit "$2"
- }
- is_downloaded() {
- return [ -d "$SOURCE_DIR" ]
- }
- is_prepared() {
- return [ -d "$BUILD_DIR" ]
- }
- is_built() {
- return [ -d "$BUILD_DIR/output" ]
- }
- check_downloaded() {
- [ ! is_downloaded ] \
- && eexit "Sources are not available! Run `$PROGNAME -a download` first."
- }
- check_prepared() {
- [ ! is_prepared ] \
- && eexit "Build directory is not available! Run `$PROGNAME -a prepare` first."
- }
- check_built() {
- [ ! is_built ] \
- && eexit "SBCL has not been built yet! Run `$PROGNAME -a \"build\"` first."
- }
- download_source() {
- status "Downloading source..."
- mkdir -p "$SOURCE_DIR"
- if [ -d "$SOURCE_DIR/.git" ]; then
- cd "$SOURCE_DIR"
- git pull \
- || eexit "Failed to download source."
- else
- git clone "$SBCL_REPO" "$SOURCE_DIR" \
- || eexit "Failed to download source."
- fi
- }
- prepare_build() {
- status "Preparing build..."
- check_downloaded
- [ -d "$BUILD_DIR" ] \
- && cleanup_build
- git clone "$SOURCE_DIR" "$BUILD_DIR" \
- || eexit "Failed to prepare build."
- cd "$BUILD_DIR"
- cat >customize-target-features.lisp <<EOF
- (lambda (features)
- (flet ((enable (x) (pushnew x features))
- (disable (x) (setf features (remove x features))))
- (dolist (feature '($ENABLED_FEATURES))
- (enable feature))
- (dolist (feature '($DISABLED_FEATURES))
- (disable feature)))
- features)
- EOF
- }
- build_sbcl() {
- status "Building SBCL..."
- check_prepared
- cd "$BUILD_DIR"
- export CFLAGS="${CFLAGS} -fno-omit-frame-pointer -D_GNU_SOURCE"
- sh make.sh --dynamic-space-size=$DYNAMIC_SPACE_SIZE \
- || eexit "SBCL build failed."
- }
- test_sbcl() {
- status "Testing SBCL..."
- check_built
- cd "$BUILD_DIR/tests"
- sh ./run-tests.sh \
- || eexit "SBCL tests failed."
- }
- build_sbcl_docs() {
- status "Building SBCL docs..."
- check_built
- cd "$BUILD_DIR/doc/manual"
- make \
- || eexit "Failed to build SBCL docs."
- }
- install_sbcl() {
- local command
- status "Installing SBCL..."
- check_built
- cd "$BUILD_DIR"
- unset SBCL_HOME
- command="INSTALL_ROOT=\"$INSTALL_TARGET\" sh install.sh"
- # Attempt to create directory always, suppressing errors
- # This way the -w test will truly check for permissions.
- [ ! -d "$INSTALL_TARGET" ] \
- && mkdir -p "$INSTALL_TARGET" &>/dev/null
- if [ -w "$INSTALL_TARGET" ]; then
- try_run "$command" "SBCL install failed."
- else
- status "Super User privileges required to install to $INSTALL_TARGET"
- try_run_sudo "$command" "SBCL install failed."
- fi
- }
- install_sources() {
- local sources_dir="$INSTALL_TARGET/share/sbcl-source"
- local copy_command="cp -R -t \"$sources_dir\" \"$BUILD_DIR/src\" \"$BUILD_DIR/contrib\""
- local clean_command="find \"$sources_dir\" \
- -name \"*.fasl\" -or \
- -name \"*.o\" -or \
- -name \"*.log\" -or \
- -name \"*.so\" -or \
- -name \"a.out\" -delete"
- local core_command="mv \"$BUILD_DIR/sbcl-sources.core\" \"$INSTALL_TARGET/lib/sbcl/sbcl.core\""
- status "Installing sources..."
- check_built
- cd "$BUILD_DIR"
- cat >setup-sources.lisp <<EOF
- (in-package #:cl-user)
- (let* ((parent (parse-namestring "$sources_dir/")))
- (setf (logical-pathname-translations "SYS")
- \`(("SYS:SRC;**;*.*.*" ,(merge-pathnames "src/" parent))
- ("SYS:CONTRIB;**;*.*.*" ,(merge-pathnames "contrib/" parent)))))
- (ignore-errors
- (sb-ext:gc :full t)
- (sb-ext:enable-debugger)
- (sb-ext:save-lisp-and-die "$BUILD_DIR/sbcl-sources.core"))
- EOF
- status "Creating proper core..."
- src/runtime/sbcl --core output/sbcl.core --no-userinit --no-sysinit --script "$BUILD_DIR/setup-sources.lisp"
- status "Copying..."
- [ ! -d "$sources_dir" ] \
- && mkdir -p "$sources_dir" &>/dev/null
- if [ -w "$sources_dir" ]; then
- try_run "$copy_command" "Source copying failed."
- try_run "$clean_command" "Source cleaning failed."
- try_run "$core_command" "Core copying failed."
- else
- status "Super User privileges required to install sources to $sources_dir"
- try_run_sudo "mkdir -p \"$sources_dir\"" "Failed to create sources dir."
- try_run_sudo "$copy_command" "Source copying failed."
- try_run_sudo "$clean_command" "Source cleaning failed."
- try_run_sudo "$core_command" "Core copying failed."
- fi
- }
- cleanup_build() {
- status "Cleaning up build..."
- rm -rf "$BUILD_DIR"
- }
- perform_actions(){
- local a=("${@}")
- status "Performing actions: ${a[@]}"
- contains_element download "${a[@]}" \
- && download_source
- contains_element prepare "${a[@]}" \
- && prepare_build
- contains_element build "${a[@]}" \
- && build_sbcl
- contains_element test "${a[@]}" \
- && test_sbcl
- contains_element build-docs "${a[@]}" \
- && build_sbcl_docs
- contains_element install "${a[@]}" \
- && install_sbcl
- contains_element install-sources "${a[@]}" \
- && install_sources
- contains_element cleanup "${a[@]}" \
- && cleanup_build
- status "All done."
- }
- cmdline() {
- local arg=
- for arg; do
- local delim=""
- case "$arg" in
- --actions) args="${args}-a ";;
- --build) args="${args}-b ";;
- --disable) args="${args}-d ";;
- --enable) args="${args}-e ";;
- --help) args="${args}-h ";;
- --install) args="${args}-i ";;
- --target) args="${args}-t ";;
- # Pass through anything else
- *) [[ "${arg:0:1}" == "-" ]] || delim="\""
- args="${args}${delim}${arg}${delim} ";;
- esac
- done
- eval set -- $args
- local current_actions=()
- while getopts "a:be:d:hit:" OPTION; do
- case $OPTION in
- a)
- current_actions=($OPTARG)
- ;;
- b)
- current_actions+=(download prepare build)
- ;;
- d)
- readonly DISABLED_FEATURES="$OPTARG"
- ;;
- e)
- readonly ENABLED_FEATURES="$OPTARG"
- ;;
- h)
- usage
- exit 0
- ;;
- i)
- current_actions+=(install install-sources)
- ;;
- t)
- readonly INSTALL_TARGET="$OPTARG"
- ;;
- *)
- eexit "Unknown option given"
- ;;
- esac
- done
- ## Defaulting & Setting
- [ ${#current_actions[@]} -eq 0 ] \
- && readonly ACTIONS=("${DEFAULT_ACTIONS[@]}") \
- || readonly ACTIONS=("${current_actions[@]}")
- [ -z ${ENABLED_FEATURES+x} ] \
- && readonly ENABLED_FEATURES="$DEFAULT_ENABLED_FEATURES"
- [ -z ${DISABLED_FEATURES+x} ] \
- && readonly DISABLED_FEATURES="$DEFAULT_DISABLED_FEATURES"
- [ -z ${INSTALL_TARGET+x} ] \
- && readonly INSTALL_TARGET="$DEFAULT_INSTALL_TARGET"
- [ -z ${DYNAMIC_SPACE_SIZE+x} ] \
- && readonly DYNAMIC_SPACE_SIZE="$DEFAULT_DYNAMIC_SPACE_SIZE"
- perform_actions "${ACTIONS[@]}"
- }
- main() {
- cmdline $ARGS
- exit 0
- }
- main
Advertisement
Add Comment
Please, Sign In to add comment