Skip to content

fix(build): stage linked prx runtimes next to Windows test executables - #8043

Open
plokmklo wants to merge 1 commit into
boykopovar:mainfrom
plokmklo:fix/build-stage-prx-next-to-test-exes
Open

plokmklo wants to merge 1 commit into
boykopovar:mainfrom
plokmklo:fix/build-stage-prx-next-to-test-exes

Conversation

@plokmklo

Copy link
Copy Markdown
Contributor

What

A test whose executable imports a .prx but whose add_test registration lacks the WIN32 ENVIRONMENT_MODIFICATION PATH prepend never reaches main(): the loader resolves lib*.prx imports to the patched copy in libs/ (or fails to find one), shows 0xC0000139 on a modal dialog, and ctest reports a timeout instead of a readable failure. The prepend is manual boilerplate repeated ~570 times across ~95 CMakeLists.txt files, every new registration must remember it, and Linux/macOS authors cannot see the breakage (rpath covers them).

add_test_executable now stages every linked prx runtime artifact next to the test executable via RUNTIME_OUTPUT / $<TARGET_RUNTIME_DLLS:...> on Windows (guarded to CMake >= 3.21; older CMake keeps today's behaviour). The executable's own directory outranks PATH in the Windows DLL search order, so a missing prepend stops mattering, the modal-dialog hang disappears, and hand-running a test exe needs no environment setup. Existing ENVIRONMENT_MODIFICATION prepends stay harmless.

Tested

Ubuntu 24.04: full configure + the libkernel/avplayer/relinker test targets build and pass unchanged on Linux (the branch is a no-op there by construction). The Windows behaviour is exactly the mechanism proposed in #7637 and cannot be exercised in this sandbox; CI's Windows matrix is the verification.

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: Windows: tests whose exe imports a .prx hang under ctest when the registration lacks the unpatched-dir PATH prepend #7637
  • Unblocks: none
  • GPUs tested: n/a
  • AI-assisted: yes

A test whose executable imports a .prx but whose add_test registration
lacks the WIN32 ENVIRONMENT_MODIFICATION PATH prepend never reaches
main(): the loader resolves lib*.prx imports to the patched copy in libs/
(or fails to find one), shows 0xC0000139 on a modal dialog, and ctest
reports a timeout instead of a failure. The prepend is manual boilerplate
repeated ~570 times across ~95 CMakeLists.txt files, and Linux/macOS
authors cannot see the breakage (rpath covers them).

add_test_executable now stages every linked prx runtime artifact next to
the test executable via RUNTIME_OUTPUT/$<TARGET_RUNTIME_DLLS> on Windows
(CMake >= 3.21; older CMake keeps today's behavior). The executable's own
directory outranks PATH in the Windows DLL search order, so a missing
prepend stops mattering and hand-running a test exe needs no environment
setup. Existing ENVIRONMENT_MODIFICATION prepends stay harmless.

Fixes boykopovar#7637
@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 7645 CMakeLists.txt L16

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 CMakeLists.txt
PR 1835 CMakeLists.txt
PR 3786 CMakeLists.txt
PR 5021 CMakeLists.txt
PR 7201 CMakeLists.txt
PR 8588 CMakeLists.txt
PR 9508 CMakeLists.txt
PR 11366 CMakeLists.txt

@github-actions github-actions Bot added fix error Closes an issue (Fixes #N) build labels Oct 19, 2026
@MarcZX10

Copy link
Copy Markdown
Contributor

The overlap with #7645 appears substantive: both PRs address #7637 by staging linked .prx runtimes beside Windows test executables from add_test_executable. #7645 is still open, includes a CMake 3.21 gate with the older PATH behavior retained below that version, and has reported Windows direct-run and test-suite coverage. Could you update the PR body to acknowledge this overlap and clarify the intended coordination or any behavior this PR adds beyond #7645? The current body also leaves Depends on and Unblocks unchecked, and the latest conventions check is failing.

@wachi35676

Copy link
Copy Markdown
Contributor

Verdict: defect (the change has no effect)

RUNTIME_OUTPUT is not a CMake target property, so set_target_properties(... RUNTIME_OUTPUT "$<TARGET_RUNTIME_DLLS:...>") only stores a user property that nothing reads. No DLL is staged next to the test executable. cmake --help-property-list (CMake 4.3.1) has no RUNTIME_OUTPUT entry. $<TARGET_RUNTIME_DLLS> only takes effect when a command uses it, for example a POST_BUILD copy or install(FILES ...).

Reproduced on Windows 11 Home 10.0.26300 with WinLibs GCC 15.2.0 r7, CMake 4.3.1 and Ninja. The test project has a SHARED library libdep.prx with RUNTIME_OUTPUT_DIRECTORY libs/, and an executable t in tests/ that links it. The executable gets the exact block from this PR:

variant contents of tests/ after build run tests/t.exe
this PR's RUNTIME_OUTPUT property only t.exe exit 127, libdep.prx: cannot open shared object file
plus add_custom_command(TARGET t POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_RUNTIME_DLLS:t> $<TARGET_FILE_DIR:t> COMMAND_EXPAND_LISTS) libdep.prx, t.exe exit 0

The PR says Windows behaviour "cannot be exercised in this sandbox" and leaves verification to CI. CI still passes because every existing test has the ENVIRONMENT_MODIFICATION PATH prepend, so CI cannot show whether this change works. A test registration without the prepend still behaves as described in #7637.

A POST_BUILD copy as in the second row does what the PR describes for this case. Executables that link no .prx would give it an empty list, which needs handling.

AI-assisted: yes (Claude Code); results above were run on this machine.

@oneandonlydean oneandonlydean self-assigned this Oct 20, 2026
@oneandonlydean

Copy link
Copy Markdown
Collaborator

@plokmklo thanks for picking up #7637. Unfortunately the new line doesn't stage anything: RUNTIME_OUTPUT isn't a CMake property (cmake --help-property RUNTIME_OUTPUT says so; the real ones are RUNTIME_OUTPUT_DIRECTORY and RUNTIME_OUTPUT_NAME). set_target_properties stores an unknown name as a user property without complaint, so the $<TARGET_RUNTIME_DLLS:...> value is never used.

I checked it with a small project cross-built for Windows with llvm-mingw (a SHARED dependency with a .prx suffix, plus a test executable in the same shape as add_test_executable). With this PR's line, the test directory holds only the .exe. With the copy that CMake's TARGET_RUNTIME_DLLS documentation describes, the .prx lands next to it:

add_custom_command(TARGET ${target} POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy_if_different
          $<TARGET_RUNTIME_DLLS:${target}> $<TARGET_FILE_DIR:${target}>
  COMMAND_EXPAND_LISTS)

Two things to watch:

A Windows test that passes without the PATH prepend would show the fix works.

@THEMANnt THEMANnt left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 8187dbafdaf967188067be8bd0dfe01a82894957 against author merge base e90a1d180268a1135ae70748c661a2830ce3f8ec.

Changes requested: the added target property does not stage any runtime dependencies.

CMakeLists.txt:19 — consume TARGET_RUNTIME_DLLS in a real staging command. RUNTIME_OUTPUT is not a CMake runtime-copy property. Setting this custom property to a generator expression does not add a build rule, change the executable directory or copy a DLL. There is no project consumer for this property. Windows tests therefore still lack their linked .prx dependencies despite this patch's stated purpose. Add an appropriate post-build copy/staging operation with correct list/empty-list handling and test both linked and standalone executables.

Validation: CMake 4.3.1 identifies RUNTIME_OUTPUT as an unknown property. Disposable Windows projects used each revision's exact add_test_executable helper and WindowsTestExit wrapper, with a linked .prx emitted to a different directory (paths contain spaces). Both builds succeeded but neither staged the dependency; linked executables exited 0xC0000135. Manually copying only the .prx made both executables exit0. This demonstrates a no-op proposed fix, not a newly introduced missing-DLL regression. Conventions/whitespace passed; this older registration CLI does not support --scripts. No production source was amended; the manual copy is a reviewer fixture control.

@plokmklo

plokmklo commented Oct 25, 2026 via email

Copy link
Copy Markdown
Contributor Author

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build fix error Closes an issue (Fixes #N)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows: tests whose exe imports a .prx hang under ctest when the registration lacks the unpatched-dir PATH prepend

5 participants