Haskell与Ubuntu上的动态库链接

前端之家收集整理的这篇文章主要介绍了Haskell与Ubuntu上的动态库链接前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有问题链接到我们写的 Haskell图书馆.它在Ubuntu上出错,但不是Arch Linux. 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-link)@H_404_2@/usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so:未定义的引用“deepseqzm1zi3zi0zi0_ControlziDeepSeq_zdfNFDataArrayzuzdcrnf1_info”

这个问题似乎是由于libHScontainers-0.4.2.1-ghc7.4.1.so不正确地链接,可以看出ldd的输出:@H_404_2@ldd /usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so@H_404_2@linux-vdso.so.1 => (0x00007fffe95a2000)@H_404_2@libHSdeepseq-1.3.0.0-ghc7.4.1.so =>未找到@H_404_2@libHSbase-4.5.0.0-ghc7.4.1.so =>未找到@H_404_2@libHSghc-prim-0.2.0.0-ghc7.4.1.so =>未找到@H_404_2@libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0(0x00007f89a5a59000)@H_404_2@libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6(0x00007f89a569a000)@H_404_2@/lib64/ld-linux-x86-64.so.2(0x00007f89a5fd8000)

显然,找不到依赖库.已安装.但是,如果我在Arch上做同样的事情:@H_404_2@ldd /usr/lib/ghc-7.8.3/deepseq-1.3.0.2/libHSdeepseq-1.3.0.2-ghc7.8.3.so@H_404_2@linux-vdso.so.1(0x00007fff09dfe000)@H_404_2@libgmp.so.10 => /usr/lib/libgmp.so.10(0x00007fb8d3e96000)@H_404_2@libm.so.6 => /usr/lib/libm.so.6(0x00007fb8d3b91000)@H_404_2@librt.so.1 => /usr/lib/librt.so.1(0x00007fb8d3988000)@H_404_2@libdl.so.2 => /usr/lib/libdl.so.2(0x00007fb8d3784000)@H_404_2@libffi.so.6 => /usr/lib/libffi.so.6(0x00007fb8d357b000)@H_404_2@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)@H_404_2@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)@H_404_2@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)@H_404_2@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)@H_404_2@libc.so.6 => /usr/lib/libc.so.6(0x00007fb8d212c000)@H_404_2@libpthread.so.0 => /usr/lib/libpthread.so.0(0x00007fb8d1f10000)@H_404_2@/usr/lib64/ld-linux-x86-64.so.2(0x00007fb8d435f000)

找到这些库.

如我所建议的,我可以在Ubuntu中通过在应用程序中使用-rpath来解决这个问题,我们尝试链接到Haskell库.但这意味着我们必须为每个Haskell软件包这样做,这似乎对我来说是错误的.@H_404_2@我们还可以通过在/etc/ld.so.conf.d/ghc.conf中添加一行来解决这个问题.但是这也需要为每个包装完成,并且不是用户友好的.

我有几个问题:

>正确的解决方法是什么?@H_404_2@>为什么ghc-dynamic中的包不正确链接?@H_404_2@>为什么链接器可以找到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为条件.这就是为什么链接器可以找到那些,但不是它的传递依赖性(再次,我猜,这包括你的case中的deepseq).

那么为什么Arch Linux和Ubuntu之间的区别呢? (进一步推测)这是因为与Arch Linux不同,Ubunbu的链接器默认使用–as.你会看到,ghc将链接你的库与其所有的依赖关系(包括传递的),但链接器将省略其中的一些依赖关系,因为它不直接依赖它们.您可以通过重新链接–no-as-needed来验证这一点.

请注意,静态链接器的这些错误真的不是错误,但是警告:它试图解析符号,但它不能;但动态链接器将能够反正.所以你可以指示链接器忽略这些错误(–unresolved-symbols = ignore-all),一切都应该很好.

我一直在争取在Cabal中添加明确的支持生成用于C程序的Haskell库,并发现了同样的问题.详见https://github.com/haskell/cabal/pull/2540#issuecomment-95984067.

原文链接:https://www.f2er.com/ubuntu/347296.html

猜你在找的Ubuntu相关文章