#!/usr/bin/env bash # prints continuous output to avoid timeouts on build systems like Travis function display_progress { local str="" while [ "$(ps a | awk '{print $1}' | grep ${1})" ]; do printf "%c" "$str" sleep 15 str="." done } # kills child processes function die_gracefully { trap - EXIT INT trap ":" INT # prevent recursion due to spamming ctrl-c echo "" trap - TERM && kill -- -$$ } function mac_toolchain_build { set -o pipefail # mac only if [[ "$(uname)" != "Darwin" ]]; then echo "macOS/Darwin required" >&2 exit 1 fi # vars PREFIX="${1:-/usr/local}" CREL=$(echo -e "\r"$(tput el)) if ! MAKEJOBS=$(sysctl -n hw.ncpu 2>/dev/null); then MAKEJOBS="4" fi SUDO= TOTAL=6 # functions function print_fail_and_exit { echo -en " [FAIL]\n" echo "Logs and temporary files remain at: ${TEMP_DIR:-}" >&2 exit 1 } # permissions mkdir -p "${PREFIX}" >/dev/null 2>&1 if [[ ! -w "${PREFIX}" ]]; then if ! sudo -n date >/dev/null 2>&1; then echo "sudo is required to install files to ${PREFIX}" [[ "${SUDO}" != "" ]] && ${SUDO} -v fi sudo mkdir -p "${PREFIX}" >/dev/null 2>&1 if sudo touch "${PREFIX}" >/dev/null 2>&1; then SUDO=sudo else echo "Unable to write to directory: ${PREFIX}" >&2 exit 1 fi fi PREFIX=$(cd "${PREFIX}" && pwd -P) PATH_ORIG="${PATH}" export PATH="${PREFIX}/bin${PATH:+:$PATH}" # temp dir TEMP_DIR=$(mktemp -d "${TMPDIR:-/tmp/}toolchain-XXXXXX") if [[ $? -ne 0 ]]; then echo "Unable to create temporary directory" >&2 exit 1 fi cd "${TEMP_DIR}" # download printf "Downloading [%02i/%02i] %s " "1" "${TOTAL}" "autoconf 2.69" curl -Lf --connect-timeout 30 https://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz -o "autoconf-2.69.tar.gz" >/dev/null 2>&1 || print_fail_and_exit echo -en "${CREL}" printf "Downloading [%02i/%02i] %s " "2" "${TOTAL}" "automake 1.15.1" curl -Lf --connect-timeout 30 https://ftp.gnu.org/gnu/automake/automake-1.15.1.tar.gz -o "automake-1.15.1.tar.gz" >/dev/null 2>&1 || print_fail_and_exit echo -en "${CREL}" printf "Downloading [%02i/%02i] %s " "3" "${TOTAL}" "cmake 3.9.6" curl -Lf --connect-timeout 30 https://cmake.org/files/v3.9/cmake-3.9.6.tar.gz -o "cmake-3.9.6.tar.gz" >/dev/null 2>&1 || print_fail_and_exit echo -en "${CREL}" printf "Downloading [%02i/%02i] %s " "4" "${TOTAL}" "libtool 2.4.6" curl -Lf --connect-timeout 30 https://ftp.gnu.org/gnu/libtool/libtool-2.4.6.tar.gz -o "libtool-2.4.6.tar.gz" >/dev/null 2>&1 || print_fail_and_exit echo -en "${CREL}" printf "Downloading [%02i/%02i] %s " "5" "${TOTAL}" "pkg-config 0.29.2" curl -Lf --connect-timeout 30 https://pkg-config.freedesktop.org/releases/pkg-config-0.29.2.tar.gz -o "pkg-config-0.29.2.tar.gz" >/dev/null 2>&1 || print_fail_and_exit echo -en "${CREL}" printf "Downloading [%02i/%02i] %s " "6" "${TOTAL}" "nasm 2.13.02" curl -Lf --connect-timeout 30 https://www.nasm.us/pub/nasm/releasebuilds/2.13.02/nasm-2.13.02.tar.bz2 -o "nasm-2.13.02.tar.bz2" >/dev/null 2>&1 || print_fail_and_exit echo -en "${CREL}" printf "Downloading [%02i/%02i] complete.\n" "${TOTAL}" "${TOTAL}" # autoconf cd "${TEMP_DIR}" printf "Building [%02i/%02i] %s " "1" "${TOTAL}" "autoconf 2.69" [[ "${SUDO}" != "" ]] && ${SUDO} -v tar -xf autoconf-2.69.tar.gz >/dev/null 2>&1 || print_fail_and_exit cd autoconf-2.69 >/dev/null 2>&1 || print_fail_and_exit ./configure --prefix="${PREFIX}" >../autoconf-2.69.log 2>&1 || print_fail_and_exit make --jobs="${MAKEJOBS}" >>../autoconf-2.69.log 2>&1 || print_fail_and_exit ${SUDO} make install >>../autoconf-2.69.log 2>&1 || print_fail_and_exit echo -en "${CREL}" # automake cd "${TEMP_DIR}" printf "Building [%02i/%02i] %s " "2" "${TOTAL}" "automake 1.15.1" [[ "${SUDO}" != "" ]] && ${SUDO} -v tar -xf automake-1.15.1.tar.gz >/dev/null 2>&1 || print_fail_and_exit cd automake-1.15.1 >/dev/null 2>&1 || print_fail_and_exit ./configure --prefix="${PREFIX}" >../automake-1.15.1.log 2>&1 || print_fail_and_exit make --jobs="${MAKEJOBS}" >>../automake-1.15.1.log 2>&1 || print_fail_and_exit ${SUDO} make install >>../automake-1.15.1.log 2>&1 || print_fail_and_exit echo -en "${CREL}" # cmake cd "${TEMP_DIR}" echo "You may safely dismiss and ignore any prompt to install Java." printf "Building [%02i/%02i] %s " "3" "${TOTAL}" "cmake 3.9.6" [[ "${SUDO}" != "" ]] && ${SUDO} -v tar -xf cmake-3.9.6.tar.gz >/dev/null 2>&1 || print_fail_and_exit cd cmake-3.9.6 >/dev/null 2>&1 || print_fail_and_exit ./configure --prefix="${PREFIX}" --no-qt-gui --system-curl >../cmake-3.9.6.log 2>&1 || print_fail_and_exit make --jobs="${MAKEJOBS}" >>../cmake-3.9.6.log 2>&1 || print_fail_and_exit ${SUDO} make install >>../cmake-3.9.6.log 2>&1 || print_fail_and_exit # libtool cd "${TEMP_DIR}" printf "Building [%02i/%02i] %s " "4" "${TOTAL}" "libtool 2.4.6" [[ "${SUDO}" != "" ]] && ${SUDO} -v tar -xf libtool-2.4.6.tar.gz >/dev/null 2>&1 || print_fail_and_exit cd libtool-2.4.6 >/dev/null 2>&1 || print_fail_and_exit ./configure --prefix="${PREFIX}" >../libtool-2.4.6.log 2>&1 || print_fail_and_exit make --jobs="${MAKEJOBS}" >>../libtool-2.4.6.log 2>&1 || print_fail_and_exit ${SUDO} make install >>../libtool-2.4.6.log 2>&1 || print_fail_and_exit echo -en "${CREL}" # pkg-config cd "${TEMP_DIR}" printf "Building [%02i/%02i] %s " "5" "${TOTAL}" "pkg-config 0.29.2" [[ "${SUDO}" != "" ]] && ${SUDO} -v tar -xf pkg-config-0.29.2.tar.gz >/dev/null 2>&1 || print_fail_and_exit cd pkg-config-0.29.2 >/dev/null 2>&1 || print_fail_and_exit ./configure --prefix="${PREFIX}" --with-internal-glib --disable-host-tool >../pkg-config-0.29.2.log 2>&1 || print_fail_and_exit make --jobs="${MAKEJOBS}" >>../pkg-config-0.29.2.log 2>&1 || print_fail_and_exit ${SUDO} make install >>../pkg-config-0.29.2.log 2>&1 || print_fail_and_exit echo -en "${CREL}" # nasm cd "${TEMP_DIR}" printf "Building [%02i/%02i] %s " "6" "${TOTAL}" "nasm 2.13.02" [[ "${SUDO}" != "" ]] && ${SUDO} -v tar -xf nasm-2.13.02.tar.bz2 >/dev/null 2>&1 || print_fail_and_exit cd nasm-2.13.02 >/dev/null 2>&1 || print_fail_and_exit ./configure --prefix="${PREFIX}" --enable-sections --enable-lto >../nasm-2.13.02.log 2>&1 || print_fail_and_exit make --jobs="${MAKEJOBS}" AR=ar RANLIB=ranlib >>../nasm-2.13.02.log 2>&1 || print_fail_and_exit ${SUDO} make install >>../nasm-2.13.02.log 2>&1 || print_fail_and_exit echo -en "${CREL}" # done printf "Building [%02i/%02i] complete.\n" "${TOTAL}" "${TOTAL}" rm -rf "${TEMP_DIR}" if [[ "${PREFIX}" != "/usr/local" ]]; then echo "bin: ${PREFIX}/bin" echo " add to your shell startup script (${HOME}/.bash_profile):" echo " export PATH=\"${PREFIX}/bin:\${PATH}\"" fi # restore original PATH export PATH="${PATH_ORIG}" set +o pipefail } trap die_gracefully EXIT INT TERM mac_toolchain_build "${@}" & PID=$! display_progress "${PID}" wait "${PID}" || CODE=$? trap - EXIT INT TERM exit "${CODE:-0}"