kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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