Files
VoxelForge/Standalone/Tools/verify/source_stamp.py
T
Fr0zkaandClaude Opus 5.5 1abee91721 refactor: resolved metre layout is the runtime authority (L41, migration step 3); stamp covers plugin sources; R8
UVoxelStrateManager::Initialize resolves the layout width to integer micrometres before passages or
scheduling; each slot stores physical [bottom, top) bounds, transition mode/width and passage settings;
chunk indices remain a floor-based compatibility projection. The Core adapter derives interiors and L29
bands from those resolved values. verify: full-tier cost baseline is HEAD (or --baseline), tier timeout
7200 s with 1800 s per process; the source stamp now includes the plugin Source tree compiled on Linux
(it previously missed VoxelStrateManager.cpp and friends). Owner hashes identical to L37; fast, medium
and full PASS on a clean rebuild. Unreal manager/adapter edits are uncompiled on Windows.
Research R8: inventory of unit-bearing UPROPERTYs and a custom-version asset migration plan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-10-23 19:36:51 +02:00

107 lines
4.0 KiB
Python

#!/usr/bin/env python3
"""Build and verify the final-source manifest used by Linux executables."""
from __future__ import annotations
import argparse
import hashlib
from pathlib import Path
import sys
def sha256(data: bytes) -> str:
return hashlib.sha256(data).hexdigest()
def manifest_entries(root: Path, include_unreal: bool = False) -> list[tuple[str, bytes]]:
standalone = root / "Standalone"
files: set[Path] = set()
core = standalone / "Core"
for suffix in ("*.h", "*.hpp", "*.cpp", "*.txt"):
files.update(core.rglob(suffix))
source = standalone / "Source"
for suffix in ("*.h", "*.hpp", "*.cpp"):
files.update(source.glob(suffix))
for path in standalone.glob("Build*"):
if path.is_file():
files.add(path)
for suffix in ("*.cmake", "*.mk", "Makefile", "CMakeLists.txt"):
files.update(standalone.glob(suffix))
core_build = standalone / "Core"
for suffix in ("*.cmake", "*.mk", "Makefile", "CMakeLists.txt"):
files.update(core_build.glob(suffix))
helper = standalone / "Tools/verify/source_stamp.py"
if helper.is_file():
files.add(helper)
# Plugin sources listed in core_sources.txt are compiled into the Linux binaries, and their
# headers are included by Core, so the whole plugin Source tree is always part of the stamp.
plugin_source = root / "Source" / "VoxelForge"
for suffix in ("*.h", "*.hpp", "*.cpp", "*.inl"):
files.update(plugin_source.rglob(suffix))
compat = standalone / "Compat"
for suffix in ("*.h", "*.hpp", "*.cpp"):
files.update(compat.rglob(suffix))
if include_unreal:
for suffix in ("*.cs",):
files.update(plugin_source.rglob(suffix))
entries = [(path.relative_to(root).as_posix(), path.read_bytes())
for path in files if path.is_file()]
# BuildLinux creates one namespace wrapper per listed Core implementation.
# Include each exact generated wrapper as a virtual source input.
source_list = core / "core_sources.txt"
for raw in source_list.read_text(encoding="utf-8").splitlines():
name = raw.split("#", 1)[0].strip()
if not name or name == "Core/src/VoxelForgeCore.cpp":
continue
source_path = standalone / name
if not source_path.is_file():
raise SystemExit(f"missing source listed in Core/core_sources.txt: {name}")
wrapper_name = "vfcore_" + "".join(c if c.isalnum() else "_" for c in name)
wrapper = ('#include "CoreNamespacePreamble.h"\n'
"namespace vfcore::detail\n{\n"
f'#include "{source_path}"\n'
"}\n").encode("utf-8")
entries.append((f"generated/wrappers/{wrapper_name}.cpp", wrapper))
return sorted(entries, key=lambda item: item[0])
def rendered_manifest(root: Path, include_unreal: bool = False) -> bytes:
lines = [f"{sha256(data)} {name}" for name, data in
manifest_entries(root, include_unreal)]
return ("\n".join(lines) + "\n").encode("utf-8")
def source_stamp(root: Path, include_unreal: bool = False) -> str:
return sha256(rendered_manifest(root, include_unreal))
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("command", choices=("stamp", "write-manifest"))
parser.add_argument("--root", type=Path,
default=Path(__file__).resolve().parents[3])
parser.add_argument("--output", type=Path)
parser.add_argument("--include-unreal-adapter", action="store_true")
args = parser.parse_args()
root = args.root.resolve()
manifest = rendered_manifest(root, args.include_unreal_adapter)
stamp = sha256(manifest)
if args.command == "write-manifest":
if args.output is None:
parser.error("write-manifest requires --output")
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_bytes(manifest)
print(stamp)
return 0
if __name__ == "__main__":
raise SystemExit(main())