#!/bin/sh -e ### # Basic sanity. ### set -e [ -z $ZSH_VERSION ] || set -y readonly APK=abuild-apk readonly DEF_ARCH=$(uname -m) readonly DEF_TD=${HOME}/builds readonly DISTRO_NAME="Adélie Linux" readonly PROGNAME=$(basename $0) export PATH=/usr/bin:`$(command -v getconf || echo false) CS_PATH || echo /usr/local/bin:/usr/bin:/bin`:/usr/local/sbin:/usr/sbin:/sbin ### # Messaging utility functions. ### info() { printf '\033[01;32m>>>\033[00;39m %s\n' "$1" } warn() { printf '\033[01;33m>>> WARNING\033[00;39m: %s\n' "$1" } error() { printf '\033[01;31m>>> ERROR\033[00;39m: %s\n' "$1" } ### # Check for required utilities. ### if ! command -v ${APK}>/dev/null 2>/dev/null; then printf "APK Tools must be present to bootstrap ${DISTRO_NAME}.\n" error "apk (as ${APK}): not found in $PATH" exit 127 fi if ! command -v abuild>/dev/null 2>/dev/null; then printf "abuild must be present to bootstrap ${DISTRO_NAME}.\n" error "abuild: not found in $PATH" exit 127 fi ### # Provide the user with help, if requested or needed. ### usage() { printf 'usage: %s [-a ARCH] [-b PATH] [-h HOSTC] [-k KEYDIR] [-p PATH] [-t TARGC] [-v] [--help]\n\n' $PROGNAME printf 'Creates a local cross-compiler, and uses it to create a small\n' printf 'bootstrap environment, capable of building itself.\n\n' printf 'This environment can be used to seed autobuilder, to verify\n' printf 'correctness and reproducibility of builds, or to perform\n' printf 'any number of scientific experiments.\n\n' printf 'Default ARCH: %s\n' $DEF_ARCH printf 'Default root for TARGET_DIRs: %s\n' $DEF_TD } ### # Determine the desired output. ### while [ -n "$1" ]; do case $1 in -a | --arch) shift readonly MY_ARCH=$1 ;; -b | --build-path) shift readonly MY_BUILDPATH=$1 ;; -h | --host-conf) shift readonly MY_HOSTCONF=$1 ;; --help) usage exit ;; -k | --key-dir) shift readonly MY_KEYDIR=$1 ;; -p | --path) shift readonly MY_TD=$1 ;; -t | --target-conf) shift readonly MY_TARGCONF=$1 ;; -v | --verbose) readonly BE_VERBOSE= ;; *) usage >&2 exit 127 ;; esac shift done readonly ARCH=${MY_ARCH:-$DEF_ARCH} readonly BUILD_PATH=${MY_BUILDPATH:-$PWD} readonly KEY_DIR=${MY_KEYDIR:-/etc/apk/keys} readonly TARGET_DIR=${MY_TD:-${DEF_TD}/${ARCH}} ### # Here comes the pain! ### [ -z ${BE_VERBOSE+v} ] || ( info "Building the target environment:" info " " info "ARCH: $ARCH" info "TARGET_DIR: $TARGET_DIR" info "Using APKBUILDs from: $BUILD_PATH" info "Using keys from: $KEY_DIR" [ -z ${MY_HOSTCONF} ] || info "Host-side abuild.conf: $MY_HOSTCONF" [ -z ${MY_TARGCONF} ] || info "Target-side abuild.conf: $MY_TARGCONF" printf '\n' ) info "Building stage1 bootstrap tools ($(uname -m) -> $ARCH)..." [ -z ${BE_VERBOSE+v} ] || info 'Setting up APK...' mkdir -p "$TARGET_DIR"/etc/apk/keys cp -a "$KEY_DIR"/* "$TARGET_DIR"/etc/apk/keys/ ${APK} add ${BE_VERBOSE---quiet} --usermode --initdb --arch $ARCH --root "$TARGET_DIR" [ -z ${BE_VERBOSE+v} ] || info 'Setting up configuration...' if [ -z ${MY_HOSTCONF} ]; then if [ -f "$TARGET_DIR"/etc/abuild.conf.host ]; then [ -z ${BE_VERBOSE+v} ] || info 'Host-side configuration reused.' else cat >"$TARGET_DIR"/etc/abuild.conf.host <"$TARGET_DIR"/etc/abuild.conf.target <"$TARGET_DIR"/$(date +%s)-$1.log else abuild -r fi ) || (error "building $1. Stop."; false) } abuild_target() { EXTRADEPENDS_TARGET="musl musl-dev" CHOST=$ARCH BOOTSTRAP=bootimage APKBUILD=${BUILD_PATH}/system/$1/APKBUILD ABUILD_CONF="$TARGET_DIR"/etc/abuild.conf.target CBUILDROOT="$TARGET_DIR" abuild -r } CTARGET=$ARCH BOOTSTRAP=nobase abuild_host binutils CHOST=$ARCH BOOTSTRAP=nocc abuild_host musl EXTRADEPENDS_TARGET=musl-dev CTARGET=$ARCH BOOTSTRAP=nolibc abuild_host gcc EXTRADEPENDS_BUILD=gcc-pass2-$ARCH CHOST=$ARCH BOOTSTRAP=nolibc abuild_host musl EXTRADEPENDS_BUILD=gcc-pass2-$ARCH EXTRADEPENDS_TARGET="musl musl-dev" CTARGET=$ARCH BOOTSTRAP=nobase abuild_host gcc for next_pkg in musl dash pkgconf zlib \ gettext-tiny ncurses bash binutils make bison flex m4 \ openssl apk-tools gmp mpfr3 mpc1 isl gcc; do abuild_target $next_pkg done