#!/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 built with # `zig cc`. Every target needs its own OS and CPU: the pinned V disables # garbage collection when cross-compiling. Linux VMs work from a Mac. 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" } native=$(host_target) target=${KOH_TARGET:-$native} case "$target" in macos-aarch64|macos-x86_64|linux-aarch64|linux-x86_64) ;; *) die "unsupported release target: $target (want macos-aarch64, macos-x86_64, linux-x86_64 or linux-aarch64)" ;; esac [ "$target" = "$native" ] || die "$target requires a native $target host or VM to retain garbage collection (this host is $native)" 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 -gc boehm -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. # musl has neither getcontext nor ARM64's expected __data_start symbol. # libgc can scan the stack and discover the data segment without them. compiler="$PWD/build/cc-$target" printf '#!/bin/sh\nexec zig cc -target %s "$@"\n' "$triple" > "$compiler" chmod 755 "$compiler" v -prod -gc boehm -d use_bundled_libgc -os linux -arch "$arch" \ -musl -cc "$compiler" -cflags "-DNO_GETCONTEXT -DSEARCH_FOR_DATA_START" \ -ldflags "-s" -o "$out" src/koh.v ;; esac echo "built $out"