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>
56 lines
2.1 KiB
Python
Executable File
56 lines
2.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""Scan xenia source for #include <...> directives and ensure case-aliases
|
|
exist in xwin's flat SDK/CRT include dirs. Idempotent — safe to re-run."""
|
|
from __future__ import annotations
|
|
import os, re, 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]:
|
|
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 fix_dir(target_dir: Path, want: set[str]) -> int:
|
|
if not target_dir.is_dir(): return 0
|
|
idx = {e.name.lower(): e.name for e in target_dir.iterdir()}
|
|
created = 0
|
|
for name in want:
|
|
if "/" in name: continue
|
|
actual = idx.get(name.lower())
|
|
if actual is None or actual == name: continue
|
|
link = target_dir / name
|
|
if link.exists() or link.is_symlink(): continue
|
|
try:
|
|
link.symlink_to(actual)
|
|
created += 1
|
|
except OSError: pass
|
|
return created
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) != 3:
|
|
sys.exit("usage: xwin-case-symlinks.py <xenia-canary-root> <xwin-splat-dir>")
|
|
repo = Path(sys.argv[1]).resolve()
|
|
xwin = Path(sys.argv[2]).resolve()
|
|
want = collect_includes(repo)
|
|
total = 0
|
|
for d in (xwin/"crt/include", xwin/"sdk/include/ucrt",
|
|
xwin/"sdk/include/um", xwin/"sdk/include/shared",
|
|
xwin/"sdk/include/winrt"):
|
|
total += fix_dir(d, want)
|
|
print(f"Created {total} case-symlinks across {len(want)} unique includes.")
|