I use haskell to create a .so .but the .so needs too much depends


#1

I use haskell to create a .so .but the .so needs too much depends.


How can i reduce the depends?


#2

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.


#3

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


#4

Right, that looks more or less okay to me. However, it still isn’t clear to me:

  1. What are you trying to build a shared library for? How do you want to call it?
  2. What is the issue with having dependencies? Do you just want less dependencies, or do you want to try and statically link the Haskell parts of the .so?

#5

Yes, I want to build a shared library.

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.

#6
╭─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 phaseLinker’. (Exit code: 1)


#7

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.