Files
Xenia-Canary/docs/CROSS_BUILD_SETUP.md
MechaCat02 03362b59fe
Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Successful in 1m19s
Orchestrator / Windows (x86-64) (push) Failing after 5m16s
Orchestrator / Linux (x86-64) (push) Failing after 13m23s
Orchestrator / Create Release (push) Has been skipped
[Build] Linux→Windows cross-compile toolchain (clang-cl + xwin)
New CMake preset `cross-win-clangcl` for Ninja Multi-Config on
non-Windows hosts. Toolchain: clang-cl (MSVC-ABI), lld-link, xwin SDK/CRT
splat. Shader compilation routes through wine fxc.exe with FXC_PATH
env forwarding and unix→Windows path translation via `winepath -w`.
Plus per-file build fixes (constexpr→const, llvm-rc forward-slash,
zlib-ng AVX guard, /RTCsu MSVC-only). third_party/snappy bumped to
fabi/sylpheed-crossbuild for the target-aware POSIX-gate header.

Produces `xenia_canary.exe` (Debug MSVC) suitable for use as the
audit oracle under Wine for xenia-rs work. See
docs/CROSS_BUILD_SETUP.md for the full reproduction recipe.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-05 23:52:27 +02:00

6.6 KiB
Raw Blame History

Building and Running Xenia Canary Windows Debug from Linux

What we built and why

A Windows-MSVC debug xenia_canary.exe cross-compiled on Linux, runnable under Wine. This serves as the audit oracle for the xenia-rs Rust port: the Linux-native canary build stalls before the front-end UI, so all audit comparisons (memory entries audit_044audit_059) need the Wine-targeted debug binary as the ground-truth reference engine.

Phase 1 — Host setup (run in your terminal)

sudo apt install -y clang-18 lld-18 llvm-18      # clang-cl driver mode + lld-link + binutils
sudo ln -s /usr/bin/clang-18 /usr/bin/clang-cl   # activates MSVC-compatible driver mode
xwin --accept-license --arch x86_64 splat --include-debug-libs --output ~/.xwin/splat
                                                  # ~807 MB Win10 SDK + MSVC CRT sysroot
curl ... linkid=2361406 -o ~/winsdk.iso          # Win10 SDK ISO for real fxc.exe (SM 5_1)
winetricks -q vkd3d                              # vkd3d-proton d3d12core.dll (5.96 MB)
winetricks -q dxvk                               # DXVK dxgi.dll (2.95 MB)

Ubuntu's clang-18 / lld-18 apt packages ship binutils suffixed (llvm-lib-18, lld-link-18, etc.); the toolchain expects unsuffixed names on PATH. Create 4 symlinks in ~/.local/bin/ (no sudo needed since it was already on PATH).

Phase 2 — In-tree edits

8 build-fix patches (compile-time only; zero runtime semantics changes)

§ File What changed
7.1 src/xenia/base/mapped_memory_win.cc:30 constexprconst for kFileHandleInvalid (clang-cl rejects reinterpret_cast in constant expressions)
7.2 src/xenia/app/main_resources.rc:3 ..\\..\\..\\assets\\icon\\icon.ico → forward slashes (llvm-rc backslash literalism)
7.3 third_party/snappy/snappy-stubs-public.h Already in place via the fabi/sylpheed-crossbuild snappy fork submodule
7.4 third_party/zlib-ng/zconf-ng.h:113 #if 1#if !defined(_WIN32) for Z_HAVE_UNISTD_H (header was pre-generated on Linux)
7.5 third_party/CMakeLists.txt:335 Extended if(NOT MSVC)if(NOT MSVC OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") for zlib-ng AVX flags
7.6a CMakeLists.txt Wrapped /RTCsu appends in CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC" AND NOT … "Clang"
7.6b CMakeLists.txt:85-101 Inserted execute_process block invoking xenia-build.py:generate_version_h() so CMake-direct flow produces version.h
7.7 cmake/XeniaHelpers.cmake Added _env_prefix to wrap per-shader commands in cmake -E env FXC_PATH=… (cmake set(ENV{…}) doesn't survive ninja's subprocess spawn)
7.8 tools/build/compile_shader_dxbc.py:74 Added _wineify() helper translating unix paths via winepath -w before fxc sees them (fxc parses /home/… as a /h switch)

3 new cross-compile config files

File Purpose
cmake/toolchains/linux-to-win-msvc.cmake clang-cl + lld-link + xwin sysroot driver. Forces MultiThreadedDLL runtime (no debug-CRT DLLs needed), feeds -imsvc flags via SHELL: prefix, suppresses 15+ clang-cl-specific warnings, defines _mm_cvtsi64x_si128 alias, opts out of MSVC STL's Clang≥19 assertion, plumbs FXC_PATH
cmake/toolchains/xwin-case-symlinks.py Scans xenia includes for mixed-case Windows headers and creates the missing case-aliases in xwin's flat splat (5 needed: ObjBase.h, Psapi.h, etc.)
CMakePresets.json Added cross-win-clangcl configure preset + cross-debug / cross-release / cross-checked build presets, gated on ${hostSystemName} ≠ Windows

Phase 3 — Configure + build

python3 cmake/toolchains/xwin-case-symlinks.py "$PWD" "$HOME/.xwin/splat"
# Created 5 case-symlinks across 556 unique includes

cmake --preset cross-win-clangcl
# Generates build-cross/ with build-Debug.ninja + auto-generated version.h

cmake --build build-cross --preset cross-debug --target xenia-app -j6
# 936 ninja targets. -j6 not -j12 because host RAM is tight (~3.4 GiB free at start)
# Wall time ~25 min total

Final output: xenia_canary.exe (27 MB PE32+ GUI x86-64) + xenia_canary.pdb (116 MB CodeView).

Phase 4 — Running the game

cd "/home/fabi/RE Project Sylpheed/xenia-canary/build-cross/bin/Windows/Debug"
WINEDEBUG=-all wine ./xenia_canary.exe --mute=true \
    "/home/fabi/RE Project Sylpheed/Project Sylpheed - Arc of Deception (USA, Europe) (En,Ja).iso"

Kill after the boot phase completes (the audit workflow only needs ~30 s of trajectory):

sleep 30
wineserver -k

Expected boot signals in xenia.log

Signal Value Meaning
Total log lines 1091 Healthy boot (≥1000 = passes)
^x> fatals 0 No xe::FatalError() triggered
^!> errors 28 Non-fatal (occasional pipeline misses — normal)
^w> warnings 28 Normal startup
i> Setup: Initializing chain Memory → Exports → Processor → Audio → Graphics → HID → VFS → Kernel All eight subsystems came up
i> Setup: Starting graphics_system + Starting audio_system present Threads spawned cleanly
DXGI adapter NVIDIA GeForce GTX 1070 Ti vkd3d-proton + DXVK loaded
K> XThread::Execute thid N count 29 Guest threads spawned (game is past XexLoadImage)
Skipping draw - pipeline not ready: VS … PS … repeating yes D3D12 backend is async-compiling pipelines — expected on cold boot
F> channel 321 lines VFS is mounting and walking the disc image
K> channel 29 lines Kernel dispatching XThread creation

Audit-workflow integration

The cross-build is now the sole canary oracle. The Linux-native xenia-canary/build/bin/Linux/Debug/xenia_canary is deprecated for audits.

All canary launches must include --mute=true (project policy 2026-05-12). XAudio2 still initializes — same code paths, silent output. Do not substitute --apu=nop; that switches backend entirely.

Point logs at audit-runs with --log_file=:

LOG="$XENIA_RS_ROOT/xenia-rs/audit-runs/audit_NN/canary.log" \
WINEDEBUG=-all wine xenia_canary.exe \
    --mute=true --log_file="$LOG" \
    --audit_NN_my_probe=true \
    "$ISO_PATH"

Add new audit instrumentation as cvars in cpu_flags.h / gpu_flags.h / kernel_flags.h, guard with if (cvars::audit_NN_my_probe), emit XELOGI("AUDIT-NN-EVENT …"). Rebuild incrementally — only the touched TU recompiles, ≤60 s.

The build is observation-only: cvars + XELOG*() + #if-gated diagnostic blocks are permitted; changing control flow, return values, struct layouts, or timing is forbidden, since that would invalidate every downstream audit comparison.