#!/usr/bin/env bash set -eo pipefail nproc=$(($(nproc) * 2)) triple="powerpc-unknown-netbsd" rust_version=1.42.0 netbsd_binary_base_url="http://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/macppc/binary/sets" netbsd_src_base_url="http://cdn.netbsd.org/pub/NetBSD/NetBSD-9.0/source/sets" working_dir="$PWD" ppc_dir="$working_dir/$triple" sysroot_dir="$ppc_dir/sysroot" src_dir="$working_dir/src" rust_dir="$working_dir/rust" rust_build_dir="$working_dir/rust-build" rust_tar="$rust_build_dir/build/dist/rust-$rust_version-x86_64-unknown-linux-gnu.tar.gz" rustc_dir="$working_dir/$(basename "$rust_tar" .tar.gz)" powerpc_std_tar="$rust_build_dir/build/dist/rust-std-$rust_version-$triple.tar.gz" power_std_dir="$working_dir/$(basename "$powerpc_std_tar" .tar.gz)" ppc_gcc="powerpc--netbsd-gcc" ppc_gxx="powerpc--netbsd-g++" files=( "$netbsd_binary_base_url/base.tgz" "$netbsd_binary_base_url/comp.tgz" "$netbsd_src_base_url/gnusrc.tgz" "$netbsd_src_base_url/sharesrc.tgz" "$netbsd_src_base_url/src.tgz" "$netbsd_src_base_url/syssrc.tgz" ) sha512=( "77bf2c9d41a64f186d260802930ac123100453ea081ca51f1b7515fb09c687a06a0285757001ee57d8c63acc42934cafee5af30e75cdde50e69f574230ea29ee" "557f9308fe2d1e4e930bd3d9bc6f1fd32290f7428c4587c60473ab52daec96cfd554a085520d1d503576a618bc1921153faedaf2012b83c39ee6318790fd1c13" "3710085a73feecf6a843415271ec794c90146b03f6bbd30f07c9e0c79febf8995d557e40194f1e05db655e4f5ef2fae97563f8456fceaae65d4ea98857a83b1c" "f080776ed82c3ac5d6272dee39746f87897d8e6984996caf5bf6d87bf11d9c9e0c1ad5c437c21258bd278bb6fd76974946e878f548517885f71c556096231369" "2c791ae009a6929c6fc893ec5df7e62910ee8207e0b2159d6937309c03efe175b6ae1e445829a13d041b6851334ad35c521f2fa03c97675d4a05f1fafe58ede0" "60b9ddf4cc6402256473e2e1eefeabd9001aa4e205208715ecc6d6fc3f5b400e469944580077271b8e80562a4c2f601249e69e07a504f46744e0c50335f1cbf1" ) extract_dirs=( "$sysroot_dir" "$sysroot_dir" "$src_dir" "$src_dir" "$src_dir" "$src_dir" ) paths_to_extract=( "./usr/include ./usr/lib ./lib" "./usr/include ./usr/lib" ) function fail { local message="$1" printf "%s\n" "$message" exit 1 } function download { local url="$1" curl "$curl_opts" "$url" } function extract { local file="$1" local x_dir="$2" local paths="$3" # shellcheck disable=SC2086 tar "$tar_opts" "$file" -C "$x_dir" $paths } function gen_sysroot_wrapper { local base_dir="$1" local to_wrap="$base_dir/bin/$2" cat - > "$to_wrap-sysroot" < "$rust_build_dir/config.toml" cd "$rust_build_dir" "$rust_dir/x.py" build -j "$nproc" "$rust_dir/x.py" dist -j "$nproc" cd "$working_dir" } function rust_install_script { local script="$1" if [[ -n "$verbose" ]]; then "$script/install.sh" --prefix="$prefix" else "$script/install.sh" --prefix="$prefix" > /dev/null fi } function install_rust { if [[ ! -d "$rustc_dir" ]]; then printf "Extracting Rust compiler and tools for host..." extract "$rust_tar" ./ printf "OK\n" fi printf "Installing Rust for host..." rust_install_script "$rustc_dir" printf "OK\n" if [[ ! -d "$power_std_dir" ]]; then printf "Extracting Rust for %s..." "$triple" extract "$powerpc_std_tar" ./ printf "OK\n" fi printf "Installing Rust STD for %s..." "$triple" rust_install_script "$power_std_dir" printf "OK\n" } function uninstall_rust { printf "Uninstalling Rust std for %s..." "$triple" printf "OK\n" } function clean { printf "Cleaning..." rm -rf ./*.tgz ./*.tar.gz "$src_dir" "$ppc_dir" "$working_dir/rust*" ./rust*/ tools_built .cargo/ printf "OK\n" } function install_ppc_tools { printf "Copying powerpc NetBSD tools..." cp -r "$ppc_dir" "$prefix" gen_sysroot_wrapper "$prefix" "$ppc_gcc" gen_sysroot_wrapper "$prefix" "$ppc_gxx" ln -s "$prefix/bin/powerpc--netbsd-gcc-sysroot" "/usr/local/bin/powerpc--netbsd-gcc" ln -s "$prefix/bin/powerpc--netbsd-g++-sysroot" "/usr/local/bin/powerpc--netbsd-g++" printf "OK\n" } function uninstall_ppc_tools { if [[ "$prefix" = "/" ]]; then fail "Cannot use root (/) as prefix" else rm -rf "$prefix" rm "/usr/local/bin/powerpc--netbsd-gcc" rm "/usr/local/bin/powerpc--netbsd-g++" fi } function check_command { local command=( "$@" ) if [[ -n "$verbose" ]]; then exec "${command[@]}" else exec "${command[@]}" 2> /dev/null fi } function build { if [[ ! $(command -v llvm-config) ]]; then fail "No llvm-config found"; fi if [[ ! $(command -v rustup) ]]; then fail "No rustup found"; fi if [[ ! $(check_command rustup which cargo) ]]; then fail "No cargo found"; fi if [[ ! $(check_command rustup which rustc) ]]; then fail "No rustc found"; fi cargo="$(rustup which cargo)" rustc="$(rustup which rustc)" mkdir -p "$sysroot_dir" "$src_dir" "$ppc_dir/bin" "$rust_build_dir" if [[ ! -f "tools_built" ]]; then get_bsd_sets build_tools touch tools_built fi download_rust build_rust } function install { install_ppc_tools install_rust } function uninstall { uninstall_ppc_tools } function link { rustup toolchain link powerpc "$prefix" } function unlink { if [[ -n "$verbose" ]]; then rustup toolchain uninstall powerpc else rustup toolchain uninstall powerpc 2> /dev/null fi } function print_usage { printf "Usage: %s [-v] command\n" "$(basename "$0")" printf "Options:\n" printf " -p Set the (un)install prefix\n" printf " -v Use verbose output\n" printf "\n" printf "Commands:\n" printf " build Build the cross-compiler and then Rust\n" printf " clean Clean working directory for clean build\n" printf " install Install Rust to the given prefix\n" printf " (/usr/local/%s)\n" "$triple" printf " uninstall Uninstall Rust from the given prefix and remove\n" printf " from rustup\n" printf " link Link to rustup toolchain\n" printf " unlink Unlink rustup toolchain\n" printf " help Print this message\n" } prefix="/usr/local/$triple" while getopts vp: opt do case $opt in v) verbose=1;; p) prefix="$(realpath "$OPTARG")";; ?) print_usage exit 2;; esac done if [[ -n "$verbose" ]]; then curl_opts=-LO tar_opts=xzvf else curl_opts=-sSLO tar_opts=xzf fi if [[ "$prefix" = "/" ]]; then fail "Cannot use root (/) as prefix"; fi shift $((OPTIND - 1)) case "$1" in build) build;; clean) clean;; install) install;; uninstall) uninstall;; link) link;; unlink) unlink;; help) print_usage;; *) print_usage exit 2 esac