rust-powerpc-unknown-netbsd/build.sh

329 lines
7.6 KiB
Bash
Executable File

#!/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" <<EOF
#!/usr/bin/env bash
exec "$to_wrap" --sysroot="$base_dir/sysroot" "\$@"
EOF
chmod +x "$to_wrap-sysroot"
}
function get_bsd_sets {
for index in ${!files[*]}; do
name=${files[index]}
base="$(basename "$name")"
if [[ ! -f "${base}" ]]; then
printf "Downloading %s..." "$name"
download "${files[index]}"
printf "OK\n"
fi
printf "Checking %s..." "$base"
if ( echo "${sha512[index]} $base" | sha512sum --status -c - ); then
printf "OK\n"
else
fail "Failed"
fi
printf "Extracting %s..." "$base"
extract "$base" "${extract_dirs[index]}" "${paths_to_extract[index]}"
printf "OK\n"
done
}
function build_tools {
cd "$src_dir/usr/src"
MKUNPRIVED=yes TOOLDIR="$ppc_dir" MKSHARE=no MKDOC=no MKHTML=no MKINFO=no \
MKKMOD=no MKLINT=no MKMAN=no MKNLS=no MKPROFILE=no ./build.sh \
-j$nproc -m macppc tools
cd "$working_dir"
gen_sysroot_wrapper "$ppc_dir" "$ppc_gcc"
gen_sysroot_wrapper "$ppc_dir" "$ppc_gxx"
}
function download_rust {
if [[ -d "$rust_dir" ]]; then return; fi
local rustc_src="rustc-$rust_version-src.tar.gz"
printf "Downloading Rust source..."
download "https://static.rust-lang.org/dist/$rustc_src"
printf "OK\n"
printf "Extracting Rust source..."
extract "$rustc_src" ./
printf "OK\n"
mv "$(basename "$rustc_src" .tar.gz)" "$rust_dir"
}
function build_rust {
sed "s%@@tools_dir@@%$ppc_dir%" config.toml | \
sed "s%@@cargo@@%$cargo%" | \
sed "s%@@rustc@@%$rustc%" \
> "$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