mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
toolchain patch windows
This commit is contained in:
@@ -538,6 +538,7 @@ static int resolve_toolchain_bin(char* out, size_t cap) {
|
||||
}
|
||||
|
||||
static void activate_toolchain_path(void) {
|
||||
char pack_root[1400];
|
||||
g_toolchain_bin[0] = '\0';
|
||||
if (!resolve_toolchain_bin(g_toolchain_bin, sizeof(g_toolchain_bin)))
|
||||
return;
|
||||
@@ -553,6 +554,39 @@ static void activate_toolchain_path(void) {
|
||||
old ? old : "");
|
||||
setenv("PATH", neu, 1);
|
||||
#endif
|
||||
/* Pack root (parent of bin/) — Windows cmake-clang-v1 ships zlib here. */
|
||||
if (dirname_copy(pack_root, sizeof(pack_root), g_toolchain_bin) &&
|
||||
pack_root[0]) {
|
||||
#if defined(_WIN32)
|
||||
_putenv_s("ZLIB_ROOT", pack_root);
|
||||
{
|
||||
const char* prev = getenv("CMAKE_PREFIX_PATH");
|
||||
char pref[8192];
|
||||
if (prev && prev[0] && !strstr(prev, pack_root))
|
||||
snprintf(pref, sizeof(pref), "%s;%s", pack_root, prev);
|
||||
else if (!prev || !prev[0])
|
||||
snprintf(pref, sizeof(pref), "%s", pack_root);
|
||||
else
|
||||
pref[0] = '\0';
|
||||
if (pref[0])
|
||||
_putenv_s("CMAKE_PREFIX_PATH", pref);
|
||||
}
|
||||
#else
|
||||
setenv("ZLIB_ROOT", pack_root, 1);
|
||||
{
|
||||
const char* prev = getenv("CMAKE_PREFIX_PATH");
|
||||
char pref[8192];
|
||||
if (prev && prev[0] && !strstr(prev, pack_root))
|
||||
snprintf(pref, sizeof(pref), "%s:%s", pack_root, prev);
|
||||
else if (!prev || !prev[0])
|
||||
snprintf(pref, sizeof(pref), "%s", pack_root);
|
||||
else
|
||||
pref[0] = '\0';
|
||||
if (pref[0])
|
||||
setenv("CMAKE_PREFIX_PATH", pref, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static int find_cmake(char* out, size_t cap) {
|
||||
@@ -1623,6 +1657,12 @@ static int write_windows_deferred_rebuild_helper(char* err_msg, size_t err_cap)
|
||||
snprintf(err_msg, err_cap, "Failed to form helper path.");
|
||||
return 0;
|
||||
}
|
||||
/* Setup zips omit build-release/; create it before writing the .cmd. */
|
||||
if (!mkdir_p(g_build_dir)) {
|
||||
snprintf(err_msg, err_cap, "Failed to create build dir: %s",
|
||||
g_build_dir);
|
||||
return 0;
|
||||
}
|
||||
FILE* f = fopen(g_helper_path, "wb");
|
||||
if (!f) {
|
||||
snprintf(err_msg, err_cap, "Failed to write rebuild helper: %s",
|
||||
|
||||
+22
-10
@@ -375,7 +375,7 @@ def ensure_framework(
|
||||
if need_seed and (ROOT / "bios").is_dir():
|
||||
if progress:
|
||||
progress.log(
|
||||
f"Seeding psxrecomp BIOS profiles from SDK → {fw}"
|
||||
f"Seeding psxrecomp BIOS profiles from SDK -> {fw}"
|
||||
)
|
||||
fw.mkdir(parents=True, exist_ok=True)
|
||||
_copy_missing(ROOT / "bios", fw / "bios")
|
||||
@@ -533,7 +533,7 @@ def run_prepare_disc(
|
||||
script = ROOT / "tools" / "prepare_disc.py"
|
||||
if not script.is_file():
|
||||
raise RuntimeError(f"missing {script}")
|
||||
progress.phase("prepare_disc", pct=0.15, message="Normalizing disc image…")
|
||||
progress.phase("prepare_disc", pct=0.15, message="Normalizing disc image...")
|
||||
cmd = [
|
||||
sys.executable,
|
||||
str(script),
|
||||
@@ -633,7 +633,7 @@ def cmd_generate(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
progress.error(f"BIOS not found: {bios_path}", code=EXIT_USAGE)
|
||||
return EXIT_USAGE
|
||||
dest = fw / "bios" / "SCPH1001.BIN"
|
||||
progress.phase("bios", pct=0.15, message="Staging retail BIOS dump…")
|
||||
progress.phase("bios", pct=0.15, message="Staging retail BIOS dump...")
|
||||
try:
|
||||
dest.parent.mkdir(parents=True, exist_ok=True)
|
||||
if dest.resolve() != bios_path.resolve():
|
||||
@@ -642,7 +642,7 @@ def cmd_generate(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
progress.error(f"failed to stage BIOS: {exc}", code=EXIT_ERROR)
|
||||
return EXIT_ERROR
|
||||
try:
|
||||
progress.phase("bios", pct=0.2, message="Generating SCPH1001 BIOS C…")
|
||||
progress.phase("bios", pct=0.2, message="Generating SCPH1001 BIOS C...")
|
||||
regen_bios_profile(project_root, "bios/SCPH1001.toml", progress=progress)
|
||||
staged_retail = True
|
||||
except Exception as exc: # noqa: BLE001
|
||||
@@ -661,7 +661,7 @@ def cmd_generate(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
):
|
||||
try:
|
||||
progress.phase(
|
||||
"bios", pct=0.25, message="Generating OpenBIOS backend C…"
|
||||
"bios", pct=0.25, message="Generating OpenBIOS backend C..."
|
||||
)
|
||||
regen_bios_profile(project_root, "bios/OpenBIOS.toml", progress=progress)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
@@ -682,7 +682,7 @@ def cmd_generate(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
progress.phase(
|
||||
"emit",
|
||||
pct=0.35,
|
||||
message=f"Running psxrecomp-game → {out_dir}",
|
||||
message=f"Running psxrecomp-game -> {out_dir}",
|
||||
)
|
||||
cmd = [str(game_tool), "--config", str(config)]
|
||||
proc = subprocess.run(
|
||||
@@ -1060,7 +1060,7 @@ def cmd_rebuild(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
|
||||
try:
|
||||
if not pgo_enabled:
|
||||
progress.phase("build", pct=0.2, message="cmake Release build…")
|
||||
progress.phase("build", pct=0.2, message="cmake Release build...")
|
||||
_cmake_configure(
|
||||
project_root, build_dir, pgo="", extra=cmake_extra, progress=progress
|
||||
)
|
||||
@@ -1076,7 +1076,7 @@ def cmd_rebuild(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
progress.phase(
|
||||
"pgo_instrument",
|
||||
pct=0.1,
|
||||
message="PGO instrumented build…",
|
||||
message="PGO instrumented build...",
|
||||
)
|
||||
_cmake_configure(
|
||||
project_root,
|
||||
@@ -1103,7 +1103,7 @@ def cmd_rebuild(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
hide_video=hide_video,
|
||||
progress=progress,
|
||||
)
|
||||
progress.phase("pgo_use", pct=0.85, message="PGO optimized rebuild…")
|
||||
progress.phase("pgo_use", pct=0.85, message="PGO optimized rebuild...")
|
||||
_cmake_configure(
|
||||
project_root,
|
||||
build_dir,
|
||||
@@ -1126,7 +1126,7 @@ def cmd_rebuild(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
prune_raw = (getattr(args, "prune_after", None) or "").strip()
|
||||
if prune_raw:
|
||||
modes = {m.strip() for m in prune_raw.split(",") if m.strip()}
|
||||
progress.phase("prune", pct=0.97, message="Pruning toolchain / build bulk…")
|
||||
progress.phase("prune", pct=0.97, message="Pruning toolchain / build bulk...")
|
||||
prune_after_rebuild(project_root, build_dir, modes, progress)
|
||||
|
||||
progress.phase("done", pct=1.0, message="Rebuild complete")
|
||||
@@ -1314,7 +1314,19 @@ def build_parser() -> argparse.ArgumentParser:
|
||||
return ap
|
||||
|
||||
|
||||
def _configure_stdio() -> None:
|
||||
"""Best-effort: don't crash on Windows cp1252 when logging Unicode."""
|
||||
for stream in (sys.stdout, sys.stderr):
|
||||
reconf = getattr(stream, "reconfigure", None)
|
||||
if callable(reconf):
|
||||
try:
|
||||
reconf(errors="replace")
|
||||
except Exception: # noqa: BLE001
|
||||
pass
|
||||
|
||||
|
||||
def main() -> int:
|
||||
_configure_stdio()
|
||||
args = build_parser().parse_args()
|
||||
progress = ProgressReporter(json_progress=bool(getattr(args, "json_progress", False)))
|
||||
try:
|
||||
|
||||
+57
-1
@@ -488,6 +488,60 @@ if(NOT PSXRECOMP_SKIP_BIOS_STALE_CHECK AND _psxrt_bios_linked)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# zlib for boot_state v4. System packages first; otherwise FetchContent a pinned
|
||||
# release so portable Windows cmake-clang-v1 setups can configure without MSYS2.
|
||||
option(PSX_ZLIB_FETCH
|
||||
"Fetch zlib when no system ZLIB package is found"
|
||||
ON)
|
||||
function(psxrecomp_ensure_zlib)
|
||||
if(TARGET ZLIB::ZLIB)
|
||||
return()
|
||||
endif()
|
||||
find_package(ZLIB QUIET)
|
||||
if(TARGET ZLIB::ZLIB)
|
||||
return()
|
||||
endif()
|
||||
if(NOT PSX_ZLIB_FETCH)
|
||||
message(FATAL_ERROR
|
||||
"ZLIB was not found. On Windows, use a cmake-clang-v1 pack that "
|
||||
"ships include/zlib.h + lib/libz.a (sets ZLIB_ROOT), or install "
|
||||
"zlib-devel / mingw-w64-zlib, or configure with -DPSX_ZLIB_FETCH=ON.")
|
||||
endif()
|
||||
message(STATUS
|
||||
"psxrecomp: ZLIB not in CMAKE_PREFIX_PATH/ZLIB_ROOT; "
|
||||
"fetching zlib 1.3.1 (prefer a toolchain pack that bundles it)")
|
||||
include(FetchContent)
|
||||
set(_psx_zlib_timestamp_args "")
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
|
||||
list(APPEND _psx_zlib_timestamp_args DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
|
||||
endif()
|
||||
FetchContent_Declare(psx_zlib
|
||||
URL
|
||||
"https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz"
|
||||
URL_HASH
|
||||
"SHA256=9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23"
|
||||
${_psx_zlib_timestamp_args})
|
||||
FetchContent_MakeAvailable(psx_zlib)
|
||||
if(TARGET ZLIB::ZLIB)
|
||||
message(STATUS "psxrecomp: ZLIB via FetchContent (ZLIB::ZLIB)")
|
||||
return()
|
||||
endif()
|
||||
# madler/zlib builds zlibstatic even when a shared zlib target exists.
|
||||
if(TARGET zlibstatic)
|
||||
add_library(ZLIB::ZLIB ALIAS zlibstatic)
|
||||
message(STATUS "psxrecomp: ZLIB via FetchContent (zlibstatic)")
|
||||
return()
|
||||
endif()
|
||||
if(TARGET zlib)
|
||||
add_library(ZLIB::ZLIB ALIAS zlib)
|
||||
message(STATUS "psxrecomp: ZLIB via FetchContent (zlib)")
|
||||
return()
|
||||
endif()
|
||||
message(FATAL_ERROR
|
||||
"Fetched zlib but no linkable target was produced "
|
||||
"(expected zlibstatic or zlib).")
|
||||
endfunction()
|
||||
|
||||
function(psxrecomp_add_runtime_target target)
|
||||
set(options ORACLE COSIM)
|
||||
set(oneValueArgs
|
||||
@@ -732,7 +786,9 @@ function(psxrecomp_add_runtime_target target)
|
||||
endif()
|
||||
|
||||
# zlib: boot_state v4 savestate compression (RAM/VRAM/SPU blobs).
|
||||
find_package(ZLIB REQUIRED)
|
||||
# Portable Windows toolchains (cmake-clang-v1) have no system zlib —
|
||||
# fetch a pinned release when find_package fails (same pattern as SDL3).
|
||||
psxrecomp_ensure_zlib()
|
||||
target_link_libraries(${target} PRIVATE ZLIB::ZLIB)
|
||||
|
||||
# Build identity: stamp the psxrecomp commit into the binary so a crash report
|
||||
|
||||
+19
-7
@@ -33,6 +33,17 @@ USER_OFF = 24
|
||||
SYNC = bytes([0x00] + [0xFF] * 10 + [0x00])
|
||||
|
||||
|
||||
def _configure_stdio() -> None:
|
||||
"""Avoid UnicodeEncodeError on Windows consoles (cp1252 / Store Python)."""
|
||||
for stream in (sys.stdout, sys.stderr):
|
||||
reconf = getattr(stream, "reconfigure", None)
|
||||
if callable(reconf):
|
||||
try:
|
||||
reconf(errors="replace")
|
||||
except Exception: # noqa: BLE001 — best-effort stdio harden
|
||||
pass
|
||||
|
||||
|
||||
def _build_edc_table() -> list[int]:
|
||||
table = []
|
||||
for i in range(256):
|
||||
@@ -388,7 +399,7 @@ def raw2448_to_bin(src: Path) -> bytes:
|
||||
raise SystemExit(f"truncated 2448 sector {n}: got {len(sec)} bytes")
|
||||
out += sec[:DST_SEC]
|
||||
n += 1
|
||||
print(f" trimmed {n} sectors 2448 → 2352")
|
||||
print(f" trimmed {n} sectors 2448 -> 2352")
|
||||
return bytes(out)
|
||||
|
||||
|
||||
@@ -408,8 +419,9 @@ def matches_known(cfg: PrepareConfig, size: int, md5: str, sha1: str) -> bool:
|
||||
|
||||
|
||||
def main() -> int:
|
||||
_configure_stdio()
|
||||
here = Path(__file__).resolve().parent
|
||||
# tools/ → psxrecomp/ → often game root is parent of psxrecomp
|
||||
# tools/ -> psxrecomp/ -> often game root is parent of psxrecomp
|
||||
fw_root = here.parent
|
||||
ap = argparse.ArgumentParser(description=__doc__)
|
||||
ap.add_argument("source", nargs="?", default="", help="path to .iso / .cue / .bin")
|
||||
@@ -489,7 +501,7 @@ def main() -> int:
|
||||
if kind == "cue":
|
||||
src = resolve_cue_bin(src)
|
||||
src_md5, src_sha1, src_size = file_hashes(src)
|
||||
print(f"cue → bin: {src}")
|
||||
print(f"cue -> bin: {src}")
|
||||
print(f" size {src_size}")
|
||||
print(f" md5 {src_md5}")
|
||||
print(f" sha1 {src_sha1}")
|
||||
@@ -512,7 +524,7 @@ def main() -> int:
|
||||
"verifying boot EXE only."
|
||||
)
|
||||
elif not cfg.known and not cfg.skip_hash_check and kind == "bin2352":
|
||||
print(" no prepare_disc.known_* configured — verifying boot EXE only")
|
||||
print(" no prepare_disc.known_* configured - verifying boot EXE only")
|
||||
|
||||
if kind == "bin2352":
|
||||
bin_data = src.read_bytes()
|
||||
@@ -520,11 +532,11 @@ def main() -> int:
|
||||
elif kind == "iso":
|
||||
iso_data = src.read_bytes()
|
||||
entries, files = extract_via(read_user_iso, iso_data, cfg.boot_exe)
|
||||
print(f" converting {len(iso_data) // USER} sectors ISO → MODE2/2352…")
|
||||
print(f" converting {len(iso_data) // USER} sectors ISO -> MODE2/2352...")
|
||||
bin_data = iso_to_bin(iso_data)
|
||||
extract_via(read_user_bin, bin_data, cfg.boot_exe)
|
||||
elif kind == "raw2448":
|
||||
print(" converting 2448 → 2352…")
|
||||
print(" converting 2448 -> 2352...")
|
||||
bin_data = raw2448_to_bin(src)
|
||||
entries, files = extract_via(read_user_bin, bin_data, cfg.boot_exe)
|
||||
else:
|
||||
@@ -563,7 +575,7 @@ def main() -> int:
|
||||
print(f" md5 {out_md5}")
|
||||
print(f" sha1 {out_sha1}")
|
||||
if kind == "iso":
|
||||
print(" rebuilt from ISO (EDC set; ECC zeroed — fine for software readers)")
|
||||
print(" rebuilt from ISO (EDC set; ECC zeroed - fine for software readers)")
|
||||
elif kind == "raw2448":
|
||||
print(" trimmed from 2448-byte/sector dump")
|
||||
|
||||
|
||||
+10
-1
@@ -231,10 +231,19 @@ def resolve_toolchain_bin(project_root: Optional[Path] = None) -> Optional[Path]
|
||||
|
||||
def activate_toolchain_bin(bin_dir: Path, log=None) -> None:
|
||||
prefix = str(bin_dir)
|
||||
pack_root = bin_dir.parent
|
||||
cur = os.environ.get("PATH", "")
|
||||
parts = cur.split(os.pathsep) if cur else []
|
||||
if not parts or Path(parts[0]) != bin_dir:
|
||||
os.environ["PATH"] = prefix + (os.pathsep + cur if cur else "")
|
||||
# Windows cmake-clang-v1 ships zlib under the pack root; help FindZLIB.
|
||||
pack_s = str(pack_root)
|
||||
os.environ["ZLIB_ROOT"] = pack_s
|
||||
prev_prefix = os.environ.get("CMAKE_PREFIX_PATH", "")
|
||||
if not prev_prefix:
|
||||
os.environ["CMAKE_PREFIX_PATH"] = pack_s
|
||||
elif pack_s not in prev_prefix.split(os.pathsep):
|
||||
os.environ["CMAKE_PREFIX_PATH"] = pack_s + os.pathsep + prev_prefix
|
||||
for name, env_key in (
|
||||
("clang", "CC"),
|
||||
("clang++", "CXX"),
|
||||
@@ -306,7 +315,7 @@ def download_latest_pack(
|
||||
token = os.environ.get("GH_TOKEN") or os.environ.get("GITHUB_TOKEN") or ""
|
||||
url = f"https://github.com/{repo}/releases/latest/download/{asset}"
|
||||
if log:
|
||||
log(f"Downloading {asset} from {repo}…")
|
||||
log(f"Downloading {asset} from {repo}...")
|
||||
with tempfile.TemporaryDirectory(prefix="psxrecomp-tc-") as tmp:
|
||||
zpath = Path(tmp) / asset
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user