#!/bin/sh # The NDK, as the C toolchain for Android, fetched where the action runs. # # Unlike zcc.sh, the archive behind this is not an input. That is deliberate: # unpacked it is three gigabytes, and an input has to travel to a worker # through the CAS — uploaded from here first, then materialised there. What # travels instead is DotSlash (under a megabyte) and the manifest naming the # archive, and the worker fetches the same bytes under the same digest from # Google. A machine that has already fetched it does nothing. # # The cost of that is honest to state: what the compiler *is* stops being part # of the action's cache digest. The manifest is an input, so a version bump # still invalidates; a machine whose DotSlash cache holds something else under # that digest cannot happen, because the digest is what the cache is keyed on. # # $1 is the directory holding the DotSlash binary, $2 the manifest to resolve # and $3 the mode — cc, c++, ar, ranlib or objcopy. buck passes all three. set -e dotslash=$1/dotslash manifest=$2 mode=$3 shift 3 # ANDROID_NDK_HOME still wins, for a machine that has one installed. ndk=${ANDROID_NDK_HOME:-${ANDROID_NDK_ROOT:-}} if [ -n "$ndk" ]; then for host in linux-x86_64 darwin-x86_64; do if [ -d "$ndk/toolchains/llvm/prebuilt/$host/bin" ]; then bin=$ndk/toolchains/llvm/prebuilt/$host/bin break fi done [ -n "${bin:-}" ] || { echo "toolchains/ndk.sh: no llvm prebuilt under $ndk" >&2; exit 1; } else # The manifest names bin/clang inside the archive; DotSlash unpacks the # whole NDK around it, which is what the driver needs — its sysroot and its # resource directory are found relative to the binary. bin=$(dirname "$("$dotslash" -- fetch "$manifest")") fi # API 28 is frq's min_sdk_version, and the floor for what the app needs from # bionic. The NDK ships a wrapper script per API level that adds this flag and # nothing else; passing it here keeps this to one executable out of the # archive, so nothing depends on which permissions survived the unpacking. target=${JOLT_ANDROID_TARGET:-aarch64-linux-android}${JOLT_ANDROID_API:-28} # The target goes *after* the caller's arguments, because clang takes the last # --target it is given and cc-rs passes one of its own. Its version carries no # API level, so putting ours first silently dropped the app back to the NDK's # default minimum — where bionic has no `getentropy`, and aws-lc-sys fails to # compile against a header that does not declare it. The API level is not a # default to be overridden; it is the floor the app is built for. case $mode in cc) exec "$bin/clang" "$@" --target="$target" ;; c++) exec "$bin/clang++" "$@" --target="$target" ;; ar) exec "$bin/llvm-ar" "$@" ;; ranlib) exec "$bin/llvm-ranlib" "$@" ;; objcopy) exec "$bin/llvm-objcopy" "$@" ;; *) echo "toolchains/ndk.sh: unknown mode $mode" >&2; exit 1 ;; esac