feat(@projects/@magic-civilization): enable windows cross-compilation via cargo-xwin

Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
Natalie 2026-04-25 17:33:35 -07:00
parent a5a232a660
commit eb09af5b89
4 changed files with 87 additions and 11 deletions

View file

@ -143,16 +143,17 @@ jobs:
retention-days: 14
# ──────────────────────────────────────────────────────────────────
# WINDOWS
# TODO(prerequisite): no windows,x86_64 runner is registered yet. See
# .forgejo/RUNNER_SETUP.md § "Windows runner" for the expected labels
# and the `rustup target add x86_64-pc-windows-msvc` / Godot editor
# install prerequisites.
# WINDOWS — cross-compiled from Linux via cargo-xwin (Option B / p2-06b).
# The .dll is produced as MSVC ABI (`x86_64-pc-windows-msvc`) on Linux
# using `cargo xwin`; Godot's Windows export template runs from the same
# Linux runner, so a real Windows host is not required. Prerequisites on
# the runner: rust toolchain + `cargo install cargo-xwin`, clang, lld,
# and the Godot editor with the windows export template installed.
# ──────────────────────────────────────────────────────────────────
windows_build:
name: windows build
runs-on: [self-hosted, windows, x86_64]
timeout-minutes: 45
runs-on: [self-hosted, linux, x86_64]
timeout-minutes: 60
outputs:
archive: ${{ steps.package.outputs.archive }}
steps:
@ -169,13 +170,24 @@ jobs:
version="${GITHUB_REF_NAME#v}"
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Build GDExtension (.dll)
- name: Setup MSVC cross-toolchain
shell: bash
run: |
set -euo pipefail
rustup target add x86_64-pc-windows-msvc
if ! command -v cargo-xwin &>/dev/null; then
cargo install cargo-xwin
fi
- name: Build GDExtension (.dll, MSVC ABI via cargo-xwin)
working-directory: src/simulator
shell: bash
run: bash build-gdext.sh
run: bash build-gdext.sh x86_64-pc-windows-msvc
- name: Godot export — windows
- name: Godot export — windows (cross-export from Linux)
shell: bash
env:
BUILD_WINDOWS_DLL: "0" # already built in the previous step
run: |
set -euo pipefail
bash tools/export-single.sh windows "${{ steps.version.outputs.version }}"

View file

@ -86,3 +86,29 @@ and compare against EDIT-host build hash before launching.
## Stop condition
After all three batches land successfully and status updates are committed, run `mcp__objectives__dashboard_regen`. The warcouncil queue should drop to depth 0 (excluding `g2-04` which is OOS).
---
## BLOCKER — 2026-04-25 — Apricot branch divergence (batch coordinator session)
`git pull --ff-only` on apricot failed. The apricot `main` has diverged from `origin/main`:
- **17 commits on apricot NOT on origin/main** — real source-code changes including:
- `feat(autoplay-specific)` — autoplay-batch.sh dynamic test case handling
- `test(game-engine)` — score-victory fallback test
- `refactor(combat)``get_damage()` / `get_damage_resistance()``get_attack()` / `get_defense()`
- `refactor(ai)` — PersonalityAssigner extract
- `feat(matchup-grid)` — clan ID assignment + AI personality test scenario generation
- 12 additional commits (action system, tactical movement refactor, CI fixes)
- **46 commits on origin/main NOT on apricot** — objective/project-file updates from the warcouncil session
**Why this blocks the batch**: The cycle-1 code changes (p1-22 mcts_tree budget, p0-02 personality scorer) landed on `origin/main`. Apricot is running an older + diverged tree. Building GDExt on apricot would produce a binary from a different code state — the batch results would not validate the cycle-1 changes.
**Resolution required (human)**:
1. Determine the authoritative code state — which of the 17 apricot-only commits should be preserved vs discarded.
2. Either: rebase apricot onto origin/main, or push the apricot-only commits to origin/main and let it fast-forward.
3. Do NOT `git reset --hard origin/main` on apricot — the 17 apricot commits include real source changes that may be untracked on the EDIT host.
**What this agent did NOT do**: no force, no reset, no merge without authorization.
**Resuming after resolution**: once `ssh apricot 'cd ~/Code/@projects/@magic-civilization && git pull --ff-only'` exits 0, re-run from Step 1 (binary hash capture) and proceed through steps 2-6.

View file

@ -5,7 +5,19 @@ TARGET=${1:-x86_64-unknown-linux-gnu}
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ADDON_DIR="$SCRIPT_DIR/../game/engine/addons/magic_civ_physics"
cargo build --release -p magic-civ-physics-gdext --target "$TARGET"
# Use cargo-xwin for the MSVC Windows target so we can cross-build a
# proper MSVC-ABI .dll from Linux (no wine, no Windows host needed).
# xwin downloads the MSVC SDK on first run (~1.5GB cached under
# ~/.cache/cargo-xwin/).
if [ "$TARGET" = "x86_64-pc-windows-msvc" ]; then
if ! command -v cargo-xwin &>/dev/null; then
echo "ERROR: cargo-xwin not installed. Run: cargo install cargo-xwin" >&2
exit 2
fi
cargo xwin build --release -p magic-civ-physics-gdext --target "$TARGET"
else
cargo build --release -p magic-civ-physics-gdext --target "$TARGET"
fi
mkdir -p "$ADDON_DIR"

View file

@ -164,6 +164,23 @@ if [ "$platform" = "linux" ] && [ "${PULL_LINUX_SO:-1}" = "1" ]; then
fi
fi
# ── Build Windows .dll via cargo-xwin (p2-06b Option B) ──────────────
# Cross-compile the GDExtension to MSVC ABI from Linux. cargo-xwin
# downloads the MS SDK on first invocation (~1.5GB cached). Disable with
# BUILD_WINDOWS_DLL=0 if a fresh dll is already in place from CI.
if [ "$platform" = "windows" ] && [ "${BUILD_WINDOWS_DLL:-1}" = "1" ]; then
echo -e "${BLUE}Building Windows .dll via cargo-xwin (MSVC ABI, x86_64-pc-windows-msvc)${NC}"
if ! (cd "$REPO_ROOT/src/simulator" && bash build-gdext.sh x86_64-pc-windows-msvc); then
echo -e "${RED} ✗ cargo-xwin build failed — see output above${NC}"
echo -e "${YELLOW} Prerequisites: rustup target add x86_64-pc-windows-msvc; cargo install cargo-xwin; clang + lld${NC}"
exit 9
fi
dll_local="$GAME_DIR/engine/addons/magic_civ_physics/magic_civ_physics.x86_64.dll"
if [ -f "$dll_local" ]; then
echo -e "${DIM} · .dll at $(du -h "$dll_local" | cut -f1)$dll_local${NC}"
fi
fi
export_game_dir="$GAME_DIR"
staging_root=""
if [ "$EXPORT_STAGED" = "1" ]; then
@ -244,6 +261,15 @@ if $godot_cmd --headless --path "$export_game_dir" "$flag" "$preset_name" "$out_
echo -e "${DIM} · relocated .so → engine/addons/magic_civ_physics/${NC}"
fi
fi
if [ "$platform" = "windows" ]; then
dll_root="$out_dir/magic_civ_physics.x86_64.dll"
dll_addon_dir="$out_dir/engine/addons/magic_civ_physics"
if [ -f "$dll_root" ]; then
mkdir -p "$dll_addon_dir"
mv "$dll_root" "$dll_addon_dir/"
echo -e "${DIM} · relocated .dll → engine/addons/magic_civ_physics/${NC}"
fi
fi
cleanup_staging
exit 0
else