http://www.vex.net/~trebla/haskell/so.xhtml描述了如何编译共享库。
关于编译命令:
ghc -O2 -dynamic -shared -fPIC -o libEval.so Eval.hs hsbracket.c -lHSrts-ghc7.6.3
它说:
(你能否省略-dynamic请求其他软件包的静态库?不是真的,它们不是用-fPIC生成的。特别是在x86_64上它是非法的。)
为什么会这样?如果没有libHS *依赖项,应该怎么做才能编译共享库?
答案 0 :(得分:10)
由于Kaiko私下与我联系以获得答案,不妨在此发布...
通过省略-dynamic,您将尝试获取所有静态.a库并将它们链接到一个大型.so文件中。那些。libs本身是在没有-fPIC的情况下构建的。最终在.so文件上的所有代码必须使用-fPIC构建(至少在ELF x86-64上)。因此,在这种情况下链接会失败,因为-fPIC是必需的,但是libs不是用-fPIC构建的。
在不同的建筑方式之间有一些不同的东西 静态和动态库:
原则上,这些东西的许多不同组合都是有意义的 但实际上只使用了少数。
在Linux(ELF)上,有两种构建库的标准方法, 完全静态和完全动态。在完全静态的方法答案 问题1,2,3上面是:.a存档,没有-fPIC,相同的DSO。在里面 完全动态的方法答案是:.so lib,-fPIC,外部DSO。
现在你想要做的是与众不同。您希望构建所有库 as .a文件,但是-fPIC和外部符号应该在 同样的DSO。然后,这将允许您将所有这些库链接到一起 一个巨大的共享库。所以关键的区别是使用-fPIC, 因为在ELF(特别是x86_64)代码中最终存在于共享库中 必须使用-fPIC构建。
相比之下,在Windows上,GHC可以完全按照你想要的方式进行链接 Haskell库(包括RTS等)成为一个庞大的共享库 (.dll文件)。这是因为在Windows上(与ELF不同),位置无关 代码没关系。所以在Windows上,一个人可以采取静态 库并将它们链接到一个大的共享库。
原则上,这应该也可以在Linux上实现,如果全部的话 Haskell库是静态构建的,但使用-fPIC。这不是 默认,这就是你不能省略-dynamic的直接原因 在这种情况下在Linux上。
原则上,人们可以尝试重建ghc和核心库 从源代码使用-fPIC标志,然后查看它是否可以省略 -dynamic并将所有内容链接到一个巨大的共享库中。
答案 1 :(得分:4)
是的,使用-fPIC进行编译有帮助。这是如何做到的。
ghc-7.8.4/mk/build.mk
:
SRC_HC_OPTS = -H64m -O
EXTRA_HC_OPTS = -fPIC
SRC_CC_OPTS = -fPIC -O
GhcStage1HcOpts = -fasm -O0
GhcStage2HcOpts = -fasm -O0
GhcLibHcOpts = -fasm -O2
GhcLibWays = v dyn
DYNAMIC_GHC_PROGRAMS = YES
DYNAMIC_BY_DEFAULT = NO
SplitObjs = NO
HADDOCK_DOCS = NO
BUILD_DOCBOOK_HTML = NO
BUILD_DOCBOOK_PS = NO
BUILD_DOCBOOK_PDF = NO
编译ghc:
export EXTRA_CONFIGURE_OPTS="--disable-library-profiling --enable-shared"
使用-fPIC构建cabal包:
cabal install --enable-shared --ghc-option=-fPIC text
测试文件foo.hs
(Data.Text用于查看cabal包是否也有效):
import Foreign.C as C
import Data.Text as T
import Data.Text.Foreign as T
foreign export ccall len :: CString -> IO CInt
len t = C.peekCString t >>= return . CInt . fromIntegral . T.length . T.pack
main = return ()
动态构建:
ghc -dynamic --make foo.hs
动态混合静态构建(不确定是否需要pthread,但它说明了如何添加动态链接):
ghc -fPIC -shared --make -o libfoo.so \
-optl-Wl,-Bstatic -lHSrts -lCffi \
-lHSbase-4.7.0.2 -lHSinteger-gmp-0.5.1.0 -lHSghc-prim-0.3.1.0 \
-optl-Wl,-Bdynamic -lpthread foo.hs