Skip to content

Update stacked: cabal 3.18.1.0 + vim 9.2.0818 - #496

Merged
twitchyliquid64 merged 12 commits into
mainfrom
fix-ghc-bundle-bootstrap
Jul 22, 2026
Merged

Update stacked: cabal 3.18.1.0 + vim 9.2.0818#496
twitchyliquid64 merged 12 commits into
mainfrom
fix-ghc-bundle-bootstrap

Conversation

@bryan-minimal

@bryan-minimal bryan-minimal commented Jul 21, 2026

Copy link
Copy Markdown
Member

Supersedes #495, keeping the bundle intact and adding the fourth package it needs to build.

Why #495 failed

File "/build/ghc-9.14.1/hadrian/bootstrap/bootstrap.py", line 146, in dep_from_json
    return BootstrapDep(**o)
TypeError: BootstrapDep.__new__() missing 1 required positional argument: 'component'

stdout: using plan-bootstrap.json from ../hadrian-bootstrap-sources-9.8.1.tar.gz

packages/ghc/build.ncl had a hard-coded version inside a templated URL:

url = ".../~ghc/%{version}/hadrian-bootstrap-sources/hadrian-bootstrap-sources-9.8.1.tar.gz"
                ^^^^^^^^^^ follows the bump                                   ^^^^^ pinned

The directory tracked ghc to 9.14.1; the filename stayed at 9.8.1. It only got as far as unpacking because the stale 9.8.1 tarball is still in our gs:// mirror from the 9.10.3 era — then 9.14.1's bootstrap.py rejected its plan-bootstrap.json for lacking component.

(Same defect shape as the provenance-comment bug fixed in pkgmgr-rs#550 — a version appearing twice with only one occurrence rewritten. There it was cosmetic; here it breaks the build.)

Why bumping that filename alone isn't enough

GHC 9.14.1 publishes bootstrap sources for only 9.10.1 and 9.12.2 — there is no 9.8.1 under it:

ghc bootstrap 9.8.1 9.10.1 9.12.2
9.10.3 (old) ✅ 200 404 404
9.14.1 ❌ 404 ✅ 200 ✅ 200

And ghc-bootstrap — the bootstrap compiler — was pinned at 9.8.1, which cannot drive a 9.12.2 plan. So the bundle needs ghc-bootstrap moved in lockstep. That's the fourth package.

This PR

package
ghc 9.10.3 → 9.14.1
ghc-bootstrap 9.8.1 9.12.2 (new here)
cabal 3.12.1.0 → 3.18.1.0
vim → 9.2.0818

plus the hadrian bootstrap sources URL moved 9.8.1 → 9.12.2 to match the bootstrap compiler.

Verified before pushing, not assumed

  • All three new URLs return 200 (both ghc-bootstrap arch tarballs + the hadrian sources)
  • ghc-bootstrap sha256s are the official values from downloads.haskell.org/~ghc/9.12.2/SHA256SUMS
  • Both arch filenames (x86_64-deb11, aarch64-deb10) exist unchanged for 9.12.2, so no naming change was needed
  • The 9.12.2 plan-bootstrap.json carries component on all 19 dependencies — the exact field whose absence threw the TypeError

Rebased onto current main

#495 branched before #493 merged, so a naive diff reverted fontconfig 2.18.2 → 2.17.1 and pango 1.58.0 → 1.56.4. Rebased onto main so those stay at their merged values; this PR touches only the four packages above.

#495 can close in favour of this.

Note

GHC is the base of the Haskell toolchain, so expect this to cascade into the Tamarin packages (built against 9.10.3) — worth watching the build for those.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Updates
    • Updated Cabal to version 3.18.1.0.
    • Updated GHC Bootstrap to version 9.12.2.
    • Updated GHC to version 9.14.1.
    • Updated Vim to version 9.2.0818.
    • Refreshed download verification checksums to match the new upstream artifacts.
  • Build Improvements
    • Improved bootstrapping source selection by automatically using the correct Hadrian bootstrap archive (with clear failure if ambiguous).
    • During GHC configuration, added system libffi support via --with-system-libffi.
    • Improved Cabal bootstrap plan handling by selecting the appropriate plan and failing clearly if it’s missing.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 20 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1bad994a-97a3-4d70-932c-483df0df129e

📥 Commits

Reviewing files that changed from the base of the PR and between 1d781e7 and 2954217.

📒 Files selected for processing (2)
  • packages/cabal/build.sh
  • packages/cabal/update_bootstrap_json.py
📝 Walkthrough

Walkthrough

Build specifications update Cabal, GHC, GHC bootstrap, and Vim to newer upstream versions with matching checksums. Bootstrap scripts now select validated inputs, and GHC configuration enables system libffi.

Changes

Upstream refresh

Layer / File(s) Summary
Compiler toolchain source refresh
packages/ghc-bootstrap/build.ncl, packages/ghc/build.ncl, packages/ghc/build.sh
GHC inputs move to newer versions with updated archive checksums, Hadrian source selection requires exactly one matching archive, and configuration enables system libffi.
Cabal bootstrap plan selection
packages/cabal/build.sh
Bootstrap JSON generation uses bootstrap/linux-9.12.4.json, validates its presence, and reports available plans when missing.
Package archive version refresh
packages/cabal/build.ncl, packages/vim/build.ncl
Cabal and Vim move to newer upstream archives with matching checksums.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: 0chroma

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches real changes in the PR, but it omits the major GHC and bootstrap toolchain updates.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-ghc-bundle-bootstrap

Comment @coderabbitai help to get the list of available commands.

bryan-minimal and others added 3 commits July 21, 2026 10:20
I moved the hadrian bootstrap sources URL from 9.8.1 to 9.12.2 and left
the 9.8.1 checksum in place, so the build got past bootstrap.py and then
failed the integrity check:

  HashMismatch: want=eec7233763bc…  got=dc17594bdbad…

`want` was the stale declared hash; `got` is the real 9.12.2 tarball.
Verified by downloading it directly — it hashes to dc17594bdbad…,
matching the builder's `got` exactly.

This is the same half-rewrite defect this PR exists to fix, committed by
hand in the fix itself: a source moved and only one of its two coupled
fields followed. Noting that plainly because it argues the check belongs
in the tooling rather than in reviewer discipline.

Also re-verified the ghc source tarball's own sha256, which I had taken
on trust from the bot: computed, declared, and the official SHA256SUMS
entry all agree on 2a83779c9af8….

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
build.sh passed --bootstrap-sources ../hadrian-bootstrap-sources-9.8.1.tar.gz
with the version hard-coded, so moving build.ncl to 9.12.2 left this
pointing at a file that no longer gets fetched:

  FileNotFoundError: '/build/hadrian-bootstrap-sources-9.8.1.tar.gz'

That is the THIRD copy of this version in the package — url, sha256, and
this argument — and the third consecutive failure from the same cause:
first the url alone was moved (plan lacked `component`), then the sha256
was left behind (HashMismatch), now the build.sh argument. Each fix
revealed the next copy, one ~50s build at a time.

So this removes the copy rather than updating it. The version lives in
build.ncl's url + sha256, which are already coupled and checksum-verified;
build.sh now globs for whatever was fetched. It fails loudly unless the
glob matches exactly one existing file, so an ambiguous /build can never
silently select the wrong bootstrap plan.

Also verified the remaining build.sh patches against the real 9.14.1
source tree rather than waiting for the build to find out — all five
guards still match:

  State.hs `import Data.List ( ... sortOn )`      line 114  ✓
  State.hs `let preload1 = nonDetKeysUniqMap ...` line 1682 ✓
  ghc-pkg  `confs = map (path </>) $ filter ...`  line 940  ✓
  ghc-pkg  `import Data.List ( group, sort, ... )` line 78  ✓ (sort in scope)
  hp2ps    `extern void *realloc();`              ABSENT

The hp2ps line is gone in 9.14.1 (fixed upstream), so that `sed -i` is now
a silent no-op — harmless, since it is unguarded, but it can be dropped
once this lands.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ghc/build.sh (1)

91-106: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Add the reproducible-build controls here
This script still misses the standard CFLAGS/CXXFLAGS/LDFLAGS/ARFLAGS setup, plus the post-install --enable-deterministic-archives/.la cleanup expected by the package rules. The required two-pass $OUTPUT_DIR comparison also isn’t wired in yet; add it here or in the package harness.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ghc/build.sh` around lines 91 - 106, Update the build flow around
the GHC configure, Hadrian install, and package-cache recache commands to apply
the standard reproducible-build CFLAGS, CXXFLAGS, LDFLAGS, and ARFLAGS, enable
deterministic archives, and remove installed .la files as required by the
package rules. Add the required two-pass build using $OUTPUT_DIR and compare the
resulting outputs, either in build.sh or the package harness, while preserving
the existing configure, build, install, and recache steps.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/ghc/build.sh`:
- Around line 91-106: Update the build flow around the GHC configure, Hadrian
install, and package-cache recache commands to apply the standard
reproducible-build CFLAGS, CXXFLAGS, LDFLAGS, and ARFLAGS, enable deterministic
archives, and remove installed .la files as required by the package rules. Add
the required two-pass build using $OUTPUT_DIR and compare the resulting outputs,
either in build.sh or the package harness, while preserving the existing
configure, build, install, and recache steps.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9d8699c8-0db1-4b36-a436-7b5d90188fae

📥 Commits

Reviewing files that changed from the base of the PR and between 0ba5150 and 1e069e9.

📒 Files selected for processing (2)
  • packages/ghc/build.ncl
  • packages/ghc/build.sh
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ghc/build.ncl

bryan-minimal and others added 5 commits July 21, 2026 12:54
GHC 9.14.1 BUILT — ~111 minutes, clean. The bundle then failed in cabal:

  File "/build/update_bootstrap_json.py", line 7
  FileNotFoundError: 'bootstrap/linux-9.8.2.json'

cabal's bootstrap/ directory ships a fixed set of linux-<ghc>.json plans per
cabal RELEASE; it does not track the GHC we build with. cabal 3.18.1.0 ships
9.6.7 / 9.8.4 / 9.10.3 / 9.12.4 — the 9.8.2 named here existed only in older
cabals, so bumping cabal broke it via a bare FileNotFoundError out of our own
script.

Which plan matters less than it looks: update_bootstrap_json.py REPLACES the
`builtin` list with the real `ghc-pkg list` output, so the compiler-package
half adapts to whatever GHC is on PATH. The base plan supplies the
`dependencies`, so this takes the newest available (9.12.4).

Adds a guard that lists the plans cabal actually ships and says what to do,
because the failure mode is otherwise a Python traceback about a missing file
with no hint that the set is version-dependent. Fourth instance of this exact
shape in this package family today (ghc url, ghc sha256, ghc build.sh arg, now
this): a version hardcoded in one place while the thing it names moved.

Note packages/cabal/build.sh:31-32 still seds `Cabal-syntax ^>= 3.12.1.0`,
pinned to the OLD cabal. At 3.18.1.0 those patterns match nothing, so they are
silent no-ops rather than errors. Left alone deliberately — whether that
constraint relaxation is still needed is a question the build answers, and
changing two things at once would make the answer ambiguous.

GHC is now cached, so re-runs exercise cabal without repaying the ~2h compile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
With the base plan moved to cabal 3.18.1.0's linux-9.12.4.json, the
bootstrap got further and then failed configuring HTTP-4000.4.1:

  subprocess.CalledProcessError: [.../dists/HTTP-4000.4.1/setup/Setup]
      'configure' ...
  retry: 'bootstrap.py -w /usr/bin/ghc -d bootstrap/linux-actual.json'
      failed after 4 attempts

HTTP-4000.4.1 is not what the plan asks for — it is what WE pinned.

update_bootstrap_json.py carried ~12 hand-pinned versions + Hackage
hashes. They existed because the base plan was linux-9.8.2.json and its
dependencies really were too old for the GHC we build with (the original
comment says exactly that). Against a plan four GHC generations newer,
every one of them inverted into a DOWNGRADE, with stale hashes:

  HTTP              plan 4000.5.0 -> pinned 4000.4.1   <- the failure
  hashable          plan 1.5.1.0  -> pinned 1.4.7.0
  random            plan 1.3.1    -> pinned 1.2.1.2
  tar               plan 0.7.1.0  -> pinned 0.6.3.0
  splitmix          plan 0.1.3.2  -> pinned 0.1.1
  async, zlib, hackage-security   -> all older than the plan

So the version pins are gone. The plan that ships WITH a cabal release is
the set that release was tested against; re-deriving it by hand is how it
drifts, and it drifted silently the moment cabal moved. Anything actually
needed should now fail loudly rather than be pre-empted by a guess.

zlib's FLAGS survive, because they are not a version pin: they select the
system zlib over the copy bundled in the Haskell package, which is a
property of our sandbox rather than of any zlib version. The `builtin`
rewrite from `ghc-pkg list` is untouched — that is what adapts the plan
to whichever GHC is on PATH, and it is why the base plan's GHC version
matters less than its name suggests.

Verified offline against the real linux-9.12.4.json before spending
another ~5 min build: HTTP stays at 4000.5.0, zlib keeps its flags at the
plan's 0.7.1.1, and builtin still rewrites.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GHC 9.14.1 built cleanly (~111 min) and cabal 3.18.1.0 built after it.
tamarin-prover then could not resolve:

  rejecting: tagged-0.8.10  (lts-pinned.config requires ==0.8.9)
  rejecting: tagged-0.8.9   (conflict: template-haskell==2.24.0.0,
                             tagged => template-haskell >=2.11 && <2.24)

Not a packaging bug — ecosystem timing. tamarin pins Stackage
LTS 24.50, and:

  lts-24.51 (newest LTS)        -> ghc-9.10.3
  nightly-2026-07-21 (today)    -> ghc-9.12.4

NO Stackage snapshot supports GHC 9.14. Building tamarin against it means
hand-resolving aeson/tagged/wai-extra/yesod-static/fclabels ourselves,
i.e. maintaining a bespoke snapshot. Staying on LTS is the right call, and
LTS 24.51 is 9.10.3 — exactly what main already ships.

So ghc and ghc-bootstrap revert to main. The bundle keeps what does not
depend on the new compiler:

  cabal 3.18.1.0  (bootstrap plan retargeted to linux-9.10.3.json,
                   which cabal 3.18.1.0 ships)
  vim   9.2.0818

The cabal dep-pin removal stands: verified against the 9.10.3 plan, our
old hand-pins are still downgrades there (HTTP 4000.5.0 -> 4000.4.1,
hashable 1.5.1.0 -> 1.4.7.0, random 1.3.1 -> 1.2.1.2, tar 0.7.1.0 ->
0.6.3.0, splitmix 0.1.3.2 -> 0.1.1).

Work not wasted, just deferred: the libffi flag, the hadrian
bootstrap-sources glob, and the ghc-bootstrap 9.12.2 pairing are all
recorded in this PR's history and apply unchanged whenever GHC does move.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@bryan-minimal bryan-minimal changed the title Update stacked: ghc 9.14.1 + cabal 3.18.1.0 + vim (with matching bootstrap) Update stacked: cabal 3.18.1.0 + vim 9.2.0818 Jul 21, 2026
@twitchyliquid64
twitchyliquid64 added this pull request to the merge queue Jul 22, 2026
Merged via the queue into main with commit 817cf97 Jul 22, 2026
10 checks passed
@twitchyliquid64
twitchyliquid64 deleted the fix-ghc-bundle-bootstrap branch July 22, 2026 01:45
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