Haskell与Ubuntu上的动态库链接
我在链接到我们编写的Haskell库时遇到问题。它在Ubuntu上出错,但在ArchLinux上没有。我们在Ubuntu上得到的错误是:Haskell与Ubuntu上的动态库链接,haskell,ubuntu,linker,Haskell,Ubuntu,Linker,我在链接到我们编写的Haskell库时遇到问题。它在Ubuntu上出错,但在ArchLinux上没有。我们在Ubuntu上得到的错误是: /usr/bin/ld:warning:libHSdeepseq-1.3.0.0-ghc7.4.1.so,/usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so所需,未找到(请尝试使用-rpath或-rpath链接) /usr/lib/ghc/containers-0.4.2.1/
/usr/bin/ld:warning:libHSdeepseq-1.3.0.0-ghc7.4.1.so,/usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so所需,未找到(请尝试使用-rpath或-rpath链接)
/usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so:未定义对“DeepSeqZm1Zi3Zi0Zi0Zi0Zi0Zi0Zi0ZiepSeq\u ZDFNFNFNDatararyZIDCRNF1\u信息”的引用。
问题似乎是由以下事实引起的:libHScontainers-0.4.2.1-ghc7.4.1。因此,ldd的输出可以看出,链接不正确:
ldd/usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so
linux vdso.so.1=>(0x00007fffe95a2000)
libHSdeepseq-1.3.0.0-ghc7.4.1.so=>未找到
libHSbase-4.5.0.0-ghc7.4.1.so=>未找到
libHSghc-prim-0.2.0.0-ghc7.4.1.so=>未找到
libpthread.so.0=>/lib/x86_64-linux-gnu/libpthread.so.0(0x00007F89A59000)
libc.so.6=>/lib/x86_64-linux-gnu/libc.so.6(0x00007f89a569a000)
/lib64/ld-linux-x86-64.so.2(0x00007f89a5fd8000)
显然,无法找到依赖库。它们已安装。但是,如果我在Arch上也这样做:
ldd/usr/lib/ghc-7.8.3/deepseq-1.3.0.2/libHSdeepseq-1.3.0.2-ghc7.8.3.so
linux vdso.so.1(0x00007fff09dfe000)
libgmp.so.10=>/usr/lib/libgmp.so.10(0x00007fb8d3e96000)
libm.so.6=>/usr/lib/libm.so.6(0x00007fb8d3b91000)
librt.so.1=>/usr/lib/librt.so.1(0x00007fb8d3988000)
libdl.so.2=>/usr/lib/libdl.so.2(0x00007fb8d3784000)
libffi.so.6=>/usr/lib/libffi.so.6(0x00007fb8d357b000)
libHSarray-0.5.0.0-ghc7.8.3.so=>/usr/lib/ghc-7.8.3/deepseq-1.3.0.2/。/array-0.5.0.0/libHSarray-0.5.0.0-ghc7.8.3.so(0x00007fb8d32e1000)
libHSbase-4.7.0.1-ghc7.8.3.so=>/usr/lib/ghc-7.8.3/deepseq-1.3.0.2/。/base-4.7.0.1/libHSbase-4.7.0.1-ghc7.8.3.so(0x00007fb8d2967000)
libHSinteger-gmp-0.5.1.0-ghc7.8.3.so=>/usr/lib/ghc-7.8.3/deepseq-1.3.0.2/。/integer-gmp-0.5.1.0/libHSinteger-gmp-0.5.1.0-ghc7.8.3.so(0x00007fb8d274c000)
libHSghc-prim-0.3.1.0-ghc7.8.3.so=>/usr/lib/ghc-7.8.3/deepseq-1.3.0.2/。/ghc-prim-0.3.1.0/libHSghc-prim-0.3.1.0-ghc7.8.3.so(0x00007fb8d24cf000)
libc.so.6=>/usr/lib/libc.so.6(0x00007fb8d212c000)
libpthread.so.0=>/usr/lib/libpthread.so.0(0x00007fb8d1f10000)
/usr/lib64/ld-linux-x86-64.so.2(0x00007fb8d435f000)
可以找到这些库
正如建议的那样,我可以在Ubuntu上通过在我们试图链接到Haskell库的应用程序中使用-rpath来解决这个问题。但这意味着我们必须为每个Haskell包这样做,这在我看来是错误的。
我们还可以通过在/etc/ld.so.conf.d/ghc.conf
中添加一行来解决这个问题。但是,这也必须为每个包完成,并且不是用户友好的
我有几个问题:
- 解决这个问题的正确方法是什么
- 为什么
ghc dynamic
中的包链接不正确
- 为什么链接器能够找到
libHScontainers-0.4.2.1-ghc7.4.1.so
而不能找到libHSdeepseq-1.3.0.0-ghc7.4.1.so
我强烈怀疑这是因为ghc安装的Haskell库具有其依赖项的位置(ELF头的RPATH
字段;您可以使用readelf-d
)根据$ORIGIN
定义进行验证。当库X依赖于库Y时,库X可以使用$ORIGIN
指示库Y应位于相对于其自身位置的位置。动态链接器支持此功能,但静态链接器不支持此功能
(我在这里推测:)您的库将根据其自身的RPATH
(而不是$ORIGIN
)定义其直接依赖项的位置(在您的情况下,我猜,这包括容器
)。这就是为什么链接器可以找到这些,但不能找到它的可传递依赖项(我猜,在您的例子中,这包括deepseq
)
那么,为什么ArchLinux和Ubuntu之间存在差异呢?(进一步推测)这是因为与Arch Linux不同,Ubunbu的链接器默认使用——根据需要使用。您可以看到,ghc
将根据库的所有依赖项(包括可传递的依赖项)链接库,但是链接器将忽略其中一些依赖项,因为它不直接依赖它们。您可以根据需要使用--no重新链接来验证这一点
请注意,静态链接器的这些错误实际上不是错误,而是警告:它试图解析符号,但无法解析;但是动态链接器无论如何都可以。因此,您可以指示链接器忽略这些错误(--unresolved symbols=ignore all
),一切都应该正常
我一直在努力在Cabal
中添加显式支持,以生成用于C程序的Haskell库,并发现了同样的问题。有关详细信息,请参阅 您是否通过apt get
安装了一些ghc库,以及通过cabal install
安装了其他ghc库?没有,我只安装了ghc dynamic。cabal安装时未安装任何软件包。