snapshot: preserve the uncommitted Canary instrumentation (not authored here)
Some checks failed
Orchestrator / Commit Message Validation (push) Has been skipped
Orchestrator / Lint (push) Failing after 2m0s
Orchestrator / Windows (x86-64) (push) Has been skipped
Orchestrator / Linux (x86-64) (push) Has been skipped
Orchestrator / Create Release (push) Has been skipped

Working-tree snapshot taken 2026-07-28 so this work is not lost. To be clear
about provenance: NONE of this was written in the session that committed it —
it is pre-existing uncommitted work on phase-a-tracing, last committed 2026-07-09,
from the xenia-rs decoder/deadlock investigation. It is recorded verbatim, not
reviewed and not tested.

Contents: 24 tracked modifications (ppc_emit_memory, xex_module, object_table,
shim_utils, xboxkrnl threading/rtl, xevent/xobject/xthread, memory) plus the
untracked probe sources audit_68_host_mem_watch, audit_69_event_signal_watch,
audit_70_semaphore_release_watch, phase_b_snapshot, and cmake/toolchains.

Deliberately excluded: build-cross/ (51 GB of build output) and
vkd3d-proton.cache. Note third_party/snappy is a submodule pointer change whose
target may not be pushed anywhere, so this branch is a preservation record rather
than a guaranteed-buildable tree.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-28 20:03:33 +00:00
parent a154309022
commit 30d05ee97b
34 changed files with 2981 additions and 32 deletions

View File

@@ -0,0 +1,119 @@
# Linux host -> Windows MSVC-ABI cross toolchain using clang-cl + lld-link
# + xwin-supplied Win10 SDK/CRT. Driven by Ninja Multi-Config.
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
if(NOT DEFINED XWIN_DIR)
if(DEFINED ENV{XWIN_DIR})
set(XWIN_DIR "$ENV{XWIN_DIR}")
else()
set(XWIN_DIR "$ENV{HOME}/.xwin/splat")
endif()
endif()
set(XWIN_DIR "${XWIN_DIR}" CACHE PATH "xwin splat root (contains crt/ and sdk/)")
if(NOT EXISTS "${XWIN_DIR}/crt/include")
message(FATAL_ERROR "XWIN_DIR=${XWIN_DIR} missing crt/include - run xwin splat.")
endif()
set(CMAKE_C_COMPILER clang-cl)
set(CMAKE_CXX_COMPILER clang-cl)
set(CMAKE_LINKER lld-link)
set(CMAKE_RC_COMPILER llvm-rc)
set(CMAKE_AR llvm-lib)
set(CMAKE_MT llvm-mt)
set(CMAKE_C_COMPILER_TARGET x86_64-pc-windows-msvc)
set(CMAKE_CXX_COMPILER_TARGET x86_64-pc-windows-msvc)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# Force /MD (release CRT) for every config. xenia's CMakeLists.txt does a
# `string(REPLACE "/MDd" "/MD" ...)` on CMAKE_CXX_FLAGS_DEBUG, but with
# clang-cl, the runtime selection comes from CMAKE_MSVC_RUNTIME_LIBRARY
# (which expands to -MDd in dash form), so the substitution misses.
# Pinning the policy here avoids the need for non-redistributable debug
# CRT DLLs (MSVCP140D.dll etc) at runtime, which xwin doesn't ship.
cmake_policy(SET CMP0091 NEW)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL")
# xwin's default splat is a flat layout (crt/include, sdk/include/{ucrt,um,shared,...}),
# which clang-cl's /winsysroot does NOT understand. Use explicit -imsvc + -libpath:
# instead. Re-running `xwin splat --use-winsysroot-style` would also work but
# requires re-downloading ~600 MB.
# Use SHELL: prefix so CMake doesn't deduplicate repeated -imsvc tokens.
add_compile_options(
"SHELL:-imsvc \"${XWIN_DIR}/crt/include\""
"SHELL:-imsvc \"${XWIN_DIR}/sdk/include/ucrt\""
"SHELL:-imsvc \"${XWIN_DIR}/sdk/include/um\""
"SHELL:-imsvc \"${XWIN_DIR}/sdk/include/shared\""
"SHELL:-imsvc \"${XWIN_DIR}/sdk/include/winrt\""
)
add_link_options(
"/libpath:${XWIN_DIR}/crt/lib/x86_64"
"/libpath:${XWIN_DIR}/sdk/lib/ucrt/x86_64"
"/libpath:${XWIN_DIR}/sdk/lib/um/x86_64"
)
# xwin pulls the latest MSVC STL which now hard-asserts Clang >= 19. Our host
# has Clang 18, which works fine in practice — opt out of the version check.
# (See yvals_core.h STL1000 in $XWIN_DIR/crt/include.)
add_compile_definitions(_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH)
# llvm-rc needs SDK headers explicitly + the resource file's own dir so the
# RC's relative ICON path (..\..\..\assets\icon\icon.ico) resolves.
get_filename_component(_toolchain_dir "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
get_filename_component(_xenia_root "${_toolchain_dir}/../.." ABSOLUTE)
set(CMAKE_RC_FLAGS_INIT
"/I \"${XWIN_DIR}/sdk/include/um\" /I \"${XWIN_DIR}/sdk/include/shared\" /I \"${_xenia_root}/src/xenia/app\"")
# Quiet MSVC-STL false positives and xenia-specific warnings that clang-cl
# emits but cl.exe doesn't (treated as errors under /WX).
add_compile_options(
-Wno-microsoft-include
-Wno-unused-command-line-argument
-Wno-ignored-pragma-intrinsic
-Wno-nonportable-include-path
-Wno-pragma-pack
-Wno-tautological-pointer-compare
-Wno-microsoft-cast
-Wno-deprecated-declarations
# These are silenced for native Linux Clang in CMakeLists.txt's else() branch,
# but the if(MSVC) branch fires under clang-cl and skips them — so re-add.
-Wno-switch
-Wno-attributes
-Wno-deprecated-register
-Wno-deprecated-volatile
-Wno-deprecated-enum-enum-conversion
# cl.exe accepts __pragma(optimize("s",on)); clang-cl only knows the empty
# argument form. xenia gates XE_MSVC_OPTIMIZE_SMALL on _MSC_VER so the
# rejected pragma still emits from the clang-cl path. Treat as no-op.
-Wno-ignored-pragmas
# xenia decorates several `virtual` methods with XE_FORCEINLINE; clang-cl
# then complains that the inline body isn't visible in includer TUs
# (definitions live in command_processor.cc). cl.exe accepts this silently.
-Wno-undefined-inline
-Wno-sizeof-pointer-memaccess
# `'ZM'` (PE magic, stored little-endian as "MZ" in the binary) — cl.exe
# accepts the multi-char constant silently; clang-cl errors under /WX.
-Wno-multichar
)
# _mm_cvtsi64x_si128 is an MSVC-only alias for the standard _mm_cvtsi64_si128.
# Used (gated on XE_PLATFORM_WIN32) in xenia/gpu/draw_util.cc.
add_compile_definitions(_mm_cvtsi64x_si128=_mm_cvtsi64_si128)
# Plumb FXC for tools/build/compile_shader_dxbc.py (wine fxc auto-prepend).
# Use real Win10 SDK fxc.exe 10.x (supports SM 5_1, produces vkd3d-proton-
# acceptable DXBC). Extracted from the Win11 SDK 26100 ISO -> Store Apps
# Tools MSI's CABs.
if(DEFINED ENV{FXC_PATH})
set(ENV_FXC "$ENV{FXC_PATH}")
else()
set(ENV_FXC "$ENV{HOME}/.local/share/xenia-cross/fxc/fxc.exe")
endif()
set(ENV{FXC_PATH} "${ENV_FXC}")
set(CMAKE_FIND_ROOT_PATH "${XWIN_DIR}")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

View File

@@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""Scan xenia source for #include directives and ensure case-aliases exist
in xwin's flat SDK/CRT include dirs. xwin's default splat adds lowercase
aliases for headers that ship with uppercase names (e.g. Windows.h),
but does NOT add aliases in the reverse direction. xenia (and its
third_party deps) include some headers using historical Microsoft casing
(<ObjBase.h>, <Psapi.h>) that don't match the lowercase filenames the
SDK ships with. This helper creates the missing symlinks.
Idempotent: re-running is safe.
"""
from __future__ import annotations
import os
import re
import sys
from pathlib import Path
INCLUDE_RE = re.compile(r'^\s*#\s*include\s*<([A-Za-z][A-Za-z0-9_/.\-]*\.h)>',
re.MULTILINE)
SOURCE_ROOTS = [
"src",
"third_party/SDL2/src",
"third_party/SDL2/include",
"third_party/discord-rpc/src",
"third_party/fmt",
"third_party/imgui",
]
SOURCE_EXTS = {".h", ".hpp", ".inc", ".c", ".cc", ".cpp", ".cxx"}
def collect_includes(repo_root: Path) -> set[str]:
"""Return set of all <foo.h>-style include targets found in source."""
seen: set[str] = set()
for root in SOURCE_ROOTS:
base = repo_root / root
if not base.exists():
continue
for path in base.rglob("*"):
if path.suffix.lower() not in SOURCE_EXTS:
continue
try:
txt = path.read_text(encoding="utf-8", errors="ignore")
except OSError:
continue
for m in INCLUDE_RE.finditer(txt):
seen.add(m.group(1))
return seen
def index_dir(d: Path) -> dict[str, str]:
"""Return mapping lowercased-basename -> actual basename for files in d."""
if not d.is_dir():
return {}
idx: dict[str, str] = {}
for entry in d.iterdir():
idx.setdefault(entry.name.lower(), entry.name)
return idx
def fix_dir(target_dir: Path, want: set[str]) -> tuple[int, int, list[str]]:
"""For each header name in `want` (basename only), create a symlink to
the case-folded sibling if the exact case doesn't exist. Returns
(created, already_ok, missing-from-sdk)."""
if not target_dir.is_dir():
return 0, 0, []
idx = index_dir(target_dir)
created = 0
already_ok = 0
missing: list[str] = []
for name in want:
# Only look at single-segment names; subdir/foo.h handled separately
if "/" in name:
continue
actual = idx.get(name.lower())
if actual is None:
missing.append(name)
continue
if actual == name:
already_ok += 1
continue
link = target_dir / name
if link.exists() or link.is_symlink():
already_ok += 1
continue
try:
link.symlink_to(actual)
created += 1
except OSError as e:
print(f" ! failed to symlink {link} -> {actual}: {e}",
file=sys.stderr)
return created, already_ok, missing
def main() -> int:
if len(sys.argv) != 3:
print("usage: xwin-case-symlinks.py <xenia-canary-root> <xwin-splat-dir>",
file=sys.stderr)
return 2
repo_root = Path(sys.argv[1]).resolve()
xwin_root = Path(sys.argv[2]).resolve()
if not (xwin_root / "crt" / "include").exists():
print(f"error: {xwin_root}/crt/include missing", file=sys.stderr)
return 1
want = collect_includes(repo_root)
print(f"Collected {len(want)} unique #include <...> targets")
sdk_dirs = [
xwin_root / "crt" / "include",
xwin_root / "sdk" / "include" / "ucrt",
xwin_root / "sdk" / "include" / "um",
xwin_root / "sdk" / "include" / "shared",
xwin_root / "sdk" / "include" / "winrt",
]
total_created = 0
for d in sdk_dirs:
created, ok, _missing = fix_dir(d, want)
if created:
print(f" {d}: created {created} case-symlinks")
total_created += created
print(f"Done: created {total_created} case-symlinks total")
return 0
if __name__ == "__main__":
sys.exit(main())