Skip to content

ghc: add the 9.10.3 bindist, and let terminfo link - #178

Merged
jonringer merged 1 commit into
ekala-project:masterfrom
hhefesto:ghc-9.10.3-binary
Sep 8, 2026
Merged

jonringer merged 1 commit into
ekala-project:masterfrom
hhefesto:ghc-9.10.3-binary

Conversation

@hhefesto

@hhefesto hhefesto commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

GHC 9.10.3 bindist and a haskell.packages.ghc9103Binary set

corepkgs ships GHC as bindists — 9.0.2 and 9.8.4 today. This adds 9.10.3 the same way, next to them; the default haskellPackages is untouched.

What lands

  • pkgs-many/ghc/9.10.3-binary.nix: 9.8.4-binary.nix with the version and the seven bindist hashes from https://downloads.haskell.org/~ghc/9.10.3/SHA256SUMS; same distribution variants (deb10 i386, deb11 x86_64/aarch64, alpine 3.12/3.18 musl, both darwins), same archSpecificLibraries checks (gmp, libtinfo.so.6), same ld.gold settings patch.
  • pkgs-many/ghc/variants.nix: v9_10_3_binary.
  • haskell/configuration-ghc-9.10.x.nix: the core libraries GHC 9.10 ships, nulled — the 9.8 list plus ghc-experimental, ghc-internal, ghc-platform, ghc-toolchain, os-string, semaphore-compat.
  • haskell/default.nix: compiler.ghc9103Binary and packages.ghc9103Binary.
  • Both 9.8.4-binary.nix and 9.10.3-binary.nix: the bindists' terminfo package links -ltinfo and expects it on the system, so anything using haskeline failed to link (ld: cannot find -ltinfo). Its package-db entry now points at ncurses, the way ghc-bignum's is pointed at gmp.

Why

The haskell-pkgs snapshot is Stackage LTS 24, which targets GHC 9.10: packages there assume base-4.20, Cabal-3.12 and os-string as a core library. Pairing it with 9.8.4 works for much of Hackage but not for a project whose cabal-version is 3.12 (GHC 9.8.4's Cabal is 3.10.3.0 and rejects it). With this set, such a project — telomare is the one that prompted it — builds on ekapkgs unchanged.

Checked

  • nix build .#legacyPackages.x86_64-linux.haskell.compiler.ghc9103Binary — the bindist unpacks, patches and passes the library checks on x86_64-linux.
  • With haskell-pkgs' pkgs-module.nix folded in: telomare (library, three executables, five test suites) and its tool set (haskell-language-server, hlint, stylish-haskell, ghcid, cabal-install) build against ghc9103Binary.

Not decided here

Whether haskellPackages should move to 9.10.3 to match the snapshot. This keeps 9.8.4 as the default so nothing downstream changes.

Noticed along the way (not addressed here): git's documentation build fails with asciidoc: command not found (gitMinimal builds); writeShellApplication's default checkPhase and haskellSrc2nix reference shellcheck-minimal and cabal2nix-unwrapped, which no repository in the ecosystem defines; haskellPackages.cabal-install needs Cabal 3.16 in its scope on either compiler; hw-fingertree needs a jailbreak on 9.10.

corepkgs ships GHC as bindists, 9.0.2 and 9.8.4 so far. This adds 9.10.3 the
same way: `pkgs-many/ghc/9.10.3-binary.nix` is `9.8.4-binary.nix` with the
version and the bindist hashes from downloads.haskell.org, the same
distribution variants and the same library checks, plus a
`configuration-ghc-9.10.x.nix` that nulls the libraries GHC 9.10 ships
(the 9.8 list plus ghc-experimental, ghc-internal, ghc-platform,
ghc-toolchain, os-string and semaphore-compat) and a
`haskell.packages.ghc9103Binary` set built on it.

The bindists' `terminfo` package links `-ltinfo` and expects to find it on
the system, so any program using haskeline failed to link ("cannot find
-ltinfo"). Both the 9.8.4 and the 9.10.3 derivations now point terminfo's
package-db entry at ncurses, the way ghc-bignum's is pointed at gmp.

The default `haskellPackages` stays on 9.8.4. The haskell-pkgs snapshot is
Stackage LTS 24, which targets GHC 9.10, so a project needing that pairing
can select `haskell.packages.ghc9103Binary`; whether the default should move
is a separate decision.

@jonringer jonringer left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice :)

@jonringer
jonringer merged commit 44b60e1 into ekala-project:master Sep 8, 2026
2 checks passed
@jonringer

Copy link
Copy Markdown
Collaborator

Noticed along the way (not addressed here): git's documentation build fails with asciidoc: command not found (gitMinimal builds); writeShellApplication's default checkPhase and haskellSrc2nix reference shellcheck-minimal and cabal2nix-unwrapped, which no repository in the ecosystem defines; haskellPackages.cabal-install needs Cabal 3.16 in its scope on either compiler; hw-fingertree needs a jailbreak on 9.10.

Unfortunately shellcheck isn't in corepkgs becuase it needs a haskell package set, and that's in https://github.com/ekala-project/haskell-pkgs

@hhefesto

hhefesto commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

This was a bit of a mishap on my part. I left my fable running at night to fully use my fable tokens right before my weekly cutoff (my week ended yesterday at 2 am). I opened a new PR (better reviewed) fixing some clear mistakes and am currently working on actually having tested with HLS (so on a new pr to haskell-pkgs)

hhefesto added a commit to hhefesto/stand-in-language that referenced this pull request Sep 8, 2026
The Nix build moves to the ekala package ecosystem: corepkgs for the base
system and the compiler, haskell-pkgs for the Hackage snapshot (Stackage
LTS 24). flake-parts, haskell-flake, flake-compat and the nixpkgs input go;
the flake has two inputs and uses `corepkgs.lib.mkFlake`. Everything, the
tools included, is built with one compiler, GHC 9.10.3.

GHC stays at 9.10.3: corepkgs carried only 9.8.4 and 9.0.2 bindists, so the
9.10.3 bindist and a `haskell.packages.ghc9103Binary` set were added
upstream (ekala-project/corepkgs#178, corrected in #180), with the bindists'
terminfo made to link (without that, nothing using haskeline links). The
corepkgs input is `github:ekala-project/corepkgs`. `cabal-version: 3.12`
and the sources are unchanged.

haskell-language-server needs its whole closure built in one Cabal-syntax
3.14 scope (ormolu, fourmolu, cabal-add and the server want 3.14 where GHC
9.10 bundles 3.12, and `extensions` is pinned to 3.12; Cabal refuses the
mix). That is ekala-project/haskell-pkgs#4; until it lands, the
haskell-pkgs input points at the fork branch hhefesto/haskell-pkgs/hls-ghc910,
and then moves back to ekala-project/haskell-pkgs.

Every entry point is preserved: `nix build`, `nix run .`/`.#repl`/`.#lsp`/
`.#format`/`.#format-lint`/`.#push-cachix`, the per-executable apps CI and
the Emacs mode use, `nix develop`, `nix flake check`, `nix-build` and
`nix-shell`. The default dev shell is the minimum that builds the project
(GHC and cabal-install); `nix develop .#full` adds haskell-language-server,
hlint, stylish-haskell and ghcid; hoogle is no longer built for either.

The Nix code lives in nix/: haskell.nix names the compiler and the tools,
telomare.nix is the package policy (built from `cabal sdist`, tests on, no
haddock or profiling, as haskell-flake did), tools.nix the shell apps,
devshell.nix, and pins.nix/pkgs.nix/legacy.nix for default.nix and
shell.nix, which read the pins from flake.lock. The package expression is a
checked-in cabal2nix file: ekapkgs does not define `cabal2nix-unwrapped`,
so `callCabal2nix` cannot evaluate; a dependency missing from the file
fails `Setup configure` loudly, and nothing is imported from a derivation
any more. Shell apps carry an explicit shellcheck check phase, since
`writeShellApplication`'s default refers to a `shellcheck-minimal` ekapkgs
does not define; shellcheck and cachix come from the 9.10.3 set rather than
haskell-pkgs' 9.8.4-built top level. The apps use `gitMinimal`: they only
list and read tracked files, and the full git brings its manual into the
closure. `cabal-install` is marked unbroken (the snapshot flags it with no
broken dependency) and built against the snapshot's Cabal 3.16, which
cabal-install 3.16 requires and GHC 9.10's bundled 3.12 is not.
`apps.telomare-lsp` carries the version stamp like `apps.lsp`; `systems`
is x86_64-linux until corepkgs marks aarch64-linux supported. CI pulls
from `ekala-corepkgs` too and accepts the flake's nixConfig.

Verified on x86_64-linux: the package builds from the sdist tarball with
its five suites passing; `nix run .#telomare-repl -- --expr 'succ 7'` gives
8; `nix-build` yields the flake's store path; `nix develop .#full -c
haskell-language-server --version` reports 2.13.0.0 on GHC 9.10.3 and the
server typechecks the 26 modules under src/; against the nixpkgs build of
master, `tictactoe.telc`, the simpleplus run transcript, its certificate
and its meter are byte-identical.
hhefesto added a commit to hhefesto/stand-in-language that referenced this pull request Sep 9, 2026
The Nix build moves to the ekala package ecosystem: corepkgs for the base
system and the compiler, haskell-pkgs for the Hackage snapshot (Stackage
LTS 24). flake-parts, haskell-flake, flake-compat and the nixpkgs input go;
the flake has two inputs and uses `corepkgs.lib.mkFlake`. Everything, the
tools included, is built with one compiler, GHC 9.10.3.

GHC stays at 9.10.3: corepkgs carried only 9.8.4 and 9.0.2 bindists, so the
9.10.3 bindist and a `haskell.packages.ghc9103Binary` set were added
upstream (ekala-project/corepkgs#178, corrected in #180), with the bindists'
terminfo made to link (without that, nothing using haskeline links). The
corepkgs input is `github:ekala-project/corepkgs`. `cabal-version: 3.12`
and the sources are unchanged.

haskell-language-server needs its whole closure built in one Cabal-syntax
3.14 scope (ormolu, fourmolu, cabal-add and the server want 3.14 where GHC
9.10 bundles 3.12, and `extensions` is pinned to 3.12; Cabal refuses the
mix). nix/haskell.nix carries that override, the recipe of nixpkgs'
configuration-common.nix and of ekala-project/haskell-pkgs#4; it goes when
the fix lands upstream, in haskell-pkgs or corepkgs. Both inputs point at
ekala-project. corepkgs' treefmt-nix input drags nixpkgs into the lock for
a formatter this flake never evaluates; it follows nix-lib instead, so the
lock and the cache push carry no nixpkgs checkout.

Every entry point is preserved: `nix build`, `nix run .`/`.#repl`/`.#lsp`/
`.#format`/`.#format-lint`/`.#push-cachix`, the per-executable apps CI and
the Emacs mode use, `nix develop`, `nix flake check`, `nix-build` and
`nix-shell`. The default dev shell is the minimum that builds the project
(GHC and cabal-install); `nix develop .#full` adds haskell-language-server,
hlint, stylish-haskell and ghcid; hoogle is no longer built for either.

The Nix code lives in nix/: haskell.nix names the compiler and the tools,
telomare.nix is the package policy (built from `cabal sdist`, tests on, no
haddock or profiling, as haskell-flake did), tools.nix the shell apps,
devshell.nix, and pins.nix/pkgs.nix/legacy.nix for default.nix and
shell.nix, which read the pins from flake.lock. The package expression is a
checked-in cabal2nix file: ekapkgs does not define `cabal2nix-unwrapped`,
so `callCabal2nix` cannot evaluate; a dependency missing from the file
fails `Setup configure` loudly, and nothing is imported from a derivation
any more. Shell apps carry an explicit shellcheck check phase, since
`writeShellApplication`'s default refers to a `shellcheck-minimal` ekapkgs
does not define; shellcheck and cachix come from the 9.10.3 set rather than
haskell-pkgs' 9.8.4-built top level. The apps use `gitMinimal`: they only
list and read tracked files, and the full git brings its manual into the
closure. CI's install-nix-action and cachix-action move to v31 and v17. `cabal-install` is marked unbroken (the snapshot flags it with no
broken dependency) and built against the snapshot's Cabal 3.16, which
cabal-install 3.16 requires and GHC 9.10's bundled 3.12 is not.
`apps.telomare-lsp` carries the version stamp like `apps.lsp`; `systems`
is x86_64-linux until corepkgs marks aarch64-linux supported. CI pulls
from `ekala-corepkgs` too and accepts the flake's nixConfig.

Verified on x86_64-linux: the package builds from the sdist tarball with
its five suites passing; `nix run .#telomare-repl -- --expr 'succ 7'` gives
8; `nix-build` yields the flake's store path; `nix develop .#full -c
haskell-language-server --version` reports 2.13.0.0 on GHC 9.10.3 and the
server typechecks the 26 modules under src/; against the nixpkgs build of
master, `tictactoe.telc`, the simpleplus run transcript, its certificate
and its meter are byte-identical.
hhefesto added a commit to hhefesto/stand-in-language that referenced this pull request Sep 15, 2026
The Nix build moves to the ekala package ecosystem: corepkgs for the base
system and the compiler, haskell-pkgs for the Hackage snapshot (Stackage
LTS 24). flake-parts, haskell-flake, flake-compat and the nixpkgs input go;
the flake has two inputs and uses `corepkgs.lib.mkFlake`. The project and
every packaged Haskell tool are built with one compiler, GHC 9.10.3.

GHC stays at 9.10.3: corepkgs carried only 9.8.4 and 9.0.2 bindists, so the
9.10.3 bindist and a `haskell.packages.ghc9103Binary` set were added
upstream (ekala-project/corepkgs#178, corrected in #180), with the bindists'
terminfo made to link. `cabal-version: 3.12` and the sources are unchanged.

haskell-language-server needs its whole closure built in one Cabal-syntax
3.14 scope (ormolu, fourmolu, cabal-add and the server want 3.14 where GHC
9.10 bundles 3.12). nix/haskell.nix carries that override, the recipe of
nixpkgs' configuration-common.nix and of ekala-project/haskell-pkgs#4; it
goes when the fix lands upstream. Both inputs point at ekala-project.
corepkgs' treefmt-nix input drags nixpkgs into the lock for a formatter this
flake never evaluates; it follows nix-lib instead, so the lock and the cache
push carry no nixpkgs checkout.

Every entry point is preserved: `nix build`, `nix run .`/`.#repl`/`.#lsp`/
`.#format`/`.#format-lint`/`.#push-cachix`, the per-executable apps CI and
the Emacs mode use, `nix develop`, `nix flake check`, `nix-build` and
`nix-shell`. The default dev shell is the minimum that builds the project
(GHC and cabal-install); `nix develop .#full` adds haskell-language-server,
hlint, stylish-haskell and ghcid; hoogle is no longer built for either.

The Nix code lives in nix/: haskell.nix names the compiler and the tools,
telomare.nix is the package policy (built from `cabal sdist`, tests on, no
haddock or profiling, as haskell-flake did), tools.nix the shell apps,
devshell.nix, and pins.nix/pkgs.nix/legacy.nix for default.nix and
shell.nix, which read the pins from flake.lock. The package expression is a
checked-in cabal2nix file: ekapkgs does not define `cabal2nix-unwrapped`,
so `callCabal2nix` cannot evaluate; a dependency missing from the file
fails `Setup configure`, and nothing is imported from a derivation any
more. Shell apps carry an explicit shellcheck check phase, since
`writeShellApplication`'s default refers to a `shellcheck-minimal` ekapkgs
does not define; shellcheck comes from the 9.10.3 set rather than
haskell-pkgs' 9.8.4-built top level. `cabal-install` is marked unbroken
(the snapshot flags it with no broken dependency) and built against the
snapshot's Cabal 3.16, which it requires. The apps use `gitMinimal`: they
only list and read tracked files.

`nix run .#push-cachix`, the maintainers' tool, now publishes every declared
dev shell with its `nix develop` environment closure (so the full shell's
HLS and editor tools reach the cache) and is built and shellchecked by
`nix flake check`. It uses the cachix and the nix on the caller's PATH:
the snapshot's cachix does not build (its amazonka 2.0 predates GHC 9.8),
and corepkgs' Nix is a from-source build nothing else needs.

`apps.telomare-lsp` carries the version stamp like `apps.lsp`; `systems`
is x86_64-linux until corepkgs marks aarch64-linux supported. CI pulls
from `ekala-corepkgs` instead of `nix-community`, accepts the flake's
nixConfig, and moves install-nix-action and cachix-action to v31 and v17.

Verified on x86_64-linux (corepkgs c3bf28c4, haskell-pkgs 427f504a): the
package builds from the sdist tarball with its five suites passing;
`nix run .#telomare-repl -- --expr 'succ 7'` gives 8; `nix-build` yields
the flake's store path; `nix develop .#full -c haskell-language-server
--version` reports 2.13.0.0 on GHC 9.10.3 and the server typechecks the
26 modules under src/; against the nixpkgs build of master,
`tictactoe.telc`, the simpleplus run transcript, its certificate and its
meter are byte-identical.
hhefesto added a commit to hhefesto/stand-in-language that referenced this pull request Sep 15, 2026
The Nix build moves to the ekala package ecosystem: corepkgs for the base
system and the compiler, haskell-pkgs for the Hackage snapshot (Stackage
LTS 24). flake-parts, haskell-flake, flake-compat and the nixpkgs input go;
the flake has two inputs and uses `corepkgs.lib.mkFlake`. The project and
every packaged Haskell tool are built with one compiler, GHC 9.10.3.

GHC stays at 9.10.3: corepkgs carried only 9.8.4 and 9.0.2 bindists, so the
9.10.3 bindist and a `haskell.packages.ghc9103Binary` set were added
upstream (ekala-project/corepkgs#178, corrected in #180), with the bindists'
terminfo made to link. `cabal-version: 3.12` and the sources are unchanged.

haskell-language-server needs its whole closure built in one Cabal-syntax
3.14 scope (ormolu, fourmolu, cabal-add and the server want 3.14 where GHC
9.10 bundles 3.12). nix/haskell.nix carries that override, the recipe of
nixpkgs' configuration-common.nix and of ekala-project/haskell-pkgs#4; it
goes when the fix lands upstream. Both inputs point at ekala-project.
corepkgs' treefmt-nix input drags nixpkgs into the lock for a formatter this
flake never evaluates; it follows nix-lib instead, so the lock and the cache
push carry no nixpkgs checkout.

Every entry point is preserved: `nix build`, `nix run .`/`.#repl`/`.#lsp`/
`.#format`/`.#format-lint`/`.#push-cachix`, the per-executable apps CI and
the Emacs mode use, `nix develop`, `nix flake check`, `nix-build` and
`nix-shell`. The default dev shell is the minimum that builds the project
(GHC and cabal-install); `nix develop .#full` adds haskell-language-server,
hlint, stylish-haskell and ghcid; hoogle is no longer built for either.

The Nix code lives in nix/: haskell.nix names the compiler and the tools,
telomare.nix is the package policy (built from `cabal sdist`, tests on, no
haddock or profiling, as haskell-flake did), tools.nix the shell apps,
devshell.nix, and pins.nix/pkgs.nix/legacy.nix for default.nix and
shell.nix, which read the pins from flake.lock. The package expression is a
checked-in cabal2nix file: ekapkgs does not define `cabal2nix-unwrapped`,
so `callCabal2nix` cannot evaluate; a dependency missing from the file
fails `Setup configure`, and nothing is imported from a derivation any
more. Shell apps carry an explicit shellcheck check phase, since
`writeShellApplication`'s default refers to a `shellcheck-minimal` ekapkgs
does not define; shellcheck comes from the 9.10.3 set rather than
haskell-pkgs' 9.8.4-built top level. `cabal-install` is marked unbroken
(the snapshot flags it with no broken dependency) and built against the
snapshot's Cabal 3.16, which it requires. The apps use `gitMinimal`: they
only list and read tracked files.

`nix run .#push-cachix`, the maintainers' tool, now publishes every declared
dev shell with its `nix develop` environment closure (so the full shell's
HLS and editor tools reach the cache) and is built and shellchecked by
`nix flake check`. It uses the cachix and the nix on the caller's PATH:
the snapshot's cachix does not build (its amazonka 2.0 predates GHC 9.8),
and corepkgs' Nix is a from-source build nothing else needs.

`apps.telomare-lsp` carries the version stamp like `apps.lsp`; `systems`
is x86_64-linux until corepkgs marks aarch64-linux supported. CI pulls
from `ekala-corepkgs` instead of `nix-community`, accepts the flake's
nixConfig, and moves install-nix-action and cachix-action to v31 and v17.

Verified on x86_64-linux (corepkgs c3bf28c4, haskell-pkgs 427f504a): the
package builds from the sdist tarball with its five suites passing;
`nix run .#telomare-repl -- --expr 'succ 7'` gives 8; `nix-build` yields
the flake's store path; `nix develop .#full -c haskell-language-server
--version` reports 2.13.0.0 on GHC 9.10.3 and the server typechecks the
26 modules under src/; against the nixpkgs build of master,
`tictactoe.telc`, the simpleplus run transcript, its certificate and its
meter are byte-identical.
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