1#!/usr/bin/env bash 2# Build `native` and keep a copy of it where `launch.sh` looks. See ./README.md. 3set -euo pipefail 4 5REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" 6cd "$REPO_ROOT" 7 8# The library path the copy will run with is the DEVSHELL's: read it here, 9# inside the shell, and write it down for launch.sh, which runs outside one. 10if [[ -z "${IN_NIX_SHELL:-}" ]]; then 11 exec nix develop -c "$0" "$@" 12fi 13 14BIN_DIR="run/bin" 15ROOTS="$BIN_DIR/roots" 16mkdir -p "$BIN_DIR" 17 18built="$(buck2 build //apps/native:native --show-full-simple-output)" 19[[ -x "$built" ]] || { echo "install.sh: buck2 named no executable ($built)" >&2; exit 1; } 20 21# A copy, never a symlink into buck-out: buck-out is wiped (2026-09-21) and 22# rewritten mid-build, and either would take the proxy away from the client. 23# The rename is atomic, so a launch racing this sees the old copy or the new. 24cp "$built" "$BIN_DIR/native.new" 25# The hot-patch build keeps every symbol and all debug info (285 MB, measured 26# 2026-09-21). The proxy is never patched - patch.sh reads the WINDOW's own 27# /proc/PID/exe - so its copy drops the debug info; C: is the scarce thing. 28strip --strip-debug "$BIN_DIR/native.new" 29printf 'LD_LIBRARY_PATH=%s\n' "$LD_LIBRARY_PATH" >"$BIN_DIR/native.env.new" 30mv -f "$BIN_DIR/native.env.new" "$BIN_DIR/native.env" 31mv -f "$BIN_DIR/native.new" "$BIN_DIR/native" 32 33# The copy names store paths - its ELF interpreter and every library it links 34# - that nothing else keeps alive outside the devshell. Root the ones ldd 35# resolves, so a garbage collection cannot leave a binary that will not start. 36rm -rf "$ROOTS" 37mkdir -p "$ROOTS" 38i=0 39while read -r store; do 40 nix-store --add-root "$ROOTS/$i" --realise "$store" >/dev/null 41 i=$((i + 1)) 42done < <(ldd "$BIN_DIR/native" | grep -o '/nix/store/[^/]*' | sort -u) 43 44echo "install.sh: $BIN_DIR/native from $built ($i store paths rooted)" >&2