mei*_*juh 10 ubuntu linker haskell
我遇到了链接到我们编写的Haskell库的问题.它在Ubuntu上出错,但在Arch Linux上却没有.我们得到的Ubuntu错误是这样的:
/usr/bin/ld: warning: libHSdeepseq-1.3.0.0-ghc7.4.1.so, needed by /usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so, not found (try using -rpath or -rpath-link)
/usr/lib/ghc/containers-0.4.2.1/libHScontainers-0.4.2.1-ghc7.4.1.so: undefined reference to 'deepseqzm1zi3zi0zi0_ControlziDeepSeq_zdfNFDataArrayzuzdcrnf1_info'
这个问题似乎是由于libHScontainers-0.4.2.1-ghc7.4.1.so
错误链接的事实导致的,因为输出可以看到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 => not found
libHSbase-4.5.0.0-ghc7.4.1.so => not found
libHSghc-prim-0.2.0.0-ghc7.4.1.so => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f89a5a59000)
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)
找到了这些图书馆.
正如所建议的,我可以在我们尝试链接到Haskell库的应用程序中使用-rpath在Ubuntu上解决这个问题.但这意味着我们必须为每个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 库RPATH
具有readelf -d
根据$ORIGIN
. 当库X依赖于库Y时,库X可以使用指示应在相对于其自身位置的位置中找到库Y。$ORIGIN
这是动态链接器支持的,但静态链接器不支持。
(我在这里推测:)您的库将根据其自己的,而不是根据 ,定义其直接依赖项的位置(在您的情况下,我猜测,这包括) 。这就是为什么链接器可以找到这些,但不能找到其传递依赖项(我再次猜测,这包括在您的情况下)。containers
RPATH
$ORIGIN
deepseq
那么为什么 Arch Linux 和 Ubuntu 之间存在差异呢?(进一步推测。)这是因为与 Arch Linux 不同,Ubunbu 的链接器--as-needed
默认使用。您会看到,ghc
会将您的库链接到其所有依赖项(包括传递性依赖项),但链接器将忽略其中一些依赖项,因为它不直接依赖于它们。您可以通过重新链接来验证这一点--no-as-needed
。
请注意,静态链接器的这些错误实际上不是错误,而是警告:它尝试解析符号,但不能;但动态链接器无论如何都可以。因此,您可以指示链接器忽略这些错误 ( --unresolved-symbols=ignore-all
),一切都应该很好。
我一直在努力添加显式支持来Cabal
生成用于 C 程序的 Haskell 库,并发现了同样的问题。有关详细信息,请参阅https://github.com/haskell/cabal/pull/2540#issuecomment-95984067。