Skip to content

Try target-prefixed ghc-pkg first in guessToolFromGhcPath#361

Open
angerman wants to merge 124 commits into
stable-haskell:stable-haskell/masterfrom
angerman:fix/target-prefix-aware-tool-guess
Open

Try target-prefixed ghc-pkg first in guessToolFromGhcPath#361
angerman wants to merge 124 commits into
stable-haskell:stable-haskell/masterfrom
angerman:fix/target-prefix-aware-tool-guess

Conversation

@angerman

Copy link
Copy Markdown

Problem

For cross-compiler bindists where the ghc binary is target-prefixed
(e.g. wasm32-unknown-wasi-ghc, javascript-unknown-ghcjs), the
companion tool typically uses the same prefix
(wasm32-unknown-wasi-ghc-pkg). The existing
guessToolFromGhcPath logic only tries the bare tool name
(ghc-pkg), falls back to PATH when not found, and ends up picking
the BUILD compiler's ghc-pkg from PATH — leading to
"Version mismatch between ghc and ghc-pkg" at dual-compiler
configure time.

This was hit immediately when wiring up the stable-haskell wasm
cross-compiler in a Stage/Toolchain dual-compiler cabal build:

Error: [Cabal-4000]
Version mismatch between ghc and ghc-pkg:
  /…/wasm32-wasi-9.14.0.stable.0/bin/wasm32-unknown-wasi-ghc is version 9.14
  /nix/store/…/ghc-9.8.4/bin/ghc-pkg is version 9.8.4

Fix

Detect the target prefix on the ghc binary (strip the
ghc<versionSuffix> tail from takeBaseName p) and prepend it to
the toolname as the first guess. Falls back to existing logic when no
prefix is detected (i.e. for bare ghc binaries).

Concrete example:

  given_path  = \"/opt/ghc-wasm/bin/wasm32-unknown-wasi-ghc\"
  given_suf   = \"\"                              -- no -X.Y.Z version suffix
  given_prefix = Just \"wasm32-unknown-wasi-\"
  guesses     = [ \"/opt/ghc-wasm/bin/wasm32-unknown-wasi-ghc-pkg\"  -- new
                , \"/opt/ghc-wasm/bin/ghc-pkg\"
                ]

Uses isSuffixOf + take instead of Data.List.stripSuffix for
base-4.19 compatibility (stripSuffix only entered Data.List in
base-4.20).

Test plan

  • Bootstrap rebuild of cabal-install against ghc-9.8.4 (devx)
  • End-to-end dual-compiler `cabal build test-app` on a wasm
    cross-compile project where with-compiler points at
    `wasm32-unknown-wasi-ghc` — produces a valid WebAssembly MVP
    wasm binary (1.7 MB). Without this patch, the same project
    fails at configure with "Version mismatch between ghc and
    ghc-pkg".

Related

- Remove QualifiyOptions

Remove QualifyOptions by setting qoSetupIndependent to be always true (the
current default) and qoBaseShim false (this must have been just a hack of some
sort).
…ry, pkgsUseProfilingLibrary, pkgsUseProfilingLibraryShared

We do not want to check the compiler.
…antiatedWith from ElaboratedConfiguredPackage to ElaboratedComponent

Instantiation only makes sense for components.
…g jsem

This is a user problem. User should not enable jsem on a compiler that does not support it.

This change also avoid us to pass the compiler all the way down.

A better approach to restore this functionality would be to defer the application of the parallel strategy.
Merge fromSolverInstallPlan and fromSolverInstallPlanWithProgress.
andreabedini and others added 26 commits May 7, 2026 16:28
This reverts commit 5573dea.
This reverts commit 7c1cd10.
Restore the file monitor mechanism to track already-built packages,
using the same approach previously established for in-place builds.
This also replaces `phaseImprovePlan`, which improved the elaborated
plan by matching source packages against installed store entries.

Key changes:
- Restore file monitor updates in `buildAndInstallUnpackedPackage`:
  source files, inplace dependency build cache files, and registration
- Simplify `BuildStatusBuild` by dropping the `Maybe InstalledPackageInfo`
  field, which is now tracked via the registration file monitor instead
- Simplify `checkPackageFileMonitorChanged` accordingly
- Remove `phaseImprovePlan` and store entry matching from the plan
  rebuild phase; `rebuildInstallPlan` now returns a 4-tuple instead of 5
…race

When two stages of the same package (e.g. build: and host: in cross-
compilation) are scheduled concurrently, both threads can observe the
unpacked source directory as non-existent and race to extract the
tarball. The second extraction overwrites the first mid-flight,
corrupting the result and causing intermittent "No cabal file found"
errors.

Add an unpackLock (using the existing Lock/criticalSection from
JobControl) to serialise the doesDirectoryExist check and tarball
extraction in withTarballLocalDirectory. This is the same pattern
already used for registerLock and cacheLock.
CompilerFlavor no longer has a GHCJS constructor and
Distribution.Simple.GHCJS module no longer exists in
stable-haskell/cabal. These imports + pattern were left
behind from incomplete GHCJS removal. Removing them lets
cabal-install bootstrap with GHC 9.8.4.

Local fix for stable-haskell/ghc#wasm-cross-ghcup. Should
be upstreamed to stable-haskell/cabal#stable-haskell/master.
binDirectoryFor was renamed/refactored to binDirectories (in
ProjectPlanning.hs) with a different signature. The call site
at ProjectOrchestration.hs:544 wasn't updated. Use elabBinDir
directly — same value that binDirectories ultimately returns
(see ProjectPlanning/Types.hs:496-497, 503).
For cross-compiler bindists where the ghc binary is target-prefixed
(e.g. `wasm32-unknown-wasi-ghc`, `javascript-unknown-ghcjs`), the
companion tool typically uses the same prefix
(`wasm32-unknown-wasi-ghc-pkg`). The existing logic only tries the
bare tool name (`ghc-pkg`), falls back to PATH when not found, and
ends up picking the BUILD compiler's ghc-pkg from PATH — leading to
"Version mismatch between ghc and ghc-pkg" at configure time.

Detect the target prefix on the ghc binary (strip the
`ghc<versionSuffix>` tail from `takeBaseName p`) and prepend it to
the toolname as the first guess. Falls back to existing logic when no
prefix is detected (i.e. for bare `ghc` binaries).

Concrete example:
  given_path = "/opt/ghc-wasm/bin/wasm32-unknown-wasi-ghc"
  given_suf  = ""  (no -X.Y.Z version suffix)
  given_prefix = Just "wasm32-unknown-wasi-"
  guesses = [ "/opt/ghc-wasm/bin/wasm32-unknown-wasi-ghc-pkg"  <-- new
            , "/opt/ghc-wasm/bin/ghc-pkg"
            ]

Uses `isSuffixOf` + `take` instead of `Data.List.stripSuffix` for
base-4.19 compatibility (stripSuffix only entered Data.List in
base-4.20).
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