I use haskell to create a .so .but the .so needs too much depends.
How can i reduce the depends?
Hi! Are you trying to create a shared library that you can call from C or other languages? Are you using any specific build tools?
In case you were not already aware of this – you probably want to look at passing a combination of -shared
and -static
to GHC. There is some more information here.
I used the cable field :
foreign-library myforeignlib
type: native-shared
lib-version-info: 6:3:2
– options: standalone
– if os(Windows)
– options: standalone
– mod-def-file: MyForeignLib.def
other-modules: Account
, Server
, Types1
, DB1
build-depends:
base >=4.7 && <5
, bytestring >= 0.10
, aeson
, lens
, servant-server >= 0.14
, warp >= 3.2
, servant
, containers >= 0.5
, persistent
, persistent-sqlite
, persistent-template
random …
hs-source-dirs: src
c-sources: csrc/MyForeignLibWrapper.c
default-language: Haskell2010
default-extensions: DeriveDataTypeable
DeriveGeneric
GeneralizedNewtypeDeriving
StandaloneDeriving
FlexibleContexts
FlexibleInstances
MultiParamTypeClasses
FunctionalDependencies
Right, that looks more or less okay to me. However, it still isn’t clear to me:
.so
?There is a example:
I have a Foo.hs:
module Foo where
import Foreign.C
import Foreign
import Data.Char
foreign export ccall "testFunc" testFunc :: CString -> IO CString
testFunc :: CString -> IO CString
testFunc s = do
st <- peekCAString s
newCString $ map toUpper st
╭─hk@hk ~/test
╰─$ stack ghc -- -dynamic -shared -c Foo.hs -o libfoo.so
╭─hk@hk ~/test
╰─$ ls
Foo.hi Foo.hs Foo.o Foo_stub.h libfoo.so
╭─hk@hk ~/test
╰─$ ldd libfoo.so
linux-vdso.so.1 => (0x00007ffec23eb000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f9d1e13c000)
libHSbase-4.12.0.0-ghc8.6.5.so => /home/hk/.stack/programs/x86_64-linux/ghc-8.6.5/lib/ghc-8.6.5/base-4.12.0.0/libHSbase-4.12.0.0-ghc8.6.5.so (0x00007f9d1d7ae000)
libHSinteger-gmp-1.0.2.0-ghc8.6.5.so => /home/hk/.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-ghc8.6.5.so (0x00007f9d1e602000)
libHSghc-prim-0.5.3-ghc8.6.5.so => /home/hk/.stack/programs/x86_64-linux/ghc-8.6.5/lib/ghc-8.6.5/ghc-prim-0.5.3/libHSghc-prim-0.5.3-ghc8.6.5.so (0x00007f9d1d31f000)
libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007f9d1d09f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9d1ccd5000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9d1e445000)
╭─hk@hk ~/test
╰─$
How to reduce the depends:
libHSbase-4.12.0.0-ghc8.6.5.so => /home/hk/.stack/programs/x86_64-linux/ghc-8.6.5/lib/ghc-8.6.5/base-4.12.0.0/libHSbase-4.12.0.0-ghc8.6.5.so (0x00007f9d1d7ae000)
libHSinteger-gmp-1.0.2.0-ghc8.6.5.so => /home/hk/.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-ghc8.6.5.so (0x00007f9d1e602000)
libHSghc-prim-0.5.3-ghc8.6.5.so => /home/hk/.stack/programs/x86_64-linux/ghc-8.6.5/lib/ghc-8.6.5/ghc-prim-0.5.3/libHSghc-prim-0.5.3-ghc8.6.5.so (0x00007f9d1d31f000)
then, others can ues the shared library and don't install stack.
╭─hk@hk ~/test
╰─$ stack ghc -- -shared -c Foo.hs -o libfoo.so
or
╭─hk@hk ~/test
╰─$ stack ghc – -dynamic -shared -static -c Foo.hs -o libfoo.so
result is
…
/usr/bin/ld.gold: error: /home/hk/.stack/programs/x86_64-linux/ghc-8.6.5/lib/ghc-8.6.5/ghc-prim-0.5.3/libHSghc-prim-0.5.3.a(popcnt.o): requires unsupported dynamic reloc 11; recompile with -fPIC
/usr/bin/ld.gold: error: /home/hk/.stack/programs/x86_64-linux/ghc-8.6.5/lib/ghc-8.6.5/ghc-prim-0.5.3/libHSghc-prim-0.5.3.a(popcnt.o): requires unsupported dynamic reloc 11; recompile with -fPIC
/usr/bin/ld.gold: error: /home/hk/.stack/programs/x86_64-linux/ghc-8.6.5/lib/ghc-8.6.5/ghc-prim-0.5.3/libHSghc-prim-0.5.3.a(popcnt.o): requires unsupported dynamic reloc 11; recompile with -fPIC
collect2: error: ld returned 1 exit status
gcc' failed in phase
Linker’. (Exit code: 1)
Right, you would need to recompile all dependencies so they can be included this way, which may be pretty painful. As an alternative, I have often distributed Haskell libraries/executables together with their shared libraries in the past. If the user (or installer) sets LD_LIBRARY_PATH
correctly, is should be a pretty smooth process.