mirror of
https://github.com/RetroPortingToolKit/psxrecomp
synced 2026-10-26 02:11:36 -04:00
Merge pull request #442 from RetroPortingToolKit/fix/windows-framework-validation-20260930
fix: unblock Windows framework regression builds and tests
This commit is contained in:
@@ -11,6 +11,18 @@ import sys
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
if os.name == 'nt':
|
||||
import ctypes
|
||||
# Several publication checks deliberately probe non-PE synthetic DLLs.
|
||||
# CTest's Windows child error mode can display a loader error dialog and
|
||||
# block LoadLibrary indefinitely. Keep the real loader/export validation,
|
||||
# but make its expected failures noninteractive in this test process.
|
||||
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
|
||||
kernel32.GetErrorMode.restype = ctypes.c_uint
|
||||
kernel32.SetErrorMode.argtypes = [ctypes.c_uint]
|
||||
kernel32.SetErrorMode.restype = ctypes.c_uint
|
||||
kernel32.SetErrorMode(kernel32.GetErrorMode() | 0x0001 | 0x8000)
|
||||
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parents[2]
|
||||
SPEC = importlib.util.spec_from_file_location(
|
||||
|
||||
@@ -342,8 +342,7 @@ if(BUILD_TESTING)
|
||||
target_compile_options(gpu_textured_dot_nw_shift_exec_test PRIVATE
|
||||
-ffunction-sections -fdata-sections)
|
||||
target_link_options(gpu_textured_dot_nw_shift_exec_test PRIVATE
|
||||
-Wl,--gc-sections
|
||||
-Wl,--error-limit=0)
|
||||
-Wl,--gc-sections)
|
||||
endif()
|
||||
add_test(NAME gpu_textured_dot_nw_shift_exec_test
|
||||
COMMAND gpu_textured_dot_nw_shift_exec_test)
|
||||
|
||||
@@ -1629,7 +1629,12 @@ function(psxrecomp_add_runtime_target target)
|
||||
string(REPLACE "\\" "/" _psxrt_ico_fwd "${PSXRT_APP_ICON}")
|
||||
set(_psxrt_rc "${CMAKE_CURRENT_BINARY_DIR}/${target}_app_icon.rc")
|
||||
file(WRITE "${_psxrt_rc}" "IDI_ICON1 ICON \"${_psxrt_ico_fwd}\"\n")
|
||||
target_sources(${target} PRIVATE "${_psxrt_rc}")
|
||||
# The icon has no dependency on runtime macros or headers.
|
||||
# Compile it separately: windres launches a preprocessor through
|
||||
# a shell, which cannot round-trip the executable's quoted
|
||||
# string definitions (notably the pipe-separated BIOS stems).
|
||||
add_library(${target}_app_icon OBJECT "${_psxrt_rc}")
|
||||
target_sources(${target} PRIVATE $<TARGET_OBJECTS:${target}_app_icon>)
|
||||
message(STATUS "psxrecomp ${target}: APP_ICON=${PSXRT_APP_ICON} (RC=${CMAKE_RC_COMPILER})")
|
||||
else()
|
||||
message(WARNING
|
||||
|
||||
@@ -26,9 +26,11 @@ def function_body(name: str) -> str:
|
||||
|
||||
|
||||
reinsert = function_body("debug_force_cd_reinsert")
|
||||
assert "cdrom_lid_begin_open" in reinsert
|
||||
assert "s_lid_irq_pending = 1" in reinsert
|
||||
assert "set_irq(CDIRQ_ACK)" not in reinsert
|
||||
assert "begin_tray_open_cycle()" in reinsert
|
||||
tray_open = function_body("begin_tray_open_cycle")
|
||||
assert "cdrom_lid_begin_open" in tray_open
|
||||
assert "s_lid_irq_pending = 1" in tray_open
|
||||
assert "set_irq(CDIRQ_ACK)" not in reinsert + tray_open
|
||||
|
||||
present = function_body("present_lid_open_irq_if_ready")
|
||||
assert "response_push(0x08)" in present
|
||||
|
||||
@@ -15,6 +15,24 @@ uint32_t g_debug_current_func_addr;
|
||||
uint32_t g_debug_last_store_pc;
|
||||
CPUState *debug_cpu_ptr;
|
||||
int g_psx_vram_dirty_tracking;
|
||||
uint32_t g_psx_ram_size = 0x00200000u;
|
||||
uint32_t g_psx_ram_mask = 0x001FFFFFu;
|
||||
|
||||
/* This fixture exercises stock GPU packets without a GL context or mod bank.
|
||||
* Keep the gpu.c dependencies explicit, including on linkers that retain
|
||||
* additional exported command handlers despite --gc-sections. */
|
||||
GrBackend gr_backend(void) { return GR_BACKEND_SOFTWARE; }
|
||||
int gl_renderer_texture_banks_supported(void) { return 0; }
|
||||
int gl_renderer_select_texture_bank(uint16_t id) { (void)id; return 0; }
|
||||
uint16_t mod_texture_packet_bank(uint32_t source, const uint32_t *words,
|
||||
uint32_t count) {
|
||||
(void)source; (void)words; (void)count;
|
||||
return 0;
|
||||
}
|
||||
int mod_texture_packet_precision(uint32_t source, float q[3], float xy[6]) {
|
||||
(void)source; (void)q; (void)xy;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t test_ram[0x00200000u / 4u];
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ int main(int argc, char** argv) {
|
||||
env = os.environ.copy()
|
||||
compiler = shutil.which(args.compiler) or args.compiler
|
||||
env['PATH'] = str(Path(compiler).parent) + os.pathsep + env.get('PATH', '')
|
||||
subprocess.run([compiler, '-std=c++17', '-O2', '-I' + str(root/'include'), str(source),
|
||||
subprocess.run([compiler, '-std=c++17', '-O2', '-I' + str(root/'include'),
|
||||
'-I' + str(root.parent/'recompiler/include'), str(source),
|
||||
str(root/'src/disc_path.cpp'), str(root/'src/cue_sheet.cpp'), '-o', str(program)],
|
||||
check=True, env=env)
|
||||
for stem, tracks in [('disc', 12), ('album', 8)]:
|
||||
|
||||
@@ -124,6 +124,7 @@ def run_select(
|
||||
|
||||
driver = tmp / "select_driver.cmake"
|
||||
driver.write_text(
|
||||
'cmake_minimum_required(VERSION 3.20)\n'
|
||||
f'include("{SELECT.as_posix()}")\n'
|
||||
"psx_select_builtin_mod_ids(_out LABEL psx-runtime"
|
||||
+ cm_list("AVAILABLE", available)
|
||||
|
||||
@@ -104,7 +104,7 @@ SCANNED_NAMES = ('CMakeLists.txt',)
|
||||
|
||||
SKIP_DIRS = {'.git', 'build', 'generated', 'node_modules', '__pycache__',
|
||||
'lib', '_deps', 'beetle-psx', 'recomp-ui', 'psxrecomp-v4',
|
||||
'ghidra', 'seeds', 'assets'}
|
||||
'ghidra', 'seeds', 'assets', 'overlay_toolchain'}
|
||||
|
||||
# A release packager that touches the OVERLAY CACHE must route through the
|
||||
# framework's shared staging surface rather than reimplementing it. The
|
||||
@@ -128,6 +128,17 @@ TAG_CONSUMER_RE = re.compile(
|
||||
SHARED_SURFACE_RE = re.compile(r'release_overlay_stage|release_stage\.py')
|
||||
|
||||
|
||||
def check_consumer_detection():
|
||||
# Config validation is not cache staging. Retain positive controls so the
|
||||
# narrower heuristic cannot silently exempt real cache consumers.
|
||||
assert not TAG_CONSUMER_RE.search('overlay_cache = true')
|
||||
assert not TAG_CONSUMER_RE.search('${SHIP_WITHOUT_OVERLAY_CACHE_BECAUSE}')
|
||||
for example in ('${overlay_cache}', '$overlay_cache', '$Overlay_Cache',
|
||||
'overlay_cache/gcc', 'cache_tag()', '$CgTag', 'cg_tag=foo',
|
||||
'overlay_toolchain'):
|
||||
assert TAG_CONSUMER_RE.search(example), example
|
||||
|
||||
|
||||
def _is_scanned(name):
|
||||
return name.endswith(SCANNED_SUFFIXES) or name in SCANNED_NAMES
|
||||
|
||||
@@ -178,6 +189,7 @@ def framework_root():
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
check_consumer_detection()
|
||||
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
|
||||
ap.add_argument('--root', action='append', default=[],
|
||||
help='extra tree to check (repeatable). In an extra tree '
|
||||
|
||||
@@ -11,12 +11,14 @@ REWIND = (ROOT / "src/psx_rewind.c").read_text(encoding="utf-8")
|
||||
DIRTY = (ROOT / "src/dirty_ram_interp.c").read_text(encoding="utf-8")
|
||||
BOOT_STATE_H = (ROOT / "include/boot_state.h").read_text(encoding="utf-8")
|
||||
DMA = (ROOT / "src/dma.c").read_text(encoding="utf-8")
|
||||
BOOT_STATE = (ROOT / "src/boot_state.c").read_text(encoding="utf-8")
|
||||
|
||||
# The per-word DMA2 cursor and XA DATA_END pending bit grow the snapshot wire.
|
||||
# Lock the format change to v7 so an old file is rejected before any state
|
||||
# section is applied.
|
||||
# Keep the v7 minimum: v8 adds enhancement memory, while vanilla writers still
|
||||
# emit v7. Older files must be rejected before any live state is applied.
|
||||
assert "#define DMA_GPU_LL_WIRE (4u + (10u * 4u))" in DMA
|
||||
assert "#define BOOT_STATE_VERSION 7u" in BOOT_STATE_H
|
||||
assert "#define BOOT_STATE_VERSION 8u" in BOOT_STATE_H
|
||||
assert "psx_mod_memory_snapshot_bytes() ? BOOT_STATE_VERSION : 7u" in BOOT_STATE
|
||||
assert "#define BOOT_STATE_VERSION_MIN_READ 7u" in BOOT_STATE_H
|
||||
assert "Reject\n * them at the header before any section changes the live machine." in BOOT_STATE_H
|
||||
|
||||
|
||||
@@ -33,10 +33,20 @@ sys.path.insert(0, str(TOOLKIT))
|
||||
TEMPLATE = FW / "docs" / "ci" / "templates" / "game-release.yml"
|
||||
CHECK_GENERATED = FW / "tools" / "ci" / "check_generated.sh"
|
||||
BOOT = "SLUS_012.34"
|
||||
GIT = shutil.which("git")
|
||||
BASH = shutil.which("bash")
|
||||
if os.name == "nt":
|
||||
# PATH can resolve bash to the WSL launcher and git to an MSYS shim.
|
||||
# Neither reliably accepts the native Windows fixture/script paths.
|
||||
git_root = Path(os.environ.get("ProgramFiles", "C:/Program Files")) / "Git"
|
||||
if (git_root / "cmd/git.exe").is_file():
|
||||
GIT = str(git_root / "cmd/git.exe")
|
||||
if (git_root / "bin/bash.exe").is_file():
|
||||
BASH = str(git_root / "bin/bash.exe")
|
||||
|
||||
|
||||
def _git(root, *args):
|
||||
return subprocess.run(["git", "-C", str(root), *args], capture_output=True,
|
||||
return subprocess.run([GIT, "-C", str(root), *args], capture_output=True,
|
||||
text=True, check=False)
|
||||
|
||||
|
||||
@@ -167,7 +177,7 @@ class ScaffoldContract(unittest.TestCase):
|
||||
|
||||
class CheckGeneratedScript(unittest.TestCase):
|
||||
def run_check(self, root):
|
||||
return subprocess.run(["bash", str(CHECK_GENERATED), "--root", str(root)],
|
||||
return subprocess.run([BASH, CHECK_GENERATED.as_posix(), "--root", root.as_posix()],
|
||||
capture_output=True, text=True, check=False)
|
||||
|
||||
def test_passes_on_committed_game_c(self):
|
||||
@@ -278,12 +288,12 @@ class PackagerScriptContract(unittest.TestCase):
|
||||
"tools/ci/generate_openbios.sh"):
|
||||
p = FW / rel
|
||||
self.assertTrue(os.access(p, os.X_OK), f"{rel} not executable")
|
||||
r = subprocess.run(["bash", "-n", str(p)], capture_output=True, text=True)
|
||||
r = subprocess.run([BASH, "-n", p.as_posix()], capture_output=True, text=True)
|
||||
self.assertEqual(r.returncode, 0, r.stderr)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if shutil.which("git") is None or shutil.which("bash") is None:
|
||||
if GIT is None or BASH is None:
|
||||
print("git and bash are required", file=sys.stderr)
|
||||
sys.exit(2)
|
||||
unittest.main(verbosity=1)
|
||||
|
||||
Reference in New Issue
Block a user