haskell / haskell/cabal

Cabal does not use the C toolchain GHC was configured with

Open
#12,332 0 comments 0 reactions 1 assignee Claimed by @zlonast View on GitHub
needs triage type: bug
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

**Describe the bug**
GHC carries its C toolchain in its settings file — the C compiler, the tool
that links object files together, `ar`, ... — chosen when GHC (or its
bindist) was configured. Cabal, however, configures its own toolchain
programs by searching the program search path (e.g. `PATH`) for well-known
names: GHC's settings are only used to derive the program *name* to search
for, and its directory. As a result the tools Cabal invokes can differ from
the tools GHC itself uses.

**To Reproduce**
Steps to reproduce the behavior:

Configure GHC with a non-default linker (e.g. `./configure
--with-ld=ld.lld ...`) and build any package with a library:

```
$ ghc --info | grep -E '"C compiler command"|"Merge objects command"'
,("C compiler command","/usr/bin/clang")
,("Merge objects command","/usr/bin/ld.lld")
$ cabal build -v2 --enable-library-for-ghci
...
Running: /usr/bin/ld --help
Running: /usr/bin/ld -x -r /tmp/cabal-1f3a5-5.o -o /tmp/cabal-1f3a5-6.o
Running: /usr/bin/ld -r -o dist/build/libHSpkg-0.1-inplace.o '@dist/tmp/ld.rsp'
```

Cabal probes and combines objects with `/usr/bin/ld` although GHC was
configured with `/usr/bin/ld.lld` — as `ghc --info` (what GHC actually
uses) shows.

**Expected behavior**

Once the compiler is configured, Cabal should obtain the tool locations
from `ghc --info` (`C compiler command`, `C++ compiler command`, `Merge
objects command`, `ar command`) and use exactly those tools when it invokes
the toolchain itself — for the C compiler used by hsc2hs and for
interpreting `cc-options`, for the `ar` invocation creating static
archives, and for the linker invocation combining object files into a
library for GHCi.

Overriding these defaults should keep working in the simple cases, where
the tool is looked up by name on the `PATH` and nothing else changes:

```console
# Use the clang on the PATH as the C compiler instead of the one GHC was
# configured with (GHC's own toolchain override):
$ cabal build --ghc-options="-pgmc clang"
# or
$ cabal build --ghc-options="-pgmcxx /usr/bin/g++"
```

Cabal's own invocations should follow the same choice as GHC's: e.g. when
the C compiler is overridden with `-pgmc`, hsc2hs should drive the same
compiler rather than the one from GHC's settings.

**System information**

- Operating system: any
- observed with GHC >= 9.10 (no `ld command` setting); the by-name lookup
of the C compiler and `ar` is affected on any GHC whose settings record
a tool that is not the `PATH` default
- `cabal` version: 3.x (current master)

**Additional context**

The relevant settings entries (see GHC's `compiler/GHC/Settings/IO.hs`):
`C compiler command`, `C++ compiler command`, `Merge objects command`,
`ar command`; note that GHC's linker *is* the C compiler (`as` and `ld` are
simply `gcc`/`clang`), and the plain `ld command` was dropped in GHC
9.10.1.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.