Home /
Input Output /
haskell.nix
Apr 27, 12-1 AM (1)
Apr 27, 1-2 AM (0)
Apr 27, 2-3 AM (0)
Apr 27, 3-4 AM (0)
Apr 27, 4-5 AM (0)
Apr 27, 5-6 AM (0)
Apr 27, 6-7 AM (0)
Apr 27, 7-8 AM (0)
Apr 27, 8-9 AM (0)
Apr 27, 9-10 AM (0)
Apr 27, 10-11 AM (0)
Apr 27, 11-12 PM (0)
Apr 27, 12-1 PM (0)
Apr 27, 1-2 PM (0)
Apr 27, 2-3 PM (0)
Apr 27, 3-4 PM (0)
Apr 27, 4-5 PM (0)
Apr 27, 5-6 PM (0)
Apr 27, 6-7 PM (0)
Apr 27, 7-8 PM (0)
Apr 27, 8-9 PM (0)
Apr 27, 9-10 PM (1)
Apr 27, 10-11 PM (0)
Apr 27, 11-12 AM (0)
Apr 28, 12-1 AM (2)
Apr 28, 1-2 AM (0)
Apr 28, 2-3 AM (2)
Apr 28, 3-4 AM (0)
Apr 28, 4-5 AM (0)
Apr 28, 5-6 AM (0)
Apr 28, 6-7 AM (0)
Apr 28, 7-8 AM (5)
Apr 28, 8-9 AM (0)
Apr 28, 9-10 AM (0)
Apr 28, 10-11 AM (0)
Apr 28, 11-12 PM (1)
Apr 28, 12-1 PM (0)
Apr 28, 1-2 PM (0)
Apr 28, 2-3 PM (0)
Apr 28, 3-4 PM (0)
Apr 28, 4-5 PM (0)
Apr 28, 5-6 PM (0)
Apr 28, 6-7 PM (0)
Apr 28, 7-8 PM (0)
Apr 28, 8-9 PM (0)
Apr 28, 9-10 PM (0)
Apr 28, 10-11 PM (0)
Apr 28, 11-12 AM (1)
Apr 29, 12-1 AM (3)
Apr 29, 1-2 AM (0)
Apr 29, 2-3 AM (0)
Apr 29, 3-4 AM (0)
Apr 29, 4-5 AM (0)
Apr 29, 5-6 AM (0)
Apr 29, 6-7 AM (0)
Apr 29, 7-8 AM (0)
Apr 29, 8-9 AM (0)
Apr 29, 9-10 AM (0)
Apr 29, 10-11 AM (0)
Apr 29, 11-12 PM (0)
Apr 29, 12-1 PM (1)
Apr 29, 1-2 PM (0)
Apr 29, 2-3 PM (0)
Apr 29, 3-4 PM (0)
Apr 29, 4-5 PM (0)
Apr 29, 5-6 PM (0)
Apr 29, 6-7 PM (0)
Apr 29, 7-8 PM (0)
Apr 29, 8-9 PM (0)
Apr 29, 9-10 PM (0)
Apr 29, 10-11 PM (0)
Apr 29, 11-12 AM (0)
Apr 30, 12-1 AM (1)
Apr 30, 1-2 AM (0)
Apr 30, 2-3 AM (0)
Apr 30, 3-4 AM (0)
Apr 30, 4-5 AM (0)
Apr 30, 5-6 AM (0)
Apr 30, 6-7 AM (0)
Apr 30, 7-8 AM (0)
Apr 30, 8-9 AM (0)
Apr 30, 9-10 AM (0)
Apr 30, 10-11 AM (0)
Apr 30, 11-12 PM (0)
Apr 30, 12-1 PM (0)
Apr 30, 1-2 PM (0)
Apr 30, 2-3 PM (0)
Apr 30, 3-4 PM (0)
Apr 30, 4-5 PM (0)
Apr 30, 5-6 PM (0)
Apr 30, 6-7 PM (0)
Apr 30, 7-8 PM (0)
Apr 30, 8-9 PM (0)
Apr 30, 9-10 PM (0)
Apr 30, 10-11 PM (0)
Apr 30, 11-12 AM (0)
May 01, 12-1 AM (1)
May 01, 1-2 AM (0)
May 01, 2-3 AM (0)
May 01, 3-4 AM (0)
May 01, 4-5 AM (0)
May 01, 5-6 AM (0)
May 01, 6-7 AM (0)
May 01, 7-8 AM (0)
May 01, 8-9 AM (0)
May 01, 9-10 AM (0)
May 01, 10-11 AM (0)
May 01, 11-12 PM (0)
May 01, 12-1 PM (0)
May 01, 1-2 PM (0)
May 01, 2-3 PM (0)
May 01, 3-4 PM (0)
May 01, 4-5 PM (0)
May 01, 5-6 PM (0)
May 01, 6-7 PM (0)
May 01, 7-8 PM (1)
May 01, 8-9 PM (0)
May 01, 9-10 PM (0)
May 01, 10-11 PM (0)
May 01, 11-12 AM (0)
May 02, 12-1 AM (1)
May 02, 1-2 AM (0)
May 02, 2-3 AM (0)
May 02, 3-4 AM (0)
May 02, 4-5 AM (0)
May 02, 5-6 AM (0)
May 02, 6-7 AM (0)
May 02, 7-8 AM (0)
May 02, 8-9 AM (0)
May 02, 9-10 AM (0)
May 02, 10-11 AM (0)
May 02, 11-12 PM (0)
May 02, 12-1 PM (0)
May 02, 1-2 PM (0)
May 02, 2-3 PM (0)
May 02, 3-4 PM (0)
May 02, 4-5 PM (0)
May 02, 5-6 PM (0)
May 02, 6-7 PM (0)
May 02, 7-8 PM (0)
May 02, 8-9 PM (0)
May 02, 9-10 PM (0)
May 02, 10-11 PM (0)
May 02, 11-12 AM (0)
May 03, 12-1 AM (1)
May 03, 1-2 AM (0)
May 03, 2-3 AM (0)
May 03, 3-4 AM (0)
May 03, 4-5 AM (0)
May 03, 5-6 AM (0)
May 03, 6-7 AM (0)
May 03, 7-8 AM (1)
May 03, 8-9 AM (0)
May 03, 9-10 AM (0)
May 03, 10-11 AM (0)
May 03, 11-12 PM (0)
May 03, 12-1 PM (0)
May 03, 1-2 PM (0)
May 03, 2-3 PM (0)
May 03, 3-4 PM (0)
May 03, 4-5 PM (0)
May 03, 5-6 PM (0)
May 03, 6-7 PM (0)
May 03, 7-8 PM (0)
May 03, 8-9 PM (0)
May 03, 9-10 PM (0)
May 03, 10-11 PM (1)
May 03, 11-12 AM (0)
May 04, 12-1 AM (1)
24 commits this week
Apr 27, 2026
-
May 04, 2026
update nix-tools-static.nix
static-nix-tools: patch cabal-install to pin unit-id OS via env var
`hashedInstalledPackageId` selects between Long / Short / VeryShort unit-id formats based on `buildOS` — the OS where cabal-install is currently executing. For haskell.nix that's the *eval* platform of the plan-nix derivation, not the *build* platform where cabal will later actually do the compile. When the two differ (e.g. evaluating on Darwin while building x86_64-linux derivations), plan-nix unit-ids diverge from the unit-ids slice cabal v2-build computes — every slice then tries to rebuild every dep from source. Add a `CABAL_INSTALLED_PACKAGE_ID_OS` env var that overrides `buildOS` for unit-id format selection. haskell.nix sets it to the build platform's OS when invoking `make-install-plan`.
Support all the env vars used by the nixpkgs `ghc-paths` patch
`NIX_GHC` is needed for `doctest`
Add WASM tutorial to docs
Documents how to build WebAssembly packages with haskell.nix using a Nix flake, covering the flake setup, build commands, test execution, dev shell usage, the overlay stack, and known limitations. docs/wasm: macOS (aarch64-darwin) is also a supported build host Fixes incorrect claim that WASM cross-compilation only works on Linux. aarch64-darwin is known to work; x86_64-darwin is untested. (cherry picked from commit c314d1654fffd7a83d379366f9685a43afa2c447)
Optimize evaluation performance: uniqueWithName, checkUnique, planned.nix, load-cabal-plan (#2495)
* Optimize uniqueWithName and checkUnique for eval performance
Profiling cardano-node evaluation with per-function allocation attribution
revealed that uniqueWithName/checkUnique consume 36% of inclusive eval time
(2.4s out of 6.7s) and ~1 GiB of memory.
Three changes:
1. Replace uniqueWithName implementation: the old approach used
`groupBy` + `lib.unique` per group. `lib.unique` is O(n²) via
linear `elem` scan with structural equality. The new implementation
uses `builtins.listToAttrs` which runs entirely in C++ at O(n log n).
First occurrence wins (same semantics for derivation dedup by name).
2. Fix checkUnique: the old implementation called `uniqueWithName` just
to compare list lengths, then discarded the result. If no duplicates
existed (the common case), it returned the original list and all the
dedup work was wasted. The error path then called `groupBy` a third
time. The new implementation uses a single `groupBy` to find groups
with length > 1, avoiding redundant work.
3. Fuse four nested `map` passes in make-config-files.nix:
The Nix evaluator does not perform list fusion -- each `map` allocates
a full intermediate list. The old code chained dependToLib, profiled
variant, DWARF variant, and chooseDrv as four separate `map` calls.
Fused into a single pass to eliminate three intermediate allocations
per component across hundreds of packages.
* Enable use-package-keys by default for faster module evaluation
When use-package-keys is false (the old default), the `packages` option
is declared as `attrsOf package` -- an open-ended attribute set where the
NixOS module system must handle arbitrary keys via recursive submodule
merging.
When true, it uses `genAttrs config.package-keys` to declare a closed
set of known package names. The module system knows exactly which
packages exist upfront and can skip the open-ended merge machinery.
The package-keys are computed from the cabal plan (via addPackageKeys),
so the set is always correct for the resolved plan. Users who inject
unplanned packages via modules should add names to package-keys
explicitly.
* Optimize load-cabal-plan.nix: single-pass plan partitioning
The install-plan was being filtered 3+ times with separate concatMap
passes (pre-existing, configured/global, configured/local), each
iterating over all ~600 packages. Replace with a single builtins.groupBy
call that categorizes entries in one C++ pass at O(n log k).
The consumers (pkgs, extras) now iterate only over their relevant
partition instead of the entire install-plan with inline filters.
This eliminates redundant type comparisons and optional allocations.
Also restructured pre-existing-depends for clarity while keeping
the lazy memoization that avoids recomputing transitive lookups.
* Simplify planned.nix: remove mkOverride and avoid getComponents
Two optimizations to planned.nix:
1. Replace `lib.mkOverride 900 true` with plain `true` for the
`planned` flag. The plan is definitive -- no other module in
the loadCabalPlan code path sets `planned`, so the override
priority machinery is wasted work. Avoids allocating ~3000
override wrapper attrsets through the module system.
2. Extract component keys directly from plan.json's `p.components`
structure using the prefix mapping (exe:→exes, test:→tests, etc.)
instead of calling the full `getComponents` function. The old
code invoked dependency resolution (lookupDependencies,
lookupPreExisting) against an empty hsPkgs -- all that work was
thrown away since planned.nix only needs component keys to set
`planned = true` on them.
* Fix uniqueWithName to preserve structurally distinct items
The listToAttrs rewrite in bd93f01d3 keyed every item by `x.name or
"noname"` and let listToAttrs first-wins handle collisions. That
collapses any two items sharing a key (or both lacking `.name`) to
one survivor, even when they are structurally different -- which
contradicts the function's contract. uniqueWithName must behave like
`lib.unique`; the name partition is a *speedup* (so lib.unique only
has to scan within a bucket), not a truncation.
This broke `shellFor`: builder/shell-for.nix:92-93 runs uniqueWithName
on `cfg.depends`, which lookupDependency populates with haskell.nix
package values (`hsPkgs.<unit-id>`). Those expose `.identifier.{name,
version}` but not `.name`, so every dependency landed in the noname
bucket and was reduced to one entry. The resulting GHC package DB
held only one library, surfacing as `Could not find module 'Conduit'`
in the shell-for and shell-for-setup-deps tests across all GHC
versions in eval 1223.
Restore the contract: groupBy by a synthesized key, then `lib.unique`
per bucket. Single-item buckets stay linear (lib.unique on a
1-element list is O(1)); multi-item buckets are correctly structural-
deduped instead of silently truncated. Keying:
- derivations: their `.name` already encodes name+version
- haskell.nix packages: `"${identifier.name} ${identifier.version}"`
with a space separator so package keys cannot collide with
derivation keys derived from the same words
- everything else: shared `_noname`/`_notset` bucket; correctness still
holds via the inner lib.unique, just at the slower path.
Note: shellFor has fed packages-without-`.name` into uniqueWithName
since at least 2019 (hspkg-builder.nix has never set `.name`), so this
is a long-standing reliance on the slow path's tolerance for noname
collisions, not a new condition.
* Bump stale head.hackage pin in test/cabal.project.local
* planned.nix: drop unused getComponents parameter
After d3819208f, planned.nix extracts component keys directly from
plan.json and no longer calls getComponents, but it still took it
as a parameter and the call site in lib/load-cabal-plan.nix still
passed it. Drop both.
getComponents (plural) is internal to load-cabal-plan.nix and is not
exposed publicly; the externally-visible name is the singular
project.getComponent / package.getComponent, which is unrelated.
* planned.nix: derive prefixMap from componentPrefix
The hard-coded prefix table duplicated haskellLib.componentPrefix.
If anyone adds a new component type to that single source of truth,
planned.nix would silently miss it.
Pass componentPrefix in and invert it (collection -> prefix becomes
prefix -> collection). Verified the inverted map equals the previous
literal { exe = "exes"; test = "tests"; bench = "benchmarks";
flib = "foreignlibs"; lib = "sublibs"; }.
* load-cabal-plan: reject unknown install-plan entries
The single-pass groupBy in b3f7c7dfa replaced an explicit
`type == "configured" && (style == "global" || style == "inplace")`
filter with an else-branch, so any plan entry that wasn't pre-existing
or configured/local fell into `nonLocal` -- which the consumer treats
as a global hackage package. For current cabal output that's the same
set, but the change silently widens the bucket if cabal ever emits a
new type or style we haven't taught us to handle.
Restore the explicit guard. Anything outside the four recognized
shapes (pre-existing; configured/local; configured/global;
configured/inplace) throws with the offending id/type/style so a real
plan shape we need to handle surfaces immediately, instead of being
silently misclassified as a hackage import.
* Bump head.hackage
* checkUnique: warn-not-error on name-only collisions
bd93f01d3 rewrote checkUnique to error on any two items sharing a name,
which is stricter than master's behavior. Master's checkUnique
(`length x == length (uniqueWithName x)`) only errored when
`uniqueWithName` would actually drop items -- i.e., when two items were
structurally identical. Two structurally-distinct items with the same
name (e.g. an HsOpenSSL.libs override that appended a non-static openssl
on top of the default openssl from cabal2nix) used to pass silently.
The bd93f01d3 strictness surfaced as `Duplicate items found in
HsOpenSSL ... buildInputs ["openssl-..."]` for th-dlls.build-ei. That
duplication is real and worth flagging, but escalating to a hard error
is too aggressive for a long-standing pattern.
Restore master's "structurally-identical = error" rule, and add a
warning for the name-only case so the underlying list-merge issue is
visible without breaking builds. Both functions now share a
`uniqueWithNameKey` helper so the name+version logic stays consistent.
---------
Co-authored-by: Hamish Mackenzie <[email protected]>
Add WASM tutorial to docs
Documents how to build WebAssembly packages with haskell.nix using a Nix flake, covering the flake setup, build commands, test execution, dev shell usage, the overlay stack, and known limitations.
checkUnique: warn-not-error on name-only collisions
bd93f01d3 rewrote checkUnique to error on any two items sharing a name, which is stricter than master's behavior. Master's checkUnique (`length x == length (uniqueWithName x)`) only errored when `uniqueWithName` would actually drop items -- i.e., when two items were structurally identical. Two structurally-distinct items with the same name (e.g. an HsOpenSSL.libs override that appended a non-static openssl on top of the default openssl from cabal2nix) used to pass silently. The bd93f01d3 strictness surfaced as `Duplicate items found in HsOpenSSL ... buildInputs ["openssl-..."]` for th-dlls.build-ei. That duplication is real and worth flagging, but escalating to a hard error is too aggressive for a long-standing pattern. Restore master's "structurally-identical = error" rule, and add a warning for the name-only case so the underlying list-merge issue is visible without breaking builds. Both functions now share a `uniqueWithNameKey` helper so the name+version logic stays consistent.
Bump head.hackage
load-cabal-plan: reject unknown install-plan entries
The single-pass groupBy in b3f7c7dfa replaced an explicit `type == "configured" && (style == "global" || style == "inplace")` filter with an else-branch, so any plan entry that wasn't pre-existing or configured/local fell into `nonLocal` -- which the consumer treats as a global hackage package. For current cabal output that's the same set, but the change silently widens the bucket if cabal ever emits a new type or style we haven't taught us to handle. Restore the explicit guard. Anything outside the four recognized shapes (pre-existing; configured/local; configured/global; configured/inplace) throws with the offending id/type/style so a real plan shape we need to handle surfaces immediately, instead of being silently misclassified as a hackage import.
planned.nix: derive prefixMap from componentPrefix
The hard-coded prefix table duplicated haskellLib.componentPrefix.
If anyone adds a new component type to that single source of truth,
planned.nix would silently miss it.
Pass componentPrefix in and invert it (collection -> prefix becomes
prefix -> collection). Verified the inverted map equals the previous
literal { exe = "exes"; test = "tests"; bench = "benchmarks";
flib = "foreignlibs"; lib = "sublibs"; }.
planned.nix: drop unused getComponents parameter
After d3819208f, planned.nix extracts component keys directly from plan.json and no longer calls getComponents, but it still took it as a parameter and the call site in lib/load-cabal-plan.nix still passed it. Drop both. getComponents (plural) is internal to load-cabal-plan.nix and is not exposed publicly; the externally-visible name is the singular project.getComponent / package.getComponent, which is unrelated.
Bump stale head.hackage pin in test/cabal.project.local
Fix uniqueWithName to preserve structurally distinct items
The listToAttrs rewrite in bd93f01d3 keyed every item by `x.name or
"noname"` and let listToAttrs first-wins handle collisions. That
collapses any two items sharing a key (or both lacking `.name`) to
one survivor, even when they are structurally different -- which
contradicts the function's contract. uniqueWithName must behave like
`lib.unique`; the name partition is a *speedup* (so lib.unique only
has to scan within a bucket), not a truncation.
This broke `shellFor`: builder/shell-for.nix:92-93 runs uniqueWithName
on `cfg.depends`, which lookupDependency populates with haskell.nix
package values (`hsPkgs.<unit-id>`). Those expose `.identifier.{name,
version}` but not `.name`, so every dependency landed in the noname
bucket and was reduced to one entry. The resulting GHC package DB
held only one library, surfacing as `Could not find module 'Conduit'`
in the shell-for and shell-for-setup-deps tests across all GHC
versions in eval 1223.
Restore the contract: groupBy by a synthesized key, then `lib.unique`
per bucket. Single-item buckets stay linear (lib.unique on a
1-element list is O(1)); multi-item buckets are correctly structural-
deduped instead of silently truncated. Keying:
- derivations: their `.name` already encodes name+version
- haskell.nix packages: `"${identifier.name} ${identifier.version}"`
with a space separator so package keys cannot collide with
derivation keys derived from the same words
- everything else: shared `_noname`/`_notset` bucket; correctness still
holds via the inner lib.unique, just at the slower path.
Note: shellFor has fed packages-without-`.name` into uniqueWithName
since at least 2019 (hspkg-builder.nix has never set `.name`), so this
is a long-standing reliance on the slow path's tolerance for noname
collisions, not a new condition.
Merge remote-tracking branch 'origin/master' into angerman/optimize-uniqueWithName
Pin alfred-margaret <2.1.1.0 in hoogle for GHC <9.10 (#2496)
alfred-margaret 2.1.1.0 (2026-04-24) uses bare `foldl'` which is only in Prelude from base-4.20 (GHC 9.10) onwards, so it fails to compile under GHC 9.6 and 9.8. It is pulled in transitively by hoogle via hackage-revdeps, breaking the 42 shell-for / simple-shell test jobs.
Pin alfred-margaret <2.1.1.0 in hoogle for GHC <9.10
alfred-margaret 2.1.1.0 (2026-04-24) uses bare `foldl'` which is only in Prelude from base-4.20 (GHC 9.10) onwards, so it fails to compile under GHC 9.6 and 9.8. It is pulled in transitively by hoogle via hackage-revdeps, breaking the 42 shell-for / simple-shell test jobs.
Add linker pool allocator for aarch64 under qemu (cf GHC #24432) (#2493)
* Add linker pool allocator for aarch64 under qemu (cf GHC #24432) When running the GHC RTS linker under qemu user-mode emulation, mmap hint addresses are ignored, causing allocations to scatter across the address space. This leads to ADR_GOT_PAGE relocation overflow (±4GB range exceeded) on aarch64. This patch pre-allocates a single contiguous 512MB RWX pool and sub-allocates from it for all linker needs: sections, GOT, BSS, and COMMON symbols. The pool is split into RW (growing down) and RX (growing up) halves, guaranteeing all allocations stay close. Also fixes GOT slot allocation for STB_LOCAL symbols (e.g. approx_tab in Android NDK's libm.a) which have GOT-relative relocations but were not assigned GOT slots. Applied to GHC 9.6.7, 9.8.3+, 9.10.2+ (versions that already use m32 for regular sections but missed BSS, COMMON, and GOT). Enables android and aarch64-cross TH tests (annotations, js-template-haskell, th-dlls) that were previously disabled due to iserv hanging under qemu. * Update nixpkgs-unstable and nixpkgs-2511, fix deprecation warnings Update nixpkgs-unstable and nixpkgs-2511 pins and fix the resulting evaluation warnings for deprecated package names. Uses backwards-compatible fallback patterns so older nixpkgs still works: - Replace xorg.* references with (pkgs.newName or pkgs.xorg.oldName) - Add xorgCompat set in pkgconf-nixpkgs-map.nix to map deprecated xorg attribute names to their new top-level equivalents - Update renamed packages (enchant2, unixODBC, goocanvas, etc.) using a prefer helper that selects the new name when available * Patch hp2ps for GCC 15 compatibility (GHC 9.6–9.8) GHC 9.6.x and 9.8.x utils/hp2ps/Utilities.c uses K&R-style extern declarations for malloc/realloc without including <stdlib.h>. GCC 15 treats these as zero-argument functions, causing build failure. * Remove deprecated 'pie' hardening flag for musl builds nixpkgs 26.05 removed 'pie' from the hardening system entirely -- PIE is now enabled by default in compilers. Any mention of 'pie' in either hardeningEnable or hardeningDisable triggers a deprecation warning: "The 'pie' hardening flag has been removed in favor of enabling PIE by default in compilers and should no longer be used." This causes ~68 warnings per evaluation for projects with musl cross-compilation, which is every haskell.nix project using crossPlatforms with musl64 or aarch64-multiplatform-musl. Remove the two places where 'pie' was added to hardeningDisable: - builder/comp-builder.nix: every Haskell component on musl - compiler/ghc/default.nix: GHC itself on musl targets * Make pie hardening removal backwards compatible Only disable pie for musl when the toolchain still has it as a default hardening flag (nixpkgs <= 25.05). On newer nixpkgs where pie was removed from the hardening system, skip it to avoid the deprecation warning. * Add wine 11.0 patch for LdrAddDllDirectory device paths Wine 11.0 renamed DOS_PATHNAME_TYPE to RTL_PATH_TYPE and changed the enum values (DEVICE_PATH -> RtlPathTypeLocalDevice). Add a new patch variant for wine >= 11.0 that uses the new API names. * Drop removed 'static' argument from zlib override in android overlay The 'static' parameter was removed from zlib in nixpkgs-unstable. Setting 'shared = false' is sufficient to get a static-only build and works across all nixpkgs versions. * Fix emnm path for emscripten 4.0+ in GHCJS builds Emscripten 4.0+ moved emnm from share/emscripten/emnm to share/emscripten/tools/emnm.py. Use builtins.pathExists to select the correct path for backwards compatibility. * Fix musl cross-compilation for libffi, gmp and ncurses - libffi, gmp: disable doCheck when cross-compiling since test binaries can't execute on the build host - ncurses: disable broken symlink check when cross-compiling to avoid case-sensitive symlink target mismatch * Disable terminfo for cross-compilation, fix ncurses handling Hadrian builds terminfo unconditionally for stage0, passing the same --with-curses-libraries to both stage0 (host compiler) and stage1 (target compiler). Before GHC 9.15 (which has MR 13932), this cannot work when the host and target have different ncurses (e.g. glibc vs musl), because the host compiler can't link against target static libs. Matching nixpkgs common-hadrian.nix: - Disable enableTerminfo when platform configs differ (cross builds) for GHC < 9.15 - Gate --with-curses-libraries on enableTerminfo so it's not passed in cross builds (avoiding the stage0 ABI mismatch) - Keep ncurses in libDeps unconditionally (not gated on enableTerminfo) since hadrian builds terminfo for stage0 regardless, and depsTargetTarget needs target ncurses for stage1 * Extend hp2ps stdlib patch to all affected GHC versions The K&R-style extern void* malloc() in utils/hp2ps/Utilities.c is present in all GHC versions from 8.10.7 through 9.12.3. It was fixed with a proper prototype in 9.10.2 and fully fixed with #include <stdlib.h> in 9.10.3 and 9.12.4+. * Fix Wine for 11.0+: use lib.getExe and wine64Packages Wine 11.0 removed the wine64 binary, unifying it into wine. Use wine64Packages.minimal (for 64-bit support) and lib.getExe to pick the correct binary name via meta.mainProgram. Also patch wine64Packages.minimal with the same fixes as winePackages.minimal. --------- Co-authored-by: Mateusz Galazyn <[email protected]>