From f395ea0515c39377c4ca702eebf994a2ddb47c66 Mon Sep 17 00:00:00 2001 From: Moritz Angermann Date: Sat, 17 Oct 2026 16:38:19 +0900 Subject: [PATCH] fix: preserve haskell.nix UCRT pthread flags --- scripts/nix/README.md | 2 ++ scripts/nix/check-mingw-stdio-scope.nix | 19 ++++++++++++++++--- scripts/nix/mingw-stdio-overlay.nix | 8 ++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/scripts/nix/README.md b/scripts/nix/README.md index b8df8c5e99..ba7121113c 100644 --- a/scripts/nix/README.md +++ b/scripts/nix/README.md @@ -279,6 +279,8 @@ The Windows CRT overlay backports upstream MinGW commit `e7e21db45eaa` to the verified 13.0.0/14.0.0 sources. It fixes ISO `swprintf` rejecting strings that exactly fit with their terminator; the regression also requires a negative return for a too-small buffer and intact outside-buffer sentinels. +The overlay preserves haskell.nix's existing UCRT pthread flags when rebuilding +the Windows scope; the current SimpleX Windows targets use MSVCRT. It requires real file opens, descriptor/stat information and fixture bytes for short, long and archive-shaped paths, including absolute and extended variants. Helper results and a separate direct Win32/CRT replay remain diagnostic output. diff --git a/scripts/nix/check-mingw-stdio-scope.nix b/scripts/nix/check-mingw-stdio-scope.nix index e3bc90dead..0a98c47eca 100644 --- a/scripts/nix/check-mingw-stdio-scope.nix +++ b/scripts/nix/check-mingw-stdio-scope.nix @@ -3,7 +3,7 @@ let overlay = import ./mingw-stdio-overlay.nix; existing = ./ghc914-rts-windows-dll-search-path.patch; fix = ./mingw-w64-swprintf-exact-fit.patch; - apply = { windows ? true, version ? "14.0.0", patches ? [ existing ] }: + apply = { windows ? true, libc ? "msvcrt", version ? "14.0.0", patches ? [ existing ] }: let runtime = { inherit version patches; @@ -12,14 +12,20 @@ let }; scope = { mingw_w64 = runtime; + mingw_w64_pthreads.CPPFLAGS = ""; unchanged = "other-Windows-packages"; overrideScope = f: scope // f scope scope; }; + # haskell.nix adds UCRT's flags with a shallow `windows // { ...; }`. + # overrideScope still closes over the original scope and drops that field. + customized = scope // (if libc == "ucrt" then { + mingw_w64_pthreads = { CPPFLAGS = "-D_UCRT"; marker = "existing-UCRT-customization"; }; + } else {}); prev = { lib.optionalAttrs = condition: attrs: if condition then attrs else {}; - stdenv.hostPlatform.isWindows = windows; + stdenv.hostPlatform = { isWindows = windows; inherit libc; }; # Non-Windows evaluation must not force any Windows dependencies. - windows = if windows then scope else throw "Windows scope was forced"; + windows = if windows then customized else throw "Windows scope was forced"; }; in overlay prev prev; selected = apply {}; @@ -27,6 +33,12 @@ in assert selected.windows.mingw_w64.patches == [ existing fix ]; assert selected.windows.mingw_w64.marker == "existing-runtime-attributes"; assert selected.windows.unchanged == "other-Windows-packages"; +assert selected.windows.mingw_w64_pthreads.CPPFLAGS == ""; +assert (apply { libc = "ucrt"; }).windows.mingw_w64_pthreads == { + CPPFLAGS = "-D_UCRT"; + marker = "existing-UCRT-customization"; +}; +assert (apply { libc = "ucrt"; }).windows.mingw_w64.patches == [ existing fix ]; assert (apply { patches = []; }).windows.mingw_w64.patches == [ fix ]; assert (apply { version = "13.0.0"; }).windows.mingw_w64.patches == [ existing fix ]; assert (apply { version = "12.0.0"; }).windows.mingw_w64.patches == [ existing ]; @@ -35,6 +47,7 @@ assert apply { windows = false; } == {}; { verifiedMingw13And14RuntimePatched = true; existingPatchOrderAndWindowsScopePreserved = true; + shallowUcrtPthreadCustomizationPreserved = true; unrelatedPlatformsAndVersionsUnchanged = true; nonWindowsDependenciesRemainLazy = true; } diff --git a/scripts/nix/mingw-stdio-overlay.nix b/scripts/nix/mingw-stdio-overlay.nix index c9a86bf865..417a0c2898 100644 --- a/scripts/nix/mingw-stdio-overlay.nix +++ b/scripts/nix/mingw-stdio-overlay.nix @@ -2,12 +2,16 @@ final: prev: prev.lib.optionalAttrs prev.stdenv.hostPlatform.isWindows { # The CRT owns libmingwex.a. Patching headers or GHC's callers alone leaves # ISO swprintf rejecting successful exact-fit strings at runtime. - windows = prev.windows.overrideScope (_self: super: { + windows = (prev.windows.overrideScope (_self: super: { # Inspect the version only after constructing the Windows scope: forcing # the CRT in the outer condition recurses through the cross libc bootstrap. mingw_w64 = super.mingw_w64.overrideAttrs (old: prev.lib.optionalAttrs (builtins.elem old.version [ "13.0.0" "14.0.0" ]) { patches = (old.patches or []) ++ [ ./mingw-w64-swprintf-exact-fit.patch ]; }); - }); + })) // prev.lib.optionalAttrs (prev.stdenv.hostPlatform.libc == "ucrt") { + # haskell.nix adds this alias with a shallow scope extension. overrideScope + # rebuilds the original scope, so retain its existing UCRT CPPFLAGS. + inherit (prev.windows) mingw_w64_pthreads; + }; }