Stabilize the real-Windows (MSYS2) CI job: green build + gating - #19
Merged
Conversation
…-path preprocessor
The native-Windows parity job (MSYS2 MINGW32, real cmd.exe/Winsock/ConPTY) died
at the RC step: its windres (binutils 2.46) fails to spawn a bare-named
preprocessor ('CreateProcess failed: The system cannot find the file
specified'). Rather than skip the manifest there (which would build a different
binary than ships and weaken the parity), drive windres with the FULL resolved
path to the C compiler CMake already verified - which spawns reliably on every
host. The RT_MANIFEST now bakes into the SAME binary on the Ubuntu cross build
and the native-Windows build alike. The .rc is self-contained (expands only its
own two #defines, no system include), so any cpp suffices; this only makes the
spawn reliable. Verified locally: windres uses the full path and wrestool shows
one type-24 manifest. Supersedes the toolchain's bare-name Windows-only override.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s no windres preprocessor
The MSYS2 native-Windows parity job's windres (binutils 2.46) cannot spawn a
preprocessor to compile the .rc - even a full-path .exe gives 'CreateProcess
failed: The system cannot find the file specified'. Ship the manifest as a
prebuilt, byte-deterministic src/mcp-w32s.res instead: compiling .res -> coff
needs NO preprocessor, so it builds identically on the Ubuntu cross host and the
native-Windows runner - the SAME manifest in every binary (no runner-specific
divergence). MSVC keeps rc.exe on the .rc. A new Ubuntu CI step regenerates the
.res from the .rc + .manifest (where the cross preprocessor works) and byte-
diffs it, so the committed artifact can never drift from source. Verified
locally: res->coff runs without --preprocessor, the exe carries one RT_MANIFEST,
imports stay {kernel32,user32}.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The res->coff custom command runs via cmd.exe on the MSYS2 native runner, where
a bare 'i686-w64-mingw32-windres' is 'not recognized' - CMake resolves the RC
compiler internally for its own RC rule, but ${CMAKE_RC_COMPILER} stays the bare
toolchain name. find_program (run at configure time in the MSYS2 PATH) yields the
full path cmd.exe can spawn. Verified locally: MCP_WINDRES resolves to the full
path, the custom command uses it, the manifest is present.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ips unprefixed binutils) The native runner got past the build (prebuilt .res) but the import check died with 'i686-w64-mingw32-objdump: command not found' (exit 127): MSYS2 MINGW32 provides binutils UNPREFIXED (objdump/windres/nm), not under the cross prefix that exists on the Ubuntu host. Use plain objdump on the native job (it is the i686 one in /mingw32/bin). The Ubuntu job keeps the cross-prefixed name. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…subject) shell_builtin_is_shell + shell_dir_routing assumed a bare 'dir' has no .exe on PATH and spawn-fails. That is false on runners that ship a coreutils dir.exe (MSYS2 /usr/bin on the native-Windows CI), where the device CORRECTLY resolves and classifies dir as a real PE - so the assertions failed there even though the device behaved right. Switch the subject to 'ver', a cmd built-in with no .exe equivalent on any host, so the 'unresolvable bare name -> shell built-in' path is exercised deterministically across the dev host, Wine, and real Windows. test_binfmt verified green; test_exec_ops is spawn-based (CI-verified, not the interop-down local wine).
…is green The native-Windows parity job builds and runs the full exec/Winsock/ConPTY suite green on real Windows (manifest from a prebuilt .res, unprefixed objdump, host-robust shell-builtin subject). Drop continue-on-error so its result counts toward the run conclusion. (A hard merge gate also needs it added to the branch-protection required checks.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stabilize the real-Windows CI job (#38)
The
windows-nativeparity job (MSYS2 MINGW32 → builds the i386 PEs natively and runs them on a real Windows runner, so exec/Winsock/ConPTY exercise real cmd.exe/Winsock/ConPTY rather than Wine) had been permanently red and informational. It died at the RC/manifest step. This makes it build and pass the full suite green, then flips it to gating.Each fix was diagnosed from the actual CI error, not a guess:
.res(no windres preprocessor). MSYS2's windres (binutils 2.46) cannot spawn a preprocessor to compile the.rc— even a full-path.exegivesCreateProcess failed: The system cannot find the file specified. Ship the manifest as a prebuilt, byte-deterministicsrc/mcp-w32s.res; compiling.res → coffneeds no preprocessor, so the same manifest bakes into every binary on every runner. A new Ubuntu CI step regenerates the.resfrom.rc + .manifestand byte-diffs it, so the committed artifact can't drift. (MSVC keepsrc.exeon the.rc.)find_program. The.res→coffcustom command runs via cmd.exe, where the barei686-w64-mingw32-windresis "not recognized";find_program(at configure, in the MSYS2 PATH) resolves the full path cmd.exe can spawn.objdump. MSYS2 MINGW32 ships binutils unprefixed; the native job's import check used the cross-prefixed name (command not found).shell_builtin_is_shell/shell_dir_routingassumed baredirhas no.exeand spawn-fails — false where coreutils shipsdir.exe(MSYS2/usr/bin), so the device correctly classified it as a real PE. Switched the subject tover(a cmd built-in with no.exeon any host), so the "unresolvable bare name → shell built-in" path is exercised deterministically across the dev host, Wine, and real Windows.Result: the native job builds, the binary is import-clean (
{kernel32, user32}only — the native toolchain also hits the Win32s floor), and the full exec/Winsock/ConPTY suite passes on real Windows.continue-on-errordropped so its result counts (add it to branch-protection required checks to make it a hard merge gate). No device-behaviour or spec change — pure CI/build/test infra; the Ubuntu suite stays green.🤖 Generated with Claude Code