cmux/scripts/setup.sh
Lawrence Chen b4bb51c509 Use SHA stamp to safely reuse local xcframework on cache miss
Instead of always rebuilding, write a .ghostty_sha stamp file
inside the xcframework after each build. On cache miss, only
seed from local if the stamp matches the current submodule SHA.
This avoids both unnecessary rebuilds and stale ABI mismatches.
2026-02-20 17:42:35 -08:00

87 lines
2.9 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_DIR"
echo "==> Initializing submodules..."
git submodule update --init --recursive
echo "==> Checking for zig..."
if ! command -v zig &> /dev/null; then
echo "Error: zig is not installed."
echo "Install via: brew install zig"
exit 1
fi
GHOSTTY_SHA="$(git -C ghostty rev-parse HEAD)"
CACHE_ROOT="${CMUX_GHOSTTYKIT_CACHE_DIR:-$HOME/.cache/cmux/ghosttykit}"
CACHE_DIR="$CACHE_ROOT/$GHOSTTY_SHA"
CACHE_XCFRAMEWORK="$CACHE_DIR/GhosttyKit.xcframework"
LOCAL_XCFRAMEWORK="$PROJECT_DIR/ghostty/macos/GhosttyKit.xcframework"
LOCAL_SHA_STAMP="$LOCAL_XCFRAMEWORK/.ghostty_sha"
LOCK_DIR="$CACHE_ROOT/$GHOSTTY_SHA.lock"
mkdir -p "$CACHE_ROOT"
echo "==> Ghostty submodule commit: $GHOSTTY_SHA"
LOCK_TIMEOUT=300
LOCK_START=$SECONDS
while ! mkdir "$LOCK_DIR" 2>/dev/null; do
if (( SECONDS - LOCK_START > LOCK_TIMEOUT )); then
echo "==> Lock stale (>${LOCK_TIMEOUT}s), removing and retrying..."
rmdir "$LOCK_DIR" 2>/dev/null || rm -rf "$LOCK_DIR"
continue
fi
echo "==> Waiting for GhosttyKit cache lock for $GHOSTTY_SHA..."
sleep 1
done
trap 'rmdir "$LOCK_DIR" >/dev/null 2>&1 || true' EXIT
if [ -d "$CACHE_XCFRAMEWORK" ]; then
echo "==> Reusing cached GhosttyKit.xcframework"
else
# Only reuse local xcframework if its SHA stamp matches the current ghostty commit.
# Without this check, a stale build from a previous commit could be cached under
# the wrong SHA, producing ABI mismatches.
LOCAL_SHA=""
if [ -f "$LOCAL_SHA_STAMP" ]; then
LOCAL_SHA="$(cat "$LOCAL_SHA_STAMP")"
fi
if [ -d "$LOCAL_XCFRAMEWORK" ] && [ "$LOCAL_SHA" = "$GHOSTTY_SHA" ]; then
echo "==> Seeding cache from existing local GhosttyKit.xcframework (SHA matches)"
else
echo "==> Building GhosttyKit.xcframework (this may take a few minutes)..."
(
cd ghostty
zig build -Demit-xcframework=true -Doptimize=ReleaseFast
)
# Stamp the build output with the SHA it was built from
echo "$GHOSTTY_SHA" > "$LOCAL_SHA_STAMP"
fi
if [ ! -d "$LOCAL_XCFRAMEWORK" ]; then
echo "Error: GhosttyKit.xcframework not found at $LOCAL_XCFRAMEWORK"
exit 1
fi
TMP_DIR="$(mktemp -d "$CACHE_ROOT/.ghosttykit-tmp.XXXXXX")"
mkdir -p "$CACHE_DIR"
cp -R "$LOCAL_XCFRAMEWORK" "$TMP_DIR/GhosttyKit.xcframework"
rm -rf "$CACHE_XCFRAMEWORK"
mv "$TMP_DIR/GhosttyKit.xcframework" "$CACHE_XCFRAMEWORK"
rmdir "$TMP_DIR"
echo "==> Cached GhosttyKit.xcframework at $CACHE_XCFRAMEWORK"
fi
echo "==> Creating symlink for GhosttyKit.xcframework..."
ln -sfn "$CACHE_XCFRAMEWORK" GhosttyKit.xcframework
echo "==> Setup complete!"
echo ""
echo "You can now build and run the app:"
echo " ./scripts/reload.sh --tag first-run"