| Build under buck2, with the toolchain pinned rather than found 460541b nandi 19d ago | 1 | #!/bin/sh |
| 2 | # rustc from a pinned upstream tarball (scripts/rustc.dotslash). |
| 3 | # |
| 4 | # The Rust dist tarball keeps its components in sibling directories, so the |
| 5 | # compiler's default sysroot (rustc/) holds no libstd — it lives under |
| 6 | # rust-std-<triple>/. Point --sysroot at that sibling; the compiler's own |
| 7 | # codegen libraries are still found via rpath, relative to the binary. |
| 8 | set -e |
| 9 | dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) |
| 10 | exe=$(dotslash -- fetch "$dir/rustc.dotslash") |
| 11 | |
| 12 | # Callers that set their own sysroot win — buck2's rustc_cfg action passes an |
| 13 | # empty --sysroot, and rustc rejects the option being given twice. |
| 14 | for arg in "$@"; do |
| 15 | case $arg in |
| 16 | --sysroot|--sysroot=*) exec "$exe" "$@" ;; |
| 17 | esac |
| 18 | done |
| 19 | |
| 20 | root=$(dirname -- "$(dirname -- "$(dirname -- "$exe")")") |
| 21 | host_std= |
| 22 | for std in "$root"/rust-std-*/; do |
| 23 | host_std=${std%/} |
| 24 | break |
| 25 | done |
| 26 | [ -n "$host_std" ] || { echo "scripts/rustc: no rust-std component under $root" >&2; exit 1; } |
| 27 | |
| 28 | # Cross-compiling needs one sysroot holding both triples: the host's, for proc |
| 29 | # macros and build scripts, and the target's, for the crate being built. The |
| 30 | # components ship as separate tarballs, so stitch them together as a symlink |
| 31 | # farm — cheap to build, and stable enough to cache across invocations. |
| 32 | # |
| 33 | # buck2 passes rustc its arguments in an @argsfile, so --target is usually not |
| 34 | # in argv at all; look inside those too. |
| 35 | scan_target() { |
| 36 | prev= |
| 37 | for arg in "$@"; do |
| 38 | case $arg in |
| 39 | --target=*-linux-android) echo "${arg#--target=}"; return ;; |
| 40 | *-linux-android) [ "$prev" = "--target" ] && { echo "$arg"; return; } ;; |
| 41 | @*) if [ -f "${arg#@}" ]; then |
| 42 | found=$(sed -n 's/^"\{0,1\}\(--target=\)\{0,1\}\([a-z0-9_]*-linux-android[0-9]*\)"\{0,1\}$/\2/p' \ |
| 43 | "${arg#@}" | head -n1) |
| 44 | [ -n "$found" ] && { echo "$found"; return; } |
| 45 | fi ;; |
| 46 | esac |
| 47 | prev=$arg |
| 48 | done |
| 49 | } |
| 50 | |
| 51 | android_target=$(scan_target "$@") |
| 52 | |
| 53 | if [ -z "$android_target" ]; then |
| 54 | exec "$exe" --sysroot "$host_std" "$@" |
| 55 | fi |
| 56 | |
| 57 | std_install=$(dotslash -- fetch "$dir/rust-std-android.dotslash") |
| 58 | target_std=$(dirname -- "$std_install")/rust-std-$android_target |
| 59 | |
| 60 | merged=${XDG_CACHE_HOME:-$HOME/.cache}/vidya-rust-sysroot/$(basename -- "$host_std")+$android_target |
| 61 | if [ ! -d "$merged/lib/rustlib/$android_target" ]; then |
| 62 | tmp=$merged.$$ |
| 63 | rm -rf -- "$tmp" |
| 64 | mkdir -p -- "$tmp/lib/rustlib" |
| 65 | for entry in "$host_std"/lib/*; do |
| 66 | [ "$(basename -- "$entry")" = rustlib ] && continue |
| 67 | ln -sfn -- "$entry" "$tmp/lib/" |
| 68 | done |
| 69 | for entry in "$host_std"/lib/rustlib/*; do |
| 70 | ln -sfn -- "$entry" "$tmp/lib/rustlib/" |
| 71 | done |
| 72 | ln -sfn -- "$target_std/lib/rustlib/$android_target" "$tmp/lib/rustlib/$android_target" |
| 73 | rm -rf -- "$merged" |
| 74 | mv -- "$tmp" "$merged" 2>/dev/null || rm -rf -- "$tmp" |
| 75 | fi |
| 76 | |
| 77 | exec "$exe" --sysroot "$merged" "$@" |