Skip to content

Simplify GHC packaging by extracting bootstrap and build tools - #203

Merged
0chroma merged 4 commits into
mainfrom
feature/simplify-ghc-cabal
Jun 8, 2026
Merged

Simplify GHC packaging by extracting bootstrap and build tools#203
0chroma merged 4 commits into
mainfrom
feature/simplify-ghc-cabal

Conversation

@0chroma

@0chroma 0chroma commented May 28, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR significantly simplifies the ghc package by extracting its inline bootstrap compiler and Haskell-based build tools (alex and happy) into their own dedicated, reusable packages.

Changes

  1. Created ghc-bootstrap (packages/ghc-bootstrap/build.ncl, packages/ghc-bootstrap/build.sh):
    • Packages the prebuilt GHC 9.8.1 binary for both x86_64 and aarch64 architectures.
    • Handles extraction, linking of libtinfo.so.6, and linker configuration in an isolated way.
  2. Created alex (packages/alex/build.ncl, packages/alex/build.sh):
    • Standalone package for the alex lexical analyzer generator, built from source using ghc-bootstrap.
  3. Created happy (packages/happy/build.ncl, packages/happy/build.sh):
    • Standalone package for the happy parser generator, built from source using ghc-bootstrap.
  4. Simplified ghc (packages/ghc/build.ncl, packages/ghc/build.sh):
    • Removed inline downloading and extraction of GHC 9.8.1 bootstrap binaries.
    • Removed inline source compilation of alex and happy.
    • Shrunk packages/ghc/build.sh from 130 lines to 63 lines.
    • The main ghc package now simply depends on ghc-bootstrap, alex, and happy as standard build dependencies.

Verification

  • Run min check --packages ghc-bootstrap,alex,happy,ghc to verify Nickel schemas and formatting.
  • Run min patched-build ghc-bootstrap to verify bootstrap compiler extraction and linking.
  • Run min patched-build alex and min patched-build happy to verify they compile successfully using ghc-bootstrap.

Summary by CodeRabbit

  • New Features

    • Added local build specs and build scripts to provide alex, happy, and a GHC bootstrap toolchain as build artifacts.
  • Refactor

    • GHC build now uses the local tooling and lightweight stubs instead of remote prebuilt archives, simplifying bootstrap and improving robustness (library handling and linker/configuration fixes).

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3d7eb980-6ddb-4780-ac6e-1acbdb015c34

📥 Commits

Reviewing files that changed from the base of the PR and between 7b17dd4 and 4ae6435.

📒 Files selected for processing (8)
  • packages/alex/build.ncl
  • packages/alex/build.sh
  • packages/ghc-bootstrap/build.ncl
  • packages/ghc-bootstrap/build.sh
  • packages/ghc/build.ncl
  • packages/ghc/build.sh
  • packages/happy/build.ncl
  • packages/happy/build.sh
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/happy/build.sh
  • packages/alex/build.sh
  • packages/ghc-bootstrap/build.ncl
  • packages/happy/build.ncl
  • packages/ghc-bootstrap/build.sh
  • packages/ghc/build.ncl
  • packages/alex/build.ncl
  • packages/ghc/build.sh

📝 Walkthrough

Walkthrough

This PR extracts alex, happy, and ghc-bootstrap as local build packages with Nickel specs and Bash build scripts, integrates them into packages/ghc build_deps, and refactors the GHC bootstrap script to use the available ghc from PATH with stubbed tools.

Changes

GHC Toolchain Refactor

Layer / File(s) Summary
alex BuildSpec and script
packages/alex/build.ncl, packages/alex/build.sh
Adds alex v3.5.1.0 build spec (Hackage source, sha256, build/runtime deps, output usr/bin/alex) and a Bash build script that compiles/uses Cabal Setup and stages outputs.
happy BuildSpec and script
packages/happy/build.ncl, packages/happy/build.sh
Adds happy v1.20.1.1 build spec (Hackage source, sha256, build/runtime deps, output usr/bin/happy) and a Bash build script that compiles/uses Cabal Setup and stages outputs.
ghc-bootstrap BuildSpec and script
packages/ghc-bootstrap/build.ncl, packages/ghc-bootstrap/build.sh
Adds ghc-bootstrap v9.8.1 spec selecting arch-specific tarball (extract=false), installs prebuilt GHC into $OUTPUT_DIR/usr, ensures libtinfo.so.6 via host curses lib discovery/copy, and patches GHC settings to avoid ld.gold.
GHC build spec imports and dependency wiring
packages/ghc/build.ncl
Imports alex, ghc-bootstrap, and happy as local build packages and replaces prior Hackage/prebuilt GHC entries in build_deps, retaining hadrian-bootstrap-sources and reordering dependencies.
GHC build script refactoring
packages/ghc/build.sh
Creates ../stub-bin with no-op cabal/sphinx-build, uses ghc from PATH for Hadrian bootstrap, updates pseudostore .so handling into LD_LIBRARY_PATH, passes GHC=ghc to configure, and fixes an unclosed if with fi.

Sequence Diagram(s)

sequenceDiagram
  participant GHC_build_sh as packages/ghc/build.sh
  participant GHC_bootstrap_sh as packages/ghc-bootstrap/build.sh
  participant Alex_build_sh as packages/alex/build.sh
  participant Happy_build_sh as packages/happy/build.sh

  GHC_build_sh->>GHC_bootstrap_sh: invoke ghc-bootstrap build (version via build_args)
  GHC_build_sh->>Alex_build_sh: invoke alex build (version via build_args)
  GHC_build_sh->>Happy_build_sh: invoke happy build (version via build_args)
  GHC_bootstrap_sh->>GHC_build_sh: install prebuilt GHC into $OUTPUT_DIR/usr and provide libtinfo
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • gominimal/pkgs#178: Overlapping changes to GHC bootstrap and build wiring (packages/ghc/build.ncl and packages/ghc/build.sh).

Suggested reviewers

  • twitchyliquid64

"🐰
I hop with a stub and a patch,
swapping tarballs for a local batch,
Alex and Happy spring to life,
bootstrap trimmed of extra strife,
building Haskell with a lighter hat."

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: extracting GHC bootstrap and build tools (ghc-bootstrap, alex, happy) into separate packages to simplify the main GHC package build spec, reducing its script from ~130 to 63 lines.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/simplify-ghc-cabal

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@0chroma
0chroma enabled auto-merge May 28, 2026 06:28

@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.

Actionable comments posted: 6

🤖 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.

Inline comments:
In `@packages/alex/build.sh`:
- Around line 1-12: The build script must change into the extracted, versioned
source directory before building and reference the version variable; update the
top of the script to cd into the directory named by $MINIMAL_ARG_VERSION (e.g.,
cd "${MINIMAL_ARG_VERSION}" or cd "$MINIMAL_ARG_VERSION") before invoking ghc
and the ./Setup commands (Setup.hs, ghc --make Setup.hs, ./Setup
configure/build/copy), ensuring $OUTPUT_DIR is still used for copy destdir.
- Around line 4-10: The build script always compiles "Setup.hs" even when only
"Setup.lhs" exists; update the logic to select the existing setup file and
compile that instead (e.g., determine a SETUP_FILE variable that is "Setup.hs"
if present, otherwise "Setup.lhs", and use that variable in the ghc --make and
./Setup commands). Ensure references to Setup.hs in the compile and run steps
are replaced by this selected setup filename so the path where only Setup.lhs is
provided succeeds.

In `@packages/ghc-bootstrap/build.sh`:
- Around line 27-35: The script hardcodes /usr/lib/libncursesw.so.6 when
creating the libtinfo.so.6 shim; update it to locate the real ncurses library
(search /usr/lib* and /usr/lib64 or use ldconfig -p/grep or gcc
-print-file-name) into a variable (e.g., NCURSES_PATH) and use that variable
when copying to "$OUTPUT_DIR/usr/lib/libtinfo.so.6" and to
"$GHC_LIB_DIR/libtinfo.so.6"; if no library is found, emit a clear error and
exit non‑zero. Ensure you reference OUTPUT_DIR, GHC_LIB_DIR and
MINIMAL_ARG_VERSION and replace the two cp -p /usr/lib/libncursesw.so.6
occurrences with cp -p "$NCURSES_PATH" ... .

In `@packages/ghc/build.sh`:
- Around line 42-46: The current export of LD_LIBRARY_PATH can produce a
trailing colon when LD_LIBRARY_PATH is unset, causing ld.so to treat it as the
current directory; update the export that sets LD_LIBRARY_PATH (the line using
PSEUDO_LIBS and export LD_LIBRARY_PATH) so it only inserts a ':' between
PSEUDO_LIBS and the existing LD_LIBRARY_PATH when LD_LIBRARY_PATH is non-empty
(i.e., append the old value conditionally via parameter expansion or an
if-check), ensuring no trailing empty entry is added.

In `@packages/happy/build.sh`:
- Around line 1-12: The build script doesn't cd into the extracted versioned
source directory nor reference the MINIMAL_ARG_VERSION variable; update
packages/happy/build.sh to first change directory into the extracted source
(e.g. cd "happy-$MINIMAL_ARG_VERSION" or whichever directory name pattern is
used) before running ghc and ./Setup commands, and replace any hardcoded paths
(if present) with references that use $MINIMAL_ARG_VERSION and keep OUTPUT_DIR
usage for copy/destdir; ensure the cd happens before checking/creating Setup.hs
and before running ghc and ./Setup configure/build/copy.
- Around line 4-10: The build script assumes Setup.hs is present when running
GHC; change the compile step to pick the existing setup file dynamically so
Setup.lhs is handled too: after the block that creates Setup.hs only when
neither file exists, invoke GHC with the actual setup filename (use Setup.lhs if
it exists, otherwise Setup.hs) for the "ghc --make" step, then continue to run
the generated ./Setup configure --prefix=/usr; update the reference to the
compiled filename in the subsequent commands to match the chosen source
(Setup.lhs or Setup.hs).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: bbb8e42f-b3de-44f1-b199-9d03f99c6dec

📥 Commits

Reviewing files that changed from the base of the PR and between 3ae4553 and cff927a.

📒 Files selected for processing (8)
  • packages/alex/build.ncl
  • packages/alex/build.sh
  • packages/ghc-bootstrap/build.ncl
  • packages/ghc-bootstrap/build.sh
  • packages/ghc/build.ncl
  • packages/ghc/build.sh
  • packages/happy/build.ncl
  • packages/happy/build.sh

Comment thread packages/alex/build.sh
Comment thread packages/alex/build.sh Outdated
Comment thread packages/ghc-bootstrap/build.sh Outdated
Comment thread packages/ghc/build.sh
Comment thread packages/happy/build.sh Outdated
Comment thread packages/happy/build.sh Outdated
@0chroma

0chroma commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

/build

@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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@packages/ghc-bootstrap/build.sh`:
- Around line 58-68: The ldconfig pipeline in the NCURSES_PATH fallback can
cause the script to abort under set -euo pipefail; modify the assignment to
LDCONFIG_PATH so pipeline failures don't propagate (e.g. replace the pipeline
with a single awk that matches and exits: ldconfig -p | awk
'/libncursesw.so.6|libncurses.so.6/ {print $NF; exit}' or append "|| true" to
the command substitution), ensuring LDCONFIG_PATH becomes empty on no-match and
lets the subsequent if [ -f "$LDCONFIG_PATH" ] check run; update the block that
sets NCURSES_PATH from LDCONFIG_PATH accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f1f448cc-0e6e-401d-ae99-83d1d19f8c27

📥 Commits

Reviewing files that changed from the base of the PR and between cff927a and 7b17dd4.

📒 Files selected for processing (7)
  • packages/alex/build.ncl
  • packages/alex/build.sh
  • packages/ghc-bootstrap/build.ncl
  • packages/ghc-bootstrap/build.sh
  • packages/ghc/build.sh
  • packages/happy/build.ncl
  • packages/happy/build.sh
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/alex/build.ncl
  • packages/ghc-bootstrap/build.ncl
  • packages/alex/build.sh

Comment thread packages/ghc-bootstrap/build.sh
@0chroma

0chroma commented May 30, 2026

Copy link
Copy Markdown
Contributor Author

/build

auto-merge was automatically disabled May 30, 2026 04:55

Pull request was closed

@bryan-minimal bryan-minimal reopened this May 30, 2026
@bryan-minimal

Copy link
Copy Markdown
Member

Hey @0chroma — good news, this is building now ✅

The minimal build check had gotten stuck on "Awaiting maintainer approval" after a buildbot restart caught it mid-flight (the build had actually already passed). I re-triggered it and it's running fresh now — it'll go green on its own shortly.

Two small things to get it merge-ready once it's green:

  • Rebase on main — the branch is a little behind.
  • It'll need one approving review.

Thanks for the GHC packaging cleanup! 🙌

@0chroma
0chroma enabled auto-merge June 1, 2026 07:50
@0chroma
0chroma force-pushed the feature/simplify-ghc-cabal branch from 7b17dd4 to 4ae6435 Compare June 1, 2026 07:55

@bryan-minimal bryan-minimal left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@0chroma
0chroma added this pull request to the merge queue Jun 8, 2026
Merged via the queue into main with commit 5aea725 Jun 8, 2026
4 checks passed
@0chroma
0chroma deleted the feature/simplify-ghc-cabal branch June 8, 2026 18:04
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.

3 participants