Skip to content

Pick the WinIO test option in the cabal file, not in configure - #628

Merged
kazu-yamamoto merged 2 commits into
haskell:masterfrom
kazu-yamamoto:configure-winio
Nov 13, 2026
Merged

kazu-yamamoto merged 2 commits into
haskell:masterfrom
kazu-yamamoto:configure-winio

Conversation

@kazu-yamamoto

@kazu-yamamoto kazu-yamamoto commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator

The -with-rtsopts=--io-manager=native that #613 added for the test suite is
never applied under plain cabal, and where the probe does run it breaks the
build instead. There are two separate bugs, one behind the other.

1. The probe does not run under plain cabal

configure.ac guards it with:

case "$host_os" in
mingw*)

but cabal runs configure under an MSYS shell on Windows, where uname -s
reports MSYS_NT-10.0-26200 and config.guess resolves the host to
x86_64-pc-msys. From a config.log of a Windows build on master:

ac_cv_host=x86_64-pc-msys
host_os='msys'
configure:4454: checking whether to use native Windows I/O manager RTS option
configure:4477: result: no, not Windows

So under plain cabal the option was never added, and the test suite has run
under MIO, in CI as much as locally.

Where the host does resolve to mingw32, as with Stack (#633) or with
--configure-option=--host=x86_64-w64-mingw32, the probe runs. It then
compiles with $HC, which is the ghc on PATH rather than the compiler
cabal was given, and with a compiler defining __IO_MANAGER_WINIO__ >= 2
first on PATH it succeeds and hits the next problem.

2. The mechanism cannot work either

Once the probe runs and succeeds, the next problem appears. configure appends

test-suite spec
  ghc-options: -with-rtsopts=--io-manager=native

to network.buildinfo, but a .buildinfo carries a HookedBuildInfo, which
Cabal accepts for the library and for named executables — not for a test-suite.
With the probe succeeding, the Windows build fails:

Warning: network.buildinfo:3:1: invalid subsection "test-suite"
Error: [Cabal-6565] Failed parsing "network.buildinfo".

The fix

Drop the machinery and say it in the cabal file, where the test-suite can be
addressed directly:

    if os(windows) && (impl(ghc > 9.12.4 && < 9.13) || impl(ghc > 9.14.1))
        ghc-options: -rtsopts -with-rtsopts=--io-manager=native

-rtsopts lets MIO be chosen at run time where WinIO is the default:
cabal test --test-options='+RTS --io-manager=posix -RTS'.

The compiler versions are spelled out rather than probed. The overlapped I/O
exception fix — the one that bumps __IO_MANAGER_WINIO__ to 2 — landed on the
ghc-9.12 and ghc-9.14 branches in April 2026, after 9.12.4 and 9.14.1 had
been released. The lower bounds are exclusive so that release candidates and
snapshots of those branches, such as 9.12.4.20260713, are covered as well.

--with-compiler is still accepted, now unused, so that cabal passing it does
not draw an unrecognized-option warning.

Testing

  • macOS: the condition does not apply; 87 examples, 0 failures.
  • Windows 11 arm64, GHC 9.12.4.20260713 (the 9.12.5 release candidate):
    • -with-rtsopts=--io-manager=native now reaches the link line (cabal -v2)
      and the string is embedded in the built spec.exe;
    • the generated network.buildinfo is back to its single valid line;
    • 82 examples, 0 failures, five runs out of five, with WinIO as the default.
    • 82 examples, 0 failures with +RTS --io-manager=posix -RTS as well.

Trade-off

Spelled-out version bounds need maintaining: a later backport, to 9.10 say,
would have to be added by hand. The probe would have tracked that automatically,
but it had no way to deliver its answer to the test-suite, which is what broke.

This is what broke network-3.2.12.0 for #633, whose tarball shipped a stale
configure from master.

Refs #602, #613, #633.

🤖 Generated with Claude Code

@kazu-yamamoto

Copy link
Copy Markdown
Collaborator Author

@Mistuke Gentle ping.

@Mistuke

Mistuke commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator

@Mistuke Gentle ping.

ah sorry was on a work trip, looking now.

@Mistuke

Mistuke commented Oct 4, 2026

Copy link
Copy Markdown
Collaborator

Yeah this is fine, The only way I can think of for doing it automatically is to put the ghc-options buildinfo chunk targetting the library. Since that gets propagated into the test. but that would enable it for users by default too when the compiler supports it.

to avoid that we cold add a cabal flag --auto-winio or something which only takes the automatic flag when this is set and we can have the testsuite use it. and when we want we can flip the default.

What do you think?

@kazu-yamamoto

Copy link
Copy Markdown
Collaborator Author

Thanks for looking, and no worries.

I tried putting ghc-options in the library's buildinfo, but it does not reach the test-suite. With a small package passing -with-rtsopts=-K3m and the test binary printing its maximum stack size (GHC 9.12.4, cabal 3.16.0.0):

  • ghc-options in the library stanza of the .cabal file: not applied to the test
  • ghc-options in the library part of a configure-generated .buildinfo: applied to the library (checked with cpp-options), but not to the test
  • ghc-options in the test-suite stanza: applied

-with-rtsopts is a link-time option, so it has to go on the test executable itself.

Rather than adding a flag, I added -rtsopts next to the automatic selection in this PR. The suite runs under WinIO on compilers which have the fix, and MIO can still be chosen at run time:

cabal test --test-options='+RTS --io-manager=posix -RTS'

On Windows 11 with GHC 9.12.4.20260713 the suite passes both ways, 82 examples, 0 failures. -rtsopts only affects the test executable, so users are not affected.

kazu-yamamoto and others added 2 commits November 13, 2026 11:00
configure.ac probed for __IO_MANAGER_WINIO__ >= 2 and, when it found it,
appended a test-suite stanza to network.buildinfo.  Neither half worked.

The probe sat behind `case "$host_os" in mingw*)`, but cabal runs
configure under an MSYS shell on Windows, where config.guess resolves the
host to *-pc-msys.  The case never matched, so even on Windows config.log
said

    checking whether to use native Windows I/O manager RTS option... no, not Windows

and under plain cabal the option was never added: the test suite has run
under MIO, in CI as much as locally.  Where the host does resolve to
mingw32, as with Stack (haskell#633), the probe runs, compiling with the ghc on
PATH rather than the compiler cabal was given.

Once the probe succeeds, the second half shows.  A .buildinfo carries
a HookedBuildInfo, which Cabal accepts for the library and for named
executables but not for a test-suite, so once the probe started
succeeding the Windows build failed with

    network.buildinfo:3:1: invalid subsection "test-suite"

Drop the machinery and say it in the cabal file, where the test-suite can
be addressed directly.  The compiler versions are spelled out rather than
probed: the overlapped I/O exception fix landed on the 9.12 and 9.14
branches in April 2026, after 9.12.4 and 9.14.1 had been released.  The
lower bounds are exclusive so that release candidates and snapshots of
those branches are covered as well.

--with-compiler is still accepted, unused, so that cabal passing it does
not draw an unrecognized-option warning.

Verified on Windows 11 with 9.12.4.20260713: the option now reaches the
link line, is embedded in the test binary, and the suite passes five runs
out of five with WinIO as the default.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
So that +RTS --io-manager=posix can bring MIO back at run time.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@kazu-yamamoto
kazu-yamamoto merged commit 771a0bd into haskell:master Nov 13, 2026
11 checks passed
kazu-yamamoto added a commit that referenced this pull request Nov 13, 2026
@kazu-yamamoto
kazu-yamamoto deleted the configure-winio branch November 13, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants