hosted.sh (7166B)
1 #!/usr/bin/env bash 2 # scripts/hosted.sh — one front-end for provisioning sysroots and 3 # cross-compiling+linking against them, across kit's hosted support set. Wraps 4 # the per-OS provisioners (it does not replace them): 5 # FreeBSD -> scripts/freebsd_sysroot.sh (base.txz extract) 6 # Windows -> scripts/llvm_mingw_sysroot.sh (llvm-mingw UCRT) 7 # Linux -> test/libc/{glibc,musl}/extract.sh (podman container extract) 8 # macOS -> host SDK (native; no cross sysroot) 9 # 10 # Targets: <os>[-<libc>]-<arch> 11 # linux-glibc-{aa64,x64,rv64} linux-musl-{aa64,x64,rv64} 12 # freebsd-{amd64,aarch64,riscv64} windows-{x64,aarch64} macos-aarch64 13 # 14 # Commands: 15 # doctor support set + what is provisioned here 16 # prepare <target>|all provision the sysroot for a target 17 # path <target> print the sysroot dir ("" for macOS native) 18 # triple <target> print the kit -target triple 19 # tag <target> print the test/lib/exec_target.sh exec tag 20 # cc <target> [kit-cc-args] compile+link: kit cc -target T --sysroot S [...] 21 # 22 # env: KIT (default build/kit), plus the per-OS provisioners' own env. 23 24 set -u 25 26 ROOT="$(cd "$(dirname "$0")/.." && pwd)" 27 KIT="${KIT:-$ROOT/build/kit}" 28 29 SUPPORT_SET=" 30 linux-glibc-aa64 linux-glibc-x64 linux-glibc-rv64 31 linux-musl-aa64 linux-musl-x64 linux-musl-rv64 32 freebsd-amd64 freebsd-aarch64 freebsd-riscv64 33 windows-x64 windows-aarch64 34 macos-aarch64 35 " 36 37 die() { printf 'hosted: %s\n' "$*" >&2; exit 1; } 38 39 # ---- target parsing -------------------------------------------------------- 40 # Sets globals: T_OS, T_LIBC (linux only), T_ARCH (canonical per-OS token). 41 parse_target() { 42 local t="$1" os rest a 43 os="${t%%-*}"; rest="${t#*-}" 44 T_OS="$os"; T_LIBC=""; T_ARCH="" 45 case "$os" in 46 linux) 47 T_LIBC="${rest%%-*}"; a="${rest#*-}" 48 case "$T_LIBC" in glibc|musl) ;; *) die "bad linux libc in '$t' (want glibc|musl)";; esac 49 case "$a" in 50 aa64|aarch64|arm64) T_ARCH=aarch64 ;; 51 x64|x86_64|amd64) T_ARCH=x64 ;; 52 rv64|riscv64) T_ARCH=rv64 ;; 53 *) die "bad linux arch '$a' in '$t'" ;; 54 esac ;; 55 freebsd) 56 case "$rest" in 57 amd64|x64|x86_64) T_ARCH=amd64 ;; 58 aarch64|arm64|aa64) T_ARCH=aarch64 ;; 59 riscv64|rv64) T_ARCH=riscv64 ;; 60 *) die "bad freebsd arch '$rest' in '$t'" ;; 61 esac ;; 62 windows) 63 case "$rest" in 64 x64|x86_64|amd64) T_ARCH=x64 ;; 65 aarch64|arm64|aa64) T_ARCH=aarch64 ;; 66 *) die "bad windows arch '$rest' in '$t'" ;; 67 esac ;; 68 macos) 69 case "$rest" in 70 aarch64|arm64|aa64) T_ARCH=aarch64 ;; 71 *) die "bad macos arch '$rest' in '$t' (arm64 only)" ;; 72 esac ;; 73 *) die "unknown os in target '$t'" ;; 74 esac 75 } 76 77 triple_of() { 78 parse_target "$1" 79 case "$T_OS" in 80 linux) 81 local suf=gnu; [ "$T_LIBC" = musl ] && suf=musl 82 case "$T_ARCH" in 83 aarch64) echo "aarch64-linux-$suf" ;; 84 x64) echo "x86_64-linux-$suf" ;; 85 rv64) echo "riscv64-linux-$suf" ;; 86 esac ;; 87 freebsd) 88 case "$T_ARCH" in 89 amd64) echo x86_64-freebsd ;; 90 aarch64) echo aarch64-freebsd ;; 91 riscv64) echo riscv64-freebsd ;; 92 esac ;; 93 windows) 94 case "$T_ARCH" in 95 x64) echo x86_64-windows ;; 96 aarch64) echo aarch64-windows ;; 97 esac ;; 98 macos) echo aarch64-apple-darwin ;; 99 esac 100 } 101 102 # exec_target tag (test/lib/exec_target.sh). Linux/macOS use aa64/x64/rv64; 103 # FreeBSD uses amd64/aarch64/riscv64; Windows uses x64/aarch64. 104 tag_of() { 105 parse_target "$1" 106 local ea 107 case "$T_ARCH" in aarch64) ea=aa64 ;; x64) ea=x64 ;; rv64) ea=rv64 ;; *) ea="$T_ARCH" ;; esac 108 case "$T_OS" in 109 linux) [ "$T_LIBC" = glibc ] && echo "$ea-linux-glibc" || echo "$ea-linux" ;; 110 macos) echo "$ea-macos" ;; 111 freebsd) echo "$T_ARCH-freebsd" ;; 112 windows) echo "$T_ARCH-windows" ;; 113 esac 114 } 115 116 _linux_sysroot_dir() { # libc arch 117 local libc="$1" arch="$2" suf="" 118 case "$arch" in x64) suf=-x64 ;; rv64) suf=-rv64 ;; esac 119 printf '%s/build/%s-sysroot%s' "$ROOT" "$libc" "$suf" 120 } 121 122 path_of() { 123 parse_target "$1" 124 case "$T_OS" in 125 linux) _linux_sysroot_dir "$T_LIBC" "$T_ARCH" ;; 126 freebsd) "$ROOT/scripts/freebsd_sysroot.sh" path "$T_ARCH" 2>/dev/null ;; 127 windows) "$ROOT/scripts/llvm_mingw_sysroot.sh" path "$T_ARCH" 2>/dev/null ;; 128 macos) echo "" ;; 129 esac 130 } 131 132 # ---- prepare --------------------------------------------------------------- 133 prepare_one() { 134 parse_target "$1" 135 case "$T_OS" in 136 linux) 137 command -v podman >/dev/null 2>&1 || die "podman required for linux sysroots" 138 bash "$ROOT/test/libc/$T_LIBC/extract.sh" -a "$T_ARCH" ;; 139 freebsd) "$ROOT/scripts/freebsd_sysroot.sh" "$T_ARCH" ;; 140 windows) "$ROOT/scripts/llvm_mingw_sysroot.sh" prepare "$T_ARCH" ;; 141 macos) printf 'macos: native host SDK, nothing to prepare\n' ;; 142 esac 143 } 144 145 # ---- cc -------------------------------------------------------------------- 146 # cc <target> [extra kit cc args...] — adds -target, --sysroot, and any 147 # OS-mandatory flags; everything else (sources, -o, -O, -static, ...) passes 148 # through. macOS compiles native (no -target/--sysroot). 149 cc_target() { 150 local target="$1"; shift 151 parse_target "$target" 152 [ -x "$KIT" ] || die "kit not found at $KIT (run 'make bin')" 153 local triple sysroot; triple="$(triple_of "$target")"; sysroot="$(path_of "$target")" 154 local args=() 155 if [ "$T_OS" = macos ]; then 156 # Native host compile against the Xcode SDK. 157 local sdk; sdk="$(xcrun --show-sdk-path 2>/dev/null)" 158 [ -n "$sdk" ] && args+=(-isysroot "$sdk") 159 else 160 args+=(-target "$triple") 161 [ -n "$sysroot" ] && args+=(--sysroot "$sysroot") 162 [ "$T_OS" = windows ] && args+=(-mconsole) # console exit-code semantics 163 fi 164 exec "$KIT" cc "${args[@]}" "$@" 165 } 166 167 # ---- doctor ---------------------------------------------------------------- 168 doctor() { 169 printf 'host: %s/%s\n' "$(uname -s 2>/dev/null)" "$(uname -m 2>/dev/null)" 170 printf 'kit: %s%s\n' "$KIT" "$([ -x "$KIT" ] && echo '' || echo ' (missing)')" 171 printf 'support set (sysroot provisioned?):\n' 172 local t sr ok 173 for t in $SUPPORT_SET; do 174 sr="$(path_of "$t")" 175 if [ "$(printf '%s' "$t" | cut -d- -f1)" = macos ]; then ok='native' 176 elif [ -n "$sr" ] && [ -d "$sr" ]; then ok='yes' 177 else ok='no'; fi 178 printf ' %-20s triple=%-22s tag=%-12s sysroot=%s\n' \ 179 "$t" "$(triple_of "$t")" "$(tag_of "$t")" "$ok" 180 done 181 } 182 183 cmd="${1:-}" 184 case "$cmd" in 185 doctor) doctor ;; 186 prepare) 187 [ $# -ge 2 ] || die "usage: $0 prepare <target>|all" 188 if [ "$2" = all ]; then for t in $SUPPORT_SET; do prepare_one "$t"; done 189 else prepare_one "$2"; fi ;; 190 path) [ $# -eq 2 ] || die "usage: $0 path <target>"; path_of "$2" ;; 191 triple) [ $# -eq 2 ] || die "usage: $0 triple <target>"; triple_of "$2" ;; 192 tag) [ $# -eq 2 ] || die "usage: $0 tag <target>"; tag_of "$2" ;; 193 cc) [ $# -ge 2 ] || die "usage: $0 cc <target> [kit-cc-args]"; shift; cc_target "$@" ;; 194 -h|--help|help|"") sed -n '2,30p' "$0" | sed 's/^# \{0,1\}//' ;; 195 *) die "unknown command '$cmd' (try: doctor prepare path triple tag cc)" ;; 196 esac