commit 7322aaa0968b55ea1f76ddbe7830155621bbbf31 Author: Kevin Cotugno Date: Tue Apr 21 12:38:28 2020 -0700 Initial commit diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 0000000..31724fa --- /dev/null +++ b/.cargo/config @@ -0,0 +1,6 @@ +[source.crates-io] +replace-with = 'vendored-sources' +registry = 'https://example.com' + +[source.vendored-sources] +directory = '/home/kcotugno/devel/rust-std-powerpc-unknown-netbsd/rust/vendor' diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bfaf0aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.tgz +*.tar.gz +tools_built +src/ +rust*/ +powerpc-unknown-netbsd/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..204fc65 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Kevin Cotugno + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6cd54b5 --- /dev/null +++ b/README.md @@ -0,0 +1,35 @@ +A script for building the Rust compiler with the standard library for +cross-building for PowerPC NetBSD. + +This script has only been tested on ArchLinux. + +# Dependencies + +```bash +sudo pacman -S llvm rustup curl +``` + +# Build + +```bash +./build.sh build +``` + +# Install +```bash +sudo ./build.sh install +``` + +# Link +Link a rustup toolchain for use. +```bash +./build.sh link +``` + +To build a cargo project, ensure `.cargo/config` exists with the contents: +```toml +[target.powerpc-unknown-netbsd] +linker = "powerpc--netbsd-gcc" +``` + +Then run `cargo +powerpc build --target=powerpc-unknown-netbsd` diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..be5be32 --- /dev/null +++ b/build.sh @@ -0,0 +1,328 @@ +#!/usr/bin/env bash +set -e + +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 + 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 diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..8a77bb5 --- /dev/null +++ b/config.toml @@ -0,0 +1,32 @@ +[llvm] +link-shared = true + +[build] +target = ["x86_64-unknown-linux-gnu", "powerpc-unknown-netbsd"] +cargo = "@@cargo@@" +rustc = "@@rustc@@" +python = "/usr/bin/python" +extended = true +sanitizers = false +profiler = false +vendor = true +docs = false + +[rust] +codegen-units-std = 1 +debuginfo-level = 2 +channel = "stable" +rpath = false +deny-warnings = false + +[target.x86_64-unknown-linux-gnu] +llvm-config = "/usr/bin/llvm-config" + +[target.powerpc-unknown-netbsd] +llvm-config = "/usr/bin/llvm-config" +cc = "@@tools_dir@@/bin/powerpc--netbsd-gcc-sysroot" +cxx = "@@tools_dir@@/bin/powerpc--netbsd-g++-sysroot" +ar = "@@tools_dir@@/bin/powerpc--netbsd-ar" + +[dist] +src-tarball = false