pkg-config linker flags are not passed to ghc --make, leading to loading errors in TH
- 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
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