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
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:
126
cmake/toolchains/xwin-case-symlinks.py
Normal file
126
cmake/toolchains/xwin-case-symlinks.py
Normal 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())
|
||||
Reference in New Issue
Block a user