commercialhaskell / stack

The Haskell Tool Stack
http://haskellstack.org
BSD 3-Clause "New" or "Revised" License
4k stars 843 forks source link

Compile all dependencies with -fPIC for a statically linked foreign library #5458

Open apaszke opened 3 years ago

apaszke commented 3 years ago

Hi! I have a Haskell project that I'd like to redistribute as an .so library with a C interface, but without any assumptions on Haskell being installed on the user machine.

To get the .so I use a foreign-library declaration in my Cabal file. For as long as I'm ok with dynamically linking all my dependencies, Stack seems to correctly recognize the library and build it. (One annoyance is that it doesn't install it be default when running stack install, but I've worked around that).

However, that doesn't give me a self-contained library, because ldd prints a ton of Haskell shared libs when I query the artifact. To help with that I tried adding ghc-options: -static -optc-static -optl-static to my foreign-library target, but this results in a huge log of errors from the linker (a selection of messages below, they're all quite similar):

/usr/bin/ld.gold: error: /home/apaszke/.stack/snapshots/x86_64-linux/42bb23596753746b1bb05fcdf285ae58aeafdf21d8f4b6d2c2efb42533aaf2e9/8.6.5/lib/x86_64-linux-ghc-8.6.5/store-0.7.2-DiSfahOiFAkIMjYQUgof09/libHSstore-0.7.2-DiSfahOiFAkIMjYQUgof09.a(Internal.o): requires unsupported dynamic reloc 11; recompile with -fPIC
...
/usr/bin/ld.gold: error: /home/apaszke/.stack/programs/x86_64-linux/ghc-8.6.5/lib/ghc-8.6.5/integer-gmp-1.0.2.0/libHSinteger-gmp-1.0.2.0.a(Type.o): requires unsupported dynamic reloc 11; recompile with -fPIC
...

This seems to imply that all the static libraries stack produces are built without -fPIC, which makes sense because this is the default use case, but it completely breaks down for me. Is there any way to override this decision and have stack build both shared and static libraries with -fPIC (and have it apply to all GHC libraries, all my dependencies, and my project)?

qrilka commented 3 years ago

I don't have much experience in this area but I suppose that this section could be helpful to you.

apaszke commented 3 years ago

Thanks for the link! I've already seen it and I don't think that this is the same issue. Though from what I understand, some people on SO did have success with modifying the "C compiler flags" in the settings file to always include -fPIC. It just feels like a bit of a hack to me, but maybe that's the way to go about it.

mpilgrem commented 8 months ago

@apaszke, I wondered if what you needed was configuration option:

ghc-options:
  "$everything": -fPIC

but I do not know how that interacts with (a) GHC boot packages or (b) built packages already in the snapshot database.