#!/bin/sh set -eu ROOT=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) BUILD_ROOT=${BUILD_ROOT:-"$ROOT/.static-build"} DIST_DIR=${DIST_DIR:-"$ROOT/dist"} JOBS=${JOBS:-$(getconf _NPROCESSORS_ONLN 2>/dev/null || printf '1')} TOOLCHAIN_RELEASE=20260823 SDL_VERSION=3.4.14 SDL_IMAGE_VERSION=3.4.4 SDL_IMAGE_COMMIT=bec9134a26c7d0f31b36d6083c25296e04cabff5 NASM_VERSION=3.02 SDL_ARCHIVE="SDL3-$SDL_VERSION.tar.gz" SDL_SHA256=30d4aa2b3037718142b32dffd4e72f917ebb6cc5227150e7bb9c45efb2153aeb SDL_URL="https://github.com/libsdl-org/SDL/releases/download/release-$SDL_VERSION/$SDL_ARCHIVE" NASM_ARCHIVE="nasm-$NASM_VERSION.tar.xz" NASM_SHA256=87336eba53b4acfe917424ab5d500d2b0054d9f5148d35c2273ccf2cfb712f0d NASM_URL="https://www.nasm.us/pub/nasm/releasebuilds/$NASM_VERSION/$NASM_ARCHIVE" log() { printf '%s\n' "compile_static: $*" >&2 } die() { log "error: $*" exit 1 } require_command() { command -v "$1" >/dev/null 2>&1 || die "required command not found: $1" } for command_name in cmake curl file find git make ninja paste pkg-config readelf sha256sum tar; do require_command "$command_name" done mkdir -p "$BUILD_ROOT/downloads" "$BUILD_ROOT/sources" \ "$BUILD_ROOT/toolchains" "$BUILD_ROOT/targets" "$DIST_DIR" download_checked() { url=$1 destination=$2 expected=$3 temporary="$destination.part" if [ -f "$destination" ] && printf '%s %s\n' "$expected" "$destination" | sha256sum -c - >/dev/null 2>&1; then return fi log "downloading $(basename "$destination")" curl -fL --retry 3 --retry-delay 2 "$url" -o "$temporary" printf '%s %s\n' "$expected" "$temporary" | sha256sum -c - >/dev/null || die "checksum mismatch for $(basename "$destination")" mv -f "$temporary" "$destination" } remove_cache_directory() { target=$1 case "$target" in "$BUILD_ROOT"/*) rm -rf -- "$target" ;; *) die "refusing to remove path outside build cache: $target" ;; esac } extract_checked() { archive=$1 destination=$2 expected=$3 stamp="$destination/.archive-sha256" temporary="$destination.tmp.$$" if [ -f "$stamp" ] && [ "$(sed -n '1p' "$stamp")" = "$expected" ]; then return fi remove_cache_directory "$temporary" mkdir -p "$temporary" tar -xf "$archive" -C "$temporary" --strip-components=1 printf '%s\n' "$expected" >"$temporary/.archive-sha256" remove_cache_directory "$destination" mv "$temporary" "$destination" } download_checked "$SDL_URL" "$BUILD_ROOT/downloads/$SDL_ARCHIVE" "$SDL_SHA256" extract_checked "$BUILD_ROOT/downloads/$SDL_ARCHIVE" \ "$BUILD_ROOT/sources/SDL-$SDL_VERSION" "$SDL_SHA256" download_checked "$NASM_URL" "$BUILD_ROOT/downloads/$NASM_ARCHIVE" "$NASM_SHA256" extract_checked "$BUILD_ROOT/downloads/$NASM_ARCHIVE" \ "$BUILD_ROOT/sources/nasm-$NASM_VERSION" "$NASM_SHA256" NASM_PREFIX="$BUILD_ROOT/host-tools/nasm-$NASM_VERSION" if [ ! -x "$NASM_PREFIX/bin/nasm" ]; then NASM_BUILD="$BUILD_ROOT/host-tools/build-nasm-$NASM_VERSION" remove_cache_directory "$NASM_BUILD" mkdir -p "$NASM_BUILD" "$NASM_PREFIX" log "building local NASM $NASM_VERSION" ( cd "$NASM_BUILD" "$BUILD_ROOT/sources/nasm-$NASM_VERSION/configure" \ --prefix="$NASM_PREFIX" ) make -C "$NASM_BUILD" -j "$JOBS" make -C "$NASM_BUILD" install fi PATH="$NASM_PREFIX/bin:$PATH" export PATH SDL_IMAGE_SOURCE="$BUILD_ROOT/sources/SDL_image-$SDL_IMAGE_VERSION" if [ ! -d "$SDL_IMAGE_SOURCE/.git" ]; then remove_cache_directory "$SDL_IMAGE_SOURCE" log "cloning SDL_image $SDL_IMAGE_VERSION and its pinned codec submodules" git clone --recursive --branch "release-$SDL_IMAGE_VERSION" \ https://github.com/libsdl-org/SDL_image.git "$SDL_IMAGE_SOURCE" fi actual_image_commit=$(git -C "$SDL_IMAGE_SOURCE" rev-parse HEAD) [ "$actual_image_commit" = "$SDL_IMAGE_COMMIT" ] || die "cached SDL_image checkout is not the pinned commit; remove $SDL_IMAGE_SOURCE" git -C "$SDL_IMAGE_SOURCE" submodule update --init --recursive build_target() { triple=$1 output_arch=$2 processor=$3 archive_sha=$4 expected_machine=$5 archive="$triple.tar.xz" archive_url="https://github.com/cross-tools/musl-cross/releases/download/$TOOLCHAIN_RELEASE/$archive" archive_path="$BUILD_ROOT/downloads/$archive" toolchain_root="$BUILD_ROOT/toolchains/$triple-$TOOLCHAIN_RELEASE" target_root="$BUILD_ROOT/targets/$triple" prefix="$target_root/prefix" toolchain_file="$target_root/toolchain.cmake" sdl_build="$target_root/build-sdl" image_build="$target_root/build-sdl-image" download_checked "$archive_url" "$archive_path" "$archive_sha" extract_checked "$archive_path" "$toolchain_root" "$archive_sha" cc=$(find "$toolchain_root" -path "*/bin/$triple-gcc" -print -quit) cxx=$(find "$toolchain_root" -path "*/bin/$triple-g++" -print -quit) [ -n "$cc" ] && [ -x "$cc" ] || die "compiler missing from $archive" [ -n "$cxx" ] && [ -x "$cxx" ] || die "C++ compiler missing from $archive" tool_bin=$(dirname "$cc") mkdir -p "$target_root" cat >"$toolchain_file" </dev/null || die "$output has the wrong architecture" file "$output" | grep -F 'statically linked' >/dev/null || die "$output is not statically linked" if readelf -l "$output" | grep -q 'INTERP'; then die "$output contains a dynamic interpreter" fi if readelf -d "$output" 2>/dev/null | grep -q '(NEEDED)'; then die "$output contains dynamic dependencies" fi case "$output_arch" in amd64) log "running native amd64 tests" "$test_output" ;; arm64) if command -v qemu-aarch64 >/dev/null 2>&1; then log "running arm64 tests with qemu-aarch64" qemu-aarch64 "$test_output" else log "qemu-aarch64 not found; arm64 binary was link-verified only" fi ;; esac } build_target x86_64-unknown-linux-musl amd64 x86_64 \ 9752ecb10bafc0fc2ea75b3ed864a78137f3e5ba9b1579f1f16923d444c48096 \ 'x86-64' build_target aarch64-unknown-linux-musl arm64 aarch64 \ 0fc483607d9ed83bdf75e7539bacc66721d7e37ca606377aed6a90cef82e45da \ 'ARM aarch64' log "finished" file "$DIST_DIR/accent-extract-linux-amd64" \ "$DIST_DIR/accent-extract-linux-arm64"