Haskell与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/

我在链接到我们编写的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/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安装时未安装任何软件包。