Skip to content

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

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
nh2 opened this issue Sep 21, 2020 · 2 comments
Labels
attention: pr-welcome re: pkg-config Concerning pkg-config and pkgconfig-depends constraints

Comments

@nh2
Copy link
Member

nh2 commented Sep 21, 2020

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 imported. 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 )

<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.

@bqv
Copy link

bqv commented Nov 4, 2020

+1, I seem to be seeing this too, and the workaround does fix it.

Edit: For those interating on nixos or using a nix shell, since those paths are not even remotely constant, you might do as I did and define the CABAL_CONFIG env var in your shell derivation to be:

pkgs.writeText "config" ''
  program-default-options
    ghc-options: -L${lib.getLib <yourlibrary>} -l<yourlib>
'';

@dminuoso
Copy link

dminuoso commented Nov 4, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
attention: pr-welcome re: pkg-config Concerning pkg-config and pkgconfig-depends constraints
Projects
None yet
Development

No branches or pull requests

5 participants