【问题标题】:GHC: statically linking Linux binaries for ARM & MIPS processorsGHC:为 ARM 和 MIPS 处理器静态链接 Linux 二进制文件
【发布时间】:2013-01-11 01:18:56
【问题描述】:

我正在使用 Debian/MIPS+QEMU 构建MIPS ports of PortFusion(一个 TCP 隧道解决方案)。生成的二进制文件链接到 GNU libc。因此,它们不能被复制并用于随 uclibc 而不是 eglibc (似乎与 GNU libc 二进制兼容)的 vanilla OpenWrt。


  • GHC 7.4 是否不能将 libc(+ libgmp 等)与用于 ARM 和 MIPS 处理器的 Linux 二进制文件静态链接?
  • 如何查看 GHC 是否使用可用的全静态编译构建?

-static 在 MIPS 上被忽略:

root@debian:~# cat hello.hs
main = print 2
root@debian:~# ghc --make hello.hs 
[1 of 1] Compiling Main             ( hello.hs, hello.o )
Linking hello ...
root@debian:~# ldd ./hello
    libgmp.so.10 => /usr/lib/mips-linux-gnu/libgmp.so.10 (0x77908000)
    libffi.so.5 => /usr/lib/mips-linux-gnu/libffi.so.5 (0x778ea000)
    libm.so.6 => /lib/mips-linux-gnu/libm.so.6 (0x77855000)
    librt.so.1 => /lib/mips-linux-gnu/librt.so.1 (0x7783c000)
    libdl.so.2 => /lib/mips-linux-gnu/libdl.so.2 (0x77827000)
    libc.so.6 => /lib/mips-linux-gnu/libc.so.6 (0x776a0000)
    libpthread.so.0 => /lib/mips-linux-gnu/libpthread.so.0 (0x77675000)
    /lib/ld.so.1 (0x55550000)
root@debian:~# rm hello
root@debian:~# ghc --make -static hello.hs 
Linking hello ...
root@debian:~# ldd ./hello
    libgmp.so.10 => /usr/lib/mips-linux-gnu/libgmp.so.10 (0x76f98000)
    libffi.so.5 => /usr/lib/mips-linux-gnu/libffi.so.5 (0x76f7a000)
    libm.so.6 => /lib/mips-linux-gnu/libm.so.6 (0x76ee5000)
    librt.so.1 => /lib/mips-linux-gnu/librt.so.1 (0x76ecc000)
    libdl.so.2 => /lib/mips-linux-gnu/libdl.so.2 (0x76eb7000)
    libc.so.6 => /lib/mips-linux-gnu/libc.so.6 (0x76d30000)
    libpthread.so.0 => /lib/mips-linux-gnu/libpthread.so.0 (0x76d05000)
    /lib/ld.so.1 (0x55550000)

关于 GHC 的信息:

root@debian:~# ghc --info
 [("Project name","The Glorious Glasgow Haskell Compilation System")
 ,("GCC extra via C opts"," -fwrapv")
 ,("C compiler command","/usr/bin/gcc")
 ,("C compiler flags"," -fno-stack-protector  -Wl,--hash-size=31 -Wl,--reduce-memory-overheads")
 ,("ar command","/usr/bin/ar")
 ,("ar flags","q")
 ,("ar supports at file","YES")
 ,("touch command","touch")
 ,("dllwrap command","/bin/false")
 ,("windres command","/bin/false")
 ,("perl command","/usr/bin/perl")
 ,("target os","OSLinux")
 ,("target arch","ArchUnknown")
 ,("target word size","4")
 ,("target has GNU nonexec stack","True")
 ,("target has subsections via symbols","False")
 ,("Project version","7.4.1")
 ,("Booter version","7.4.1")
 ,("Stage","2")
 ,("Build platform","mips-unknown-linux")
 ,("Host platform","mips-unknown-linux")
 ,("Target platform","mips-unknown-linux")
 ,("Have interpreter","NO")
 ,("Object splitting supported","NO")
 ,("Have native code generator","NO")
 ,("Support SMP","NO")
 ,("Unregisterised","YES")
 ,("Tables next to code","YES")
 ,("RTS ways","l debug    ")
 ,("Leading underscore","NO")
 ,("Debug on","False")
 ,("LibDir","/usr/lib/ghc")
 ,("Global Package DB","/usr/lib/ghc/package.conf.d")
 ,("Gcc Linker flags","[\"-Wl,--hash-size=31\",\"-Wl,--reduce-memory-overheads\"]")
 ,("Ld Linker flags","[\"--hash-size=31\",\"--reduce-memory-overheads\"]")
 ]

另见:Can GHC link binaries against a libc implementation such as uclibc (used in OpenWrt by default)?

【问题讨论】:

  • -static -optl-pthread -optl-static 有帮助吗?
  • 如果我没记错的话,-optl-static 确保 C 库的链接器被告知静态链接。 AFAIK 还需要被告知包含 pthreads,因为这些库的一些排序被搞砸了。我认为这些标志对于 x86 上的完全静态二进制文件也是必需的。
  • @gspr 确实有效!你应该把它作为答案。
  • @gspr 我现在将更新PortFusion.cabal

标签: haskell arm mips ghc static-linking


【解决方案1】:

In fact-static 标志只是告诉 GHC 避免动态链接到 Haskell 库。要静态链接到 C 库,您还需要传递 -optl-pthread -optl-static。后者告诉链接器静态链接到 C 库,而前者是 (AFAIK) 需要的,因为这样做时链接库的某些顺序被搞砸了。

对于 x86 上的完全静态二进制文件,您也需要相同的标志,因此这并不特定于 ARM 和 MIPS。

【讨论】:

  • 我相信在 PortFusion.cabal 中的 x86 上拥有 ld-options: -static 就足够了,我在没有 -pthread 的情况下构建并验证了 Linux x86-64 和 x86-32 二进制文件的静态性。感谢您指出两者!在 ARM 和 MIPS 上,-pthread 似乎是严格需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 2015-04-02
  • 1970-01-01
  • 2012-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多