mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
cli: stage the overlay toolchain beside every built product
No setup package ever staged one, so overlay_cache = true alone left every streamed overlay on the interpreter. rebuild now stages the pinned Python, tcc, this pin's recompiler, headers and the build's codegen hash beside the normal and diagnostic products, and writes compiler.txt naming the compiler the wizard already has; the runtime treats that as a gcc-tier compiler, so a player with nothing on PATH gets -O2 shards. Verified on the NCII kit: gcc tier reported and four shards built with no compiler on PATH. (cherry picked from commit 03865e10f6ee198d58c47c74526df5db46bb35a9)
This commit is contained in:
@@ -1778,6 +1778,8 @@ def cmd_rebuild(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
if exe is None:
|
||||
progress.error(exe_err, code=EXIT_ERROR)
|
||||
return EXIT_ERROR
|
||||
progress.phase("overlays", pct=0.93, message="Staging overlay toolchain beside the product...")
|
||||
stage_overlay_toolchain_for_product(project_root, exe.parent, progress)
|
||||
|
||||
prune_raw = (getattr(args, "prune_after", None) or "").strip()
|
||||
if prune_raw:
|
||||
@@ -1790,6 +1792,57 @@ def cmd_rebuild(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
return EXIT_OK
|
||||
|
||||
|
||||
def stage_overlay_toolchain_for_product(project_root: Path, exe_dir: Path, progress) -> Optional[Path]:
|
||||
"""Stage overlay_toolchain/ beside a built product so the runtime's autocompile gate is
|
||||
true for every player build (wave-5 F1), and name the compiler the wizard already has so
|
||||
shards get an optimising compiler instead of tcc (F2). Best effort: a failure leaves the
|
||||
product playable with overlays interpreted, and says so."""
|
||||
try:
|
||||
fw = framework_root(project_root)
|
||||
tools_dir = fw / "tools"
|
||||
inc_dir = fw / "runtime" / "include"
|
||||
game_emitter = find_psxrecomp_game(project_root)
|
||||
if str(tools_dir) not in sys.path:
|
||||
sys.path.insert(0, str(tools_dir))
|
||||
import release_stage # noqa: E402
|
||||
|
||||
dl_cache = project_root / ".cache" / "overlay-toolchain"
|
||||
# Runtime DLLs only from the emitter's own directory, never from PATH: Git's
|
||||
# mingw64 on PATH carries the MSVCRT runtime, which is the 0xC0000139 trap.
|
||||
mingw_bin = game_emitter.parent if (game_emitter.parent / "libgcc_s_seh-1.dll").is_file() else None
|
||||
tk = Path(release_stage.stage_toolchain(
|
||||
str(exe_dir), str(game_emitter.parent), str(tools_dir), str(inc_dir), str(dl_cache),
|
||||
mingw_bin=str(mingw_bin) if mingw_bin else None, log=progress.log))
|
||||
# The stale-recompiler check compares the emitter's codegen hash with the runtime's tag.
|
||||
for cand in (exe_dir / "psxrecomp_codegen_include" / "overlay_codegen_hash.h",
|
||||
inc_dir / "overlay_codegen_hash.h"):
|
||||
if cand.is_file():
|
||||
shutil.copy2(cand, tk / "include" / "overlay_codegen_hash.h")
|
||||
break
|
||||
compiler = None
|
||||
if sys.platform == "win32":
|
||||
bin_dir = resolve_toolchain_bin(project_root)
|
||||
if bin_dir and (bin_dir / "clang.exe").is_file():
|
||||
compiler = bin_dir / "clang.exe"
|
||||
else:
|
||||
for name in ("gcc", "cc", "clang"):
|
||||
w = shutil.which(name)
|
||||
if w:
|
||||
compiler = Path(w)
|
||||
break
|
||||
if compiler:
|
||||
(tk / "compiler.txt").write_text(str(compiler) + "\n", encoding="utf-8")
|
||||
progress.log(f"overlay toolchain staged at {tk}; shard compiler: {compiler}")
|
||||
else:
|
||||
progress.log(f"overlay toolchain staged at {tk}; no optimising compiler found (tcc tier)")
|
||||
return tk
|
||||
except Exception as exc: # noqa: BLE001
|
||||
progress.log(f"WARNING: overlay toolchain staging failed; overlays will run interpreted: {exc}")
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
def cmd_pgo_train(args: argparse.Namespace, progress: ProgressReporter) -> int:
|
||||
args.force_pgo = True
|
||||
args.no_pgo = False
|
||||
|
||||
+20
-3
@@ -13530,6 +13530,20 @@ int main(int argc, char** argv) {
|
||||
const char *tk_tcc = "tcc";
|
||||
#endif
|
||||
const bool tk_present = std::filesystem::exists(tk_py);
|
||||
/* Wave-5 F2: the CLI names the compiler it already has (the wizard's pack on
|
||||
* Windows, the native cc on POSIX) in overlay_toolchain/compiler.txt, so a player
|
||||
* with nothing on PATH still gets optimised shards instead of tcc's. */
|
||||
std::string tk_compiler;
|
||||
{
|
||||
std::ifstream cf(tk_dir / "compiler.txt");
|
||||
std::string line;
|
||||
if (cf.is_open() && std::getline(cf, line)) {
|
||||
while (!line.empty() && (line.back() == '\r' || line.back() == '\n' || line.back() == ' '))
|
||||
line.pop_back();
|
||||
std::error_code cec;
|
||||
if (!line.empty() && std::filesystem::exists(line, cec)) tk_compiler = line;
|
||||
}
|
||||
}
|
||||
auto build_toolchain_cmd = [&](const char *compiler) {
|
||||
auto cmd_quote = [](const std::string& s) {
|
||||
return std::string("\"") + s + "\"";
|
||||
@@ -13546,12 +13560,14 @@ int main(int argc, char** argv) {
|
||||
" --out-dir " + cmd_quote((tk_xd / "cache").string()) +
|
||||
(g_psx_cps_mode ? " --cps" : "") +
|
||||
" --compiler " + compiler;
|
||||
if (std::string(compiler) == "gcc" && !tk_compiler.empty())
|
||||
c += " --gcc " + cmd_quote(tk_compiler);
|
||||
if (std::string(compiler) == "tcc")
|
||||
c += " --tcc " + cmd_quote((tk_dir / "tcc" / tk_tcc).string());
|
||||
return c;
|
||||
};
|
||||
int gcc_avail = (deferred_has_overlay_ac || tk_present)
|
||||
&& autocompile_toolchain_available();
|
||||
&& (autocompile_toolchain_available() || !tk_compiler.empty());
|
||||
OverlayBackend eff = overlay_backend_resolve(cfg_backend, gcc_avail);
|
||||
std::string built_tcc_cmd;
|
||||
std::string built_gcc_cmd;
|
||||
@@ -13579,8 +13595,9 @@ int main(int argc, char** argv) {
|
||||
built_gcc_cmd = build_toolchain_cmd("gcc");
|
||||
ac_cmd = &built_gcc_cmd;
|
||||
std::fprintf(stdout,
|
||||
"psxrecomp: gcc tier using bundled toolchain (%s) with gcc from PATH\n",
|
||||
tk_dir.string().c_str());
|
||||
"psxrecomp: gcc tier using bundled toolchain (%s) with %s\n",
|
||||
tk_dir.string().c_str(),
|
||||
tk_compiler.empty() ? "gcc from PATH" : tk_compiler.c_str());
|
||||
}
|
||||
}
|
||||
if (const char *e = std::getenv("PSX_OVERLAY_AUTOCOMPILE_CMD")) {
|
||||
|
||||
+11
-3
@@ -636,10 +636,18 @@ def stage_toolchain(stage, recomp_dir, recomp_tools, recomp_include, dl_cache,
|
||||
# Windows needs the mingw runtime beside the recompiler; a Linux build links
|
||||
# against the system libstdc++ that is already present.
|
||||
if platform_tag == 'win':
|
||||
if not mingw_bin:
|
||||
_die('--mingw-bin is required when staging a Windows toolchain')
|
||||
# A recompiler built against a static CRT (the cmake-clang-v1 emitters) needs no
|
||||
# runtime DLLs; a gcc-built one does. Copy whatever the named bin dir (or the
|
||||
# emitter's own directory) holds, and say which case this is.
|
||||
dll_src = mingw_bin or recomp_dir
|
||||
copied = 0
|
||||
for d in ('libgcc_s_seh-1.dll', 'libstdc++-6.dll', 'libwinpthread-1.dll'):
|
||||
shutil.copy2(os.path.join(mingw_bin, d), os.path.join(toolchain, d))
|
||||
p = os.path.join(dll_src, d)
|
||||
if os.path.isfile(p):
|
||||
shutil.copy2(p, os.path.join(toolchain, d))
|
||||
copied += 1
|
||||
log('mingw runtime DLLs staged beside the recompiler: %d (from %s)%s'
|
||||
% (copied, dll_src, '' if copied else ' -- assuming a static recompiler'))
|
||||
|
||||
shutil.copy2(os.path.join(recomp_tools, 'compile_overlays.py'), toolchain)
|
||||
tool_inc = _mkdirs(os.path.join(toolchain, 'include'))
|
||||
|
||||
Reference in New Issue
Block a user