329 lines
7.6 KiB
Bash
Executable File
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
|