7
votes

I am using Debian/MIPS+QEMU to build MIPS ports of PortFusion (a TCP tunneling solution). The resulting binaries are linked against GNU libc. Thus, they cannot be just copied over and used on vanilla OpenWrt which ships with uclibc instead of eglibc (which seems binary-compatible with GNU libc).


  • Can GHC 7.4 not statically link libc (+ libgmp, etc.) with Linux binaries for ARM and MIPS processors?
  • How can I see whether GHC is built with fully static compilation available?

-static ignored on 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)

info on 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\"]")
 ]

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

1
Does -static -optl-pthread -optl-static help?gspr
If I recall correctly, -optl-static makes sure the linker for the C libraries is told to link statically. AFAIK it also needs to be told to include pthreads then due to some ordering of the libraries being messed up. I think these flags are required for a fully static binary also on x86.gspr
@gspr it does work! You should put that as an answer.Cetin Sert
@gspr I will now update PortFusion.cabal.Cetin Sert

1 Answers

10
votes

In fact, the -static flag simply tells GHC to avoid dynamic linking to Haskell libraries. To statically link also to the C libraries, you need to pass -optl-pthread -optl-static as well. The latter tells the linker to statically link to the C libraries, while the former is (AFAIK) needed due to some ordering of the linked libraries being messed up when doing this.

You need the same flags for a fully static binary on x86 as well, so this isn't specific to ARM and MIPS.