Skip to content

fix(Cabal): Use the C toolchain GHC was configured with - #12333

Open
zlonast wants to merge 4 commits into
haskell:masterfrom
zlonast:zlonast/use-ghc-toolchain
Open

zlonast wants to merge 4 commits into
haskell:masterfrom
zlonast:zlonast/use-ghc-toolchain

Conversation

@zlonast

@zlonast zlonast commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

Fix: #12332

Cabal now asks GHC what toolchain it was configured with (via ghc --info, i.e. the settings file chosen when GHC or its bindist was configured)


Template Α: This PR modifies behaviour or interface

Include the following checklist in your PR:

QA Notes

Prerequisite: check what your GHC records in its settings — ghc --info | grep -E '"C compiler command"|"ld command"|"ar command"'. The two kinds of setups are covered below.

1. GHC records absolute tool paths (official bindists; e.g. the Windows ghcup bindist records C:\ghcup\ghc\<version>\lib\..\mingw\bin\clang.exe):

  • cabal build -v2 of a package with c-sources should compile the C file with -pgmc <exact path from "C compiler command"> and create the static archive with the exact "ar command" (e.g. llvm-ar);
  • a like-named executable placed earlier on the PATH (e.g. a gcc script in ~/bin) must not change which compiler gets invoked.

2. GHC records bare tool names (e.g. --enable-distro-toolchain builds, ghcup source installs — "C compiler command","gcc"):

  • cabal build -v2 should resolve the tools from the PATH, as GHC itself does: e.g. -pgmc /usr/bin/gcc;
  • an unrelated executable called gcc sitting in the project directory must NOT be picked up: current master prints Running: ./gcc -dumpversion and passes -pgmc ./gcc to GHC; with this PR those invocations are gone (this is the behaviour change recorded in the changelog).

3. User overrides keep winning: cabal build --with-gcc=<wrapper> (see PackageTests/WithGcc) still drives the C compilation with <wrapper>.

hsc2hs, ar and strip are exercised by the above: they now receive the exact settings tool (or the PATH fallback) instead of a like-named lookup.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Merge-tool metadata and compiler overrides are not propagated consistently, and key tool-selection paths remain untested.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Updates Cabal to resolve C toolchain programs from GHC’s reported configuration.

Changes:

  • Uses absolute tool paths from ghc --info.
  • Preserves search-path and user-location fallbacks.
  • Adds a toolchain integration test and changelog entry.
File summaries
File Description
changelog.d/12333.md Documents the toolchain behavior change.
Cabal/src/Distribution/Simple/GHC/Internal.hs Resolves configured compiler and binutils paths.
cabal-testsuite/PackageTests/GhcConfiguredToolchain/cabal.test.hs Tests configured C compiler selection.
cabal-testsuite/PackageTests/GhcConfiguredToolchain/ghc-toolchain.cabal Defines the test package.
cabal-testsuite/PackageTests/GhcConfiguredToolchain/cabal.project Configures the test project.
cabal-testsuite/PackageTests/GhcConfiguredToolchain/src/Lib.hs Exposes the test C function.
cabal-testsuite/PackageTests/GhcConfiguredToolchain/cbits/clib.c Implements the test C function.
cabal-testsuite/PackageTests/GhcConfiguredToolchain/app/Main.hs Runs the test executable.
Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 3
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Cabal/src/Distribution/Simple/GHC/Internal.hs Outdated
Comment thread Cabal/src/Distribution/Simple/GHC/Internal.hs Outdated
Comment thread cabal-testsuite/PackageTests/GhcConfiguredToolchain/cabal.test.hs Outdated

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

Thanks. The diagnosis in #12332 is right for GHC >= 9.10, but I don't think this is the fix.

The only thing we do with ld is ld -r for the GHCi object, and since 9.4 ghc --merge-objs does that with GHC's own tool and flags. GHC#20712 added it so Cabal could drop this code, and #9226 already does the Cabal side. It stalled on a Windows discussion that I don't think blocks it (GHC falls back to ar when no merge tool is configured, and we disable GHCi libs there anyway). Every GHC affected here has --merge-objs.

So for ld I'd revive #9226 rather than teach configureToolchain about Merge objects command. That also kills the -x probe (#10970). Happy to review a rebase. If you want the two-line stopgap first, fine, but title and changelog should say just that.

For the other tools this is nearly a no-op: we already searched the directory from ghc --info first. What changes is that a missing absolute path is now used blindly, and that bare names no longer put . on the search path (takeDirectory "gcc" == "."). The latter is worth a changelog line; the rest I'd drop or restructure (inline).

Also: the -pgmc-to-hsc2hs part of #12332 isn't addressed, and this needs squash+merge me.

PS: I revived #9226 as #12358. I think that is the correct solution.

Comment thread Cabal/src/Distribution/Simple/GHC/Internal.hs Outdated
Comment thread Cabal/src/Distribution/Simple/GHC/Internal.hs Outdated
Comment thread cabal-testsuite/PackageTests/GhcConfiguredToolchain/cabal.test.hs Outdated
andreabedini and others added 3 commits September 15, 2026 14:11
Add GhcFeature: each constructor names the flag whose presence in
`ghc --show-options` signals it. Configuring ghc queries once and records
the answers as program properties; ghcSupports reads them back. This is
detection by capability rather than by version, unlike GhcImplInfo.

First feature: the --merge-objs mode (GHC >= 9.4). Add the matching
GhcMode too.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
We used to run `ld -r` ourselves, finding ld from the ghc settings and
probing it for -r and -x. When ghc has --merge-objs, let it do the
merging: it uses the tool and flags it was configured with and handles
long argument lists. Whether a GHCi library can be built at all then
follows from "Merge objects command" being set, not from probing
`ld --help`. GHCs without --merge-objs keep the ld path.

Revives haskell#9226 with feature detection instead of a version gate.
Refs haskell#7828, haskell#9301, haskell#12332.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
With --merge-objs we never run ld, so skip the two probes at configure
time: compiling a C file through ghc to test `ld -x` (not always
possible, see haskell#10970) and `ld --help` for relocatable output.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@zlonast
zlonast force-pushed the zlonast/use-ghc-toolchain branch from 9d39415 to 2f7a3c8 Compare September 15, 2026 14:43

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

I think the actual bug is the . that mkExtraPath puts on the search path for bare names. It should never happen. If a program is mentioned just by its name, it has to be looked up on the PATH.

I'd cut this PR down to that: add the settings directory only when the command is absolute, keep findProg as it was, and replace the test with your reproducer from the issue.

I don't think using absolute paths verbatim has anything to do with the issue. master already finds the same file, and the this version would return something different only when the settings point at a path that no longer exists. I would drop this bit from the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cabal does not use the C toolchain GHC was configured with

3 participants