From 7dfd790d087c468946d5bae5bdb6370c2c9a945b Mon Sep 17 00:00:00 2001 From: MiniRML <134226498+MiniRML@users.noreply.github.com> Date: Mon, 12 Oct 2026 09:05:52 -0700 Subject: [PATCH] fix(release): find the configured Windows runtime --- tools/package_release.py | 11 ++++++++++- tools/tests/test_package_release.py | 30 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/tools/package_release.py b/tools/package_release.py index 52f0b3ffc7..fea3cbff8a 100644 --- a/tools/package_release.py +++ b/tools/package_release.py @@ -9,6 +9,15 @@ from pathlib import Path ROOT = Path(__file__).resolve().parent.parent +def windows_runtime(build): + for line in (build / "CMakeCache.txt").read_text(encoding="utf-8").splitlines(): + if line.startswith("CMAKE_CXX_COMPILER:"): + compiler = line.partition("=")[2] + if compiler and not compiler.endswith("-NOTFOUND"): + return Path(compiler).parent + raise RuntimeError(f"CMAKE_CXX_COMPILER is not configured in {build / 'CMakeCache.txt'}") + + def package(platform, build, output, version): if not re.fullmatch(r"v[0-9A-Za-z][0-9A-Za-z._-]*", version) or version.endswith("."): raise ValueError(f"Invalid release tag for asset filenames: {version}") @@ -20,7 +29,7 @@ def package(platform, build, output, version): executable = "relinker.exe" if platform == "windows" else "relinker" files = [library for library in libraries if library.name in expected] if platform == "windows": - runtime = Path("C:/winlibs/mingw64/bin") + runtime = windows_runtime(build) files.extend(runtime / name for name in ("libgcc_s_seh-1.dll", "libstdc++-6.dll", "libwinpthread-1.dll")) binary = build / "core/relinker" / executable for file in [*files, binary]: diff --git a/tools/tests/test_package_release.py b/tools/tests/test_package_release.py index a969a1692a..7c72e3cb91 100644 --- a/tools/tests/test_package_release.py +++ b/tools/tests/test_package_release.py @@ -42,6 +42,36 @@ class ReleasePackageTests(unittest.TestCase): self.addCleanup(patch.stopall) patch.object(package_release, "ROOT", self.source, create=True).start() + def test_windows_runtime_follows_the_configured_compiler_directory(self): + runtime = self.root / "custom toolchain" / "bin" + runtime.mkdir(parents=True) + names = ("libgcc_s_seh-1.dll", "libstdc++-6.dll", "libwinpthread-1.dll") + for name in names: + (runtime / name).write_bytes(name.encode()) + compiler = runtime / "g++.exe" + (self.build / "CMakeCache.txt").write_text("CMAKE_CXX_COMPILER:STRING=" + compiler.as_posix() + "\n", encoding="utf-8") + (self.build / "core/relinker/relinker.exe").write_bytes(b"Windows executable") + package_release.package("windows", self.build, self.output, "v1") + with zipfile.ZipFile(self.output / "prx-windows-v1.zip") as archive: + self.assertEqual(set(archive.namelist()), {"libs/libc.prx", *("libs/" + name for name in names)}) + for name in names: + self.assertEqual(archive.read("libs/" + name), name.encode()) + with tarfile.open(self.output / "prx-windows-v1.tar.gz") as archive: + for name in names: + self.assertEqual(archive.extractfile("libs/" + name).read(), name.encode()) + self.assertEqual((self.output / "relinker-v1.exe").read_bytes(), b"Windows executable") + + def test_windows_package_without_configured_compiler_preserves_existing_output(self): + (self.build / "CMakeCache.txt").write_text("CMAKE_CXX_COMPILER:FILEPATH=compiler-NOTFOUND\n", encoding="utf-8") + (self.build / "core/relinker/relinker.exe").write_bytes(b"Windows executable") + self.output.mkdir() + previous = self.output / "previous.asset" + previous.write_bytes(b"existing output") + with self.assertRaisesRegex(RuntimeError, "CMAKE_CXX_COMPILER"): + package_release.package("windows", self.build, self.output, "v1") + self.assertEqual(list(self.output.iterdir()), [previous]) + self.assertEqual(previous.read_bytes(), b"existing output") + def test_source_discovery_does_not_depend_on_working_directory(self): with working_directory(self.root): package_release.package("linux", self.build, self.output, "v1.0")