Extract dummy-ghc, make it cross-aware, and fix plan-nix UnitId stability (#2509)
Cabal-install reads `ghc --info` during plan elaboration to decide
per-unit settings (`--enable-shared` vs `--disable-shared`, RTS-way
inclusion, etc.) that feed into the recorded UnitId hash. The
inline `dummy-ghc` script in `lib/call-cabal-project-to-nix.nix`
was a stripped-down stub whose `--info` output didn't match the
real cross GHCs', so plan-nix recorded UnitIds that diverged from
what a downstream cabal v2-build (or any consumer running cabal
against the real compiler) would compute.
Three changes:
1. **`lib/dummy-ghc.nix`** (new): extract the dummy-ghc script and
emit cross-aware `--info` capabilities matching real cross GHCs
for windows, ghcjs, wasm, android, static, native-musl, and
native — `Support dynamic-too`, `Support shared libraries`,
`RTS ways`, `Stage`, `GHC Dynamic`, the iserv-related fields,
etc.
2. **`lib/call-cabal-project-to-nix.nix`**:
* gate the dummy-ghc-pkg `-inplace` suffix on GHC ≥ 9.8 — older
GHCs register pre-existing packages without it, so the dummy
was synthesising the wrong package ids for plan-to-nix
against ghc 8.10 / 9.0 / 9.2 / 9.4 / 9.6.
* pin `CABAL_INSTALLED_PACKAGE_ID_OS` to the build platform's
OS when running plan-to-nix. Without this the patched
cabal-install's installed-package-id format tracks the eval
system; a darwin host evaluating a linux derivation gets the
`VeryShort` form and forks UnitIds from what cabal v2-build
on a linux builder would compute.
3. **`lib/default.nix`**: tighten `uniqueWithNameKey` so
derivations (`.name = "<pkg>-<ver>"`) and module values
(`.identifier.{name,version}`) can't collide on shared name
fragments — partition into `unit-id:` / `id:` / `name:` buckets.
Correctness is unchanged when buckets are correct; this just
avoids the slow `lib.unique` fallback in more cases.
Pulled out of #2504 (`hkm/builder-v2`).