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
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`.
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]>
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.
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.
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.
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]>