haskell / haskell/cabal

pkg-config linker flags are not passed to ghc --make, leading to loading errors in TH

Open
#7,082 2 comments 0 reactions 0 assignees View on GitHub
attention: pr-welcome re: pkg-config
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

When you use `pkgconfig-depends`, Cabal determines `-I`, `-L` and `-l` flags.

Of those, only the `includDirs` are passed to `ghc --make` here (and related code below it):

https://github.com/haskell/cabal/blob/09db4dc416c2ed5dd3e6fd4d38afa1db928f0a85/Cabal/src/Distribution/Simple/GHC/Internal.hs#L283

I believe that is insufficient, and the `-L` and `-l` flags need to be passed.

The reason:

* When compiling a module, you can use TemplateHaskell (TH) to call, at compile time, any code you've `import`ed. For example function `f` from module `M`.
* Because `f` may use foreign library code. Example: You call, at compile time, a function `f = generatePNG` that calls some C function `genPNG()` from `libpng`.
* Because it wants to make the above possible, the GHCi that does TH evaluation will load all `-l` libraries from the `-L` paths when loading `M`.

Because `-l`/`-L` are not passed to `ghc --make`, you'll get an error like this:

```
[238 of 255] Compiling MyModule ( MyModule.hs, dist/build/MyModule.o )

: error:
ghc: panic! (the 'impossible' happened)
(GHC version 8.6.5 for x86_64-unknown-linux):
Loading temp shared object failed: /run/user/1000/ghc20683_0/libghc_47.so: undefined symbol: genPNG
```

Tragically, you get this error even if you don't make any use of that foreign code at compile time (e.g. you never need `generatePNG` at compile time, but only at run time), simply because GHC will try to satisfy all symbols when loading `M`, and then fail.

## Current workaround

Set `ghc-options: -L/path/to/mylib -lmylib` in your cabal file, _in addition_ to `pkgconfig-depends: mylib`.

This is bad, because you need to hardcode `-L/path/to/mylib`, and it varies across Linux distributions

## Proposed solution

Pass the `pkg-config`-determined `-L` and `-l` flags to GHC, in the same way as we do it with `-I` flags.

Contributor guide

Open the contributing guide

Research direction

Start at Cabal/src/Distribution/Simple/GHC/Internal.hs around the linked line and inspect the related code that passes pkg-config include flags to ghc --make. Reproduce the TemplateHaskell loading failure with a pkgconfig-depends foreign library, then verify that the determined -L and -l flags are passed and the loading error is resolved.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
build-system
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.