Skip to content

feat(windows): support MSYS2 GCC runtime builds - #8087

Merged
oneandonlydean merged 3 commits into
boykopovar:mainfrom
harry-z-kang:codex/windows-seh-runtime
Oct 22, 2026
Merged

oneandonlydean merged 3 commits into
boykopovar:mainfrom
harry-z-kang:codex/windows-seh-runtime

Conversation

@harry-z-kang

@harry-z-kang harry-z-kang commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

What

MSYS2 GCC could not build the full Windows runtime with its native SEH exception model. Support System V ABI SEH frames alongside the existing WinLibs DWARF path, identify project GCC personalities, and preserve guest/host cleanup, typed catches, rethrow and register restoration. Includes the required pthread startup, makecontext frame, thread-description lookup and ATRAC9 fixture fixes.

MSYS2 qualification runs in the separate Windows MSYS2 workflow nightly at 08:23 UTC and through workflow_dispatch. The regular WinLibs Build workflow is unchanged. Full builds with testing enabled retain the configure-time error for missing runtime DLLs; MSYS2 supplies all three beside the compiler. Relinker-only static-runtime support from merged #8067 is preserved.

Standalone Scoop GCC 15.2 remains unsupported for full runtime builds: disabling SEH selects SjLj, and its SEH backend cannot compile System V catch handlers. MSYS2 UCRT64 GCC 16.2.0-6 carries the compiler fix. Unmarked native handlers and SjLj remain in libc debt.

The SHA-1 relinker execution test now reports its instruction bytes, sample, RAX, RCX and RFLAGS when preservation fails. Its register, flag and result checks are unchanged.

Windows TLS coverage fixtures now use the existing bounded cleanup retry helper when a finished executable is temporarily locked. Fixture assertions and the 30-second test timeout are unchanged.

Tested

  • Fixed the Windows CI cleanup failure in tls_function_coverage_displacement_r8: all fixture checks completed, but TemporaryDirectory failed to remove an executable with WinError 32. A deterministic local reproduction held a real Windows file handle after execution: the original cleanup failed after 12 successful fixture runs, and the fix waited for release and removed the directory. An injected TLS assertion failure still propagated after cleanup.
  • WinLibs GCC 15.2, Python 3.15.0, Windows: rebuilt the relinker and passed all 33 TLS coverage groups three times with ctest --test-dir b/rw --label-regex '^tls_function_coverage$' --repeat until-fail:3 --parallel 4 --output-on-failure --timeout 30 (99 executions, 19.61 s). Conventions and whitespace checks passed.
  • Latest rebase onto 6ef5a1c4c, head 4e9854ea2: both commit patches are unchanged. Rebuilt the focused MSYS2 runtime targets; all 36 tests passed (12.31 s). Conventions, whitespace and Actionlint passed.
  • After rebasing onto cecb540a6, the affected runtime targets built successfully; all 36 focused MSYS2 tests and all seven WinLibs GCC 15.2 mutex/condition-variable tests passed, including explicit adaptive-mutex initialization.
  • CI initially failed only amd64_only_converter under macOS 26 Rosetta with SHA-1 stub changed a general register or RFLAGS. The relinker implementation is unchanged from main. The failure did not reproduce in 20 unmodified Linux/WSL runs or 100 native Intel macOS runs. The diagnostic change passed another 20 Linux/WSL runs and the upstream Rosetta job. The underlying cause remains unconfirmed; no preservation assertion was removed or relaxed.
  • Previous base e41fb9db5, Windows NT 26300: rebuilt the focused MSYS2 targets; all 29 unwind, exception, module-info, timer, context and ATRAC9 tests passed (10.43 s).
  • Missing-runtime regression: full BUILD_TESTING=ON configuration with standalone Scoop GCC fails immediately with Cannot locate MinGW runtime: libgcc_s_seh-1.dll; relinker-only configuration with that same compiler succeeds. MSYS2 configuration succeeds with its adjacent runtime DLLs.
  • Actionlint 1.7.12, all 11 CI-gating unit tests, conventions and whitespace checks passed. The nightly cache-key shell step was executed successfully locally. The new scheduled workflow has not run on GitHub yet.
  • Earlier full MSYS2 build and libs build passed on base 252cbc29b; CTest reported 1,670 passed, 19 skipped, 1 failed out of 1,690. The failure was agc_driver_pass_input_hazard: a pass writing indices read by an open pass took no barrier. The same assertion reproduces with WinLibs GCC 15.2 r7 on the same PR code and machine; this comparison uses the DWARF and SEH paths of the branch. agc_driver_storage_file_write and agc_driver_pm4 passed under both toolchains with validation enabled.
  • That historical run used NVIDIA GeForce RTX 5080, driver 617.42, Windows NT 26300, ANYPS5_REQUIRE_VULKAN=1, ANYPS5_NO_SHADER_CACHE=1 and VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation; verbose logs confirmed the layer loaded. agc_sparse_run_import_copied passes but logs VUID-vkCmdCopyBuffer-srcBuffer-00118 under both toolchains. No GPU implementation files change.
  • Historical coverage gaps include the 19 skips (120 Hz display mode unavailable and Windows long paths disabled account for two strict-skip-checker warnings) and the existing shader_cache_runtime_sources fixture taking 43.17 s in the full run / 36.10 s alone. No existing timeout was increased. WinLibs 15.2 r7 previously passed 32 focused runtime tests and eight final compatibility checks. Full Linux runtime qualification has not run locally.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • Fixes: none
  • Unblocks: none
  • GPUs tested: n/a (runtime/build changes; historical qualification on NVIDIA GeForce RTX 5080, driver 617.42, Windows NT 26300)
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
PR 6819 core/libs/prx/libc/src/exception/Unwind.cpp L259-260, L419-420
docs/dev/debt/libc.md L103-104
PR 8619 docs/dev/BUILD.md L33-34
PR 8658 core/libs/tests/GuestModuleInfo.cpp L58-59
PR 9471 docs/dev/BUILD.md L15
PR 9585 core/libs/prx/libc/src/exception/Unwind.cpp L107-108, L110-111, L113-115

Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.

Pull request Shared files not compared
PR 674 docs/dev/BUILD.md
PR 1835 docs/dev/BUILD.md
PR 3965 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 4627 core/libs/prx/libc/CMakeLists.txt
PR 5021 core/libs/CMakeLists.txt
core/libs/prx/libc/CMakeLists.txt
docs/dev/BUILD.md
docs/dev/debt/libc.md
PR 5303 docs/dev/debt/libc.md
PR 6044 core/libs/CMakeLists.txt
core/libs/prx/libSceAjm.native/CMakeLists.txt
core/libs/prx/libc/CMakeLists.txt
core/libs/tests/GuestMessageDestructorAbi.S
core/libs/tests/GuestMessageDestructorAbi.cpp
core/libs/tests/GuestModuleInfo.cpp
PR 6469 docs/dev/debt/libc.md
PR 6879 docs/dev/BUILD.md
docs/dev/debt/libc.md
PR 7081 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 7201 core/libs/CMakeLists.txt
core/libs/prx/libc/CMakeLists.txt
core/libs/prx/libc/src/exception/Unwind.cpp
core/libs/tests/GuestModuleInfo.cpp
PR 7275 core/libs/CMakeLists.txt
PR 7648 docs/dev/debt/libc.md
PR 7715 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 7918 core/relinker/codegen/tests/Amd64OnlyConverterTests.cpp
PR 8042 core/relinker/codegen/tests/Amd64OnlyConverterTests.cpp
PR 8150 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 8285 core/libs/CMakeLists.txt
PR 8650 core/libs/CMakeLists.txt
PR 8965 core/libs/prx/libc/CMakeLists.txt
docs/dev/debt/libc.md
PR 9224 core/libs/CMakeLists.txt
PR 9408 docs/dev/debt/libc.md

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks, this is careful work. Two questions while this waits for a maintainer decision on the extra Windows CI lane:

  1. Your MSYS2 run reports 1,670 passed, 19 skipped, 1 failed out of 1,690. Which test failed, and does it also fail with WinLibs?
  2. This PR changes fix(build): allow static MinGW runtimes in relinker-only tests #8067's if(ANYPS5_RELINKER_ONLY) continue() into an unconditional continue() in the root CMakeLists.txt. A full build then configures without a missing runtime DLL and fails later at test start (0xc0000135), while fix(build): allow static MinGW runtimes in relinker-only tests #8067 says "Full builds still require all three DLLs". Could you keep the FATAL_ERROR for full builds, or explain why the MSYS2 path needs it dropped? MSYS2 ships the DLLs in ucrt64/bin next to the compiler.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks for this. We'd like to take MSYS2 GCC support, with one change to how its CI runs and two small things to sort out first.

  1. CI trigger. A second full Windows build on every push to main roughly doubles our Windows CI time. Could you move the msys2 build out of the per-push matrix into a scheduled nightly run, with a workflow_dispatch trigger so it can also be started by hand? The WinLibs row stays as it is.
  2. The one failing test. Your MSYS2 run reported 1,670 passed, 19 skipped and 1 failed out of 1,690. Which test failed, and does it also fail on WinLibs?
  3. Missing runtime DLLs in full builds. This PR makes the continue() from fix(build): allow static MinGW runtimes in relinker-only tests #8067 unconditional in the root CMakeLists.txt. So a full build with a runtime DLL missing no longer fails at configure time: it fails later, when a test starts, with 0xc0000135. fix(build): allow static MinGW runtimes in relinker-only tests #8067 kept "full builds still require all three DLLs". Could you keep the FATAL_ERROR for full builds? If MSYS2 needs it dropped, could you explain why?

#8067 is merged now, so a rebase onto main should leave just your own commit.

@harry-z-kang
harry-z-kang force-pushed the codex/windows-seh-runtime branch from 8909edf to 23e4047 Compare October 20, 2026 10:33
@harry-z-kang

Copy link
Copy Markdown
Contributor Author

Addressed in commit 23e4047:

  1. CI: MSYS2 now has a separate windows-msys2.yml workflow, scheduled daily at 08:23 UTC and runnable through workflow_dispatch. The regular WinLibs .github/workflows/build.yml matches main, so this adds no MSYS2 build to push or PR runs. The nightly job builds the runtime/libraries, runs the registered suite, checks skips, reports slow tests and uploads its test logs.
  2. Failing test: the reported failure was agc_driver_pass_input_hazard, with a pass writing the indices an open pass reads in place took no barrier. It reproduces with both MSYS2 UCRT64 GCC 16.2.0-6 and WinLibs GCC 15.2 r7 on the same PR code and RTX 5080 / driver 617.42 / Windows NT 26300, with Vulkan validation enabled. The 1,690-test figures refer to the historical run based on 252cbc29b; the matched compiler comparison uses this branch's SEH and DWARF paths. The PR description now names the failure directly.
  3. Runtime DLLs: MSYS2 does not need the guard removed. Restored main's FATAL_ERROR for full builds with testing enabled, while preserving fix(build): allow static MinGW runtimes in relinker-only tests #8067's relinker-only exception. Verified the missing-DLL full build fails during CMake configuration and the same static-runtime compiler still configures in relinker-only mode. MSYS2 configuration and all 29 focused runtime checks pass.

Rebased onto main e41fb9db5; #8067 is now part of main, the branch contains only this PR's single commit, and Depends on is none. Actionlint, the 11 CI-gating unit tests, conventions and whitespace checks pass. The new scheduled workflow was linted and its cache-key shell step was exercised locally; its first hosted run is still pending.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 21, 2026
@Felipebmaitan Felipebmaitan mentioned this pull request Oct 21, 2026
12 tasks done
@harry-z-kang
harry-z-kang force-pushed the codex/windows-seh-runtime branch from 23e4047 to 2734ac7 Compare October 21, 2026 16:42
@github-actions github-actions Bot added relinker and removed needs rebase Conflicts with main, rebase needed labels Oct 21, 2026
@harry-z-kang
harry-z-kang force-pushed the codex/windows-seh-runtime branch from a97e45b to 4e9854e Compare October 22, 2026 03:31
@oneandonlydean
oneandonlydean merged commit c61d20f into boykopovar:main Oct 22, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants