#!/bin/sh # Builds one Koh release binary into build/releases/koh-. # # KOH_TARGET=linux-x86_64 sh build.sh # # `koh build` sets KOH_TARGET for each platform in koh.build; run by hand, the # target defaults to the machine running the script. Runs on macOS and Linux. # # macOS targets need macOS: they link against the Apple SDK and are ad-hoc # signed with codesign. Linux targets are static musl binaries cross-compiled # with `zig cc`, so they build the same from either host, and NixOS's gcc # wrapper and missing tcc never come into it. set -eu die() { echo "build.sh: $*" >&2 exit 1 } # Paths below are relative to the repository, wherever the script is run from. cd "$(dirname "$0")" # The pin is the only compiler Koh is verified against; see AGENTS.md. command -v v >/dev/null 2>&1 || die 'V is not on PATH; install V 0.5.2 b9a2d87 (see AGENTS.md)' [ "$(v version)" = 'V 0.5.2 b9a2d87' ] || die "Koh requires V 0.5.2 b9a2d87, found: $(v version)" host_target() { case "$(uname -s)" in Darwin) os=macos ;; Linux) os=linux ;; *) die "unsupported host OS: $(uname -s)" ;; esac case "$(uname -m)" in arm64|aarch64) cpu=aarch64 ;; x86_64|amd64) cpu=x86_64 ;; *) die "unsupported host CPU: $(uname -m)" ;; esac echo "$os-$cpu" } target=${KOH_TARGET:-$(host_target)} out="build/releases/koh-$target" mkdir -p build/releases case "$target" in macos-aarch64|macos-x86_64) [ "$(uname -s)" = Darwin ] || die "$target needs the Apple SDK; build it on macOS" case "$target" in macos-aarch64) arch=arm64; cpu=arm64 ;; *) arch=x64; cpu=x86_64 ;; esac v -prod -d use_bundled_libgc -arch "$arch" \ -cflags "-arch $cpu -mmacosx-version-min=11.0" -o "$out" src/koh.v # Apple Silicon refuses to run an unsigned binary. codesign -f -s - "$out" ;; linux-aarch64|linux-x86_64) command -v zig >/dev/null 2>&1 || die 'Linux builds need Zig on PATH (zig cc provides the musl toolchain)' case "$target" in linux-aarch64) arch=arm64; triple=aarch64-linux-musl ;; *) arch=x64; triple=x86_64-linux-musl ;; esac # V's -cc takes a single program, not `zig cc -target …`, so wrap it. # V drops the GC for any cross target, which is how every Linux release # has shipped; -gc none pins that on a Linux host too, where V would # otherwise link libgc against musl and fail on glibc's getcontext. compiler="$PWD/build/cc-$target" printf '#!/bin/sh\nexec zig cc -target %s "$@"\n' "$triple" > "$compiler" chmod 755 "$compiler" v -prod -gc none -os linux -arch "$arch" -musl -cc "$compiler" \ -ldflags "-s" -o "$out" src/koh.v ;; *) die "unsupported release target: $target (want macos-aarch64, macos-x86_64, linux-x86_64 or linux-aarch64)" ;; esac echo "built $out"