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):
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 functionf
from moduleM
. - Because
f
may use foreign library code. Example: You call, at compile time, a functionf = generatePNG
that calls some C functiongenPNG()
fromlibpng
. - Because it wants to make the above possible, the GHCi that does TH evaluation will load all
-l
libraries from the-L
paths when loadingM
.
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 )
<no location info>: 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.
Activity