Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GHC: statically linking Linux binaries for ARM & MIPS processors

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)?

like image 814
Cetin Sert Avatar asked Jan 11 '13 01:01

Cetin Sert


People also ask

How to statically link C++ programs in GCC?

Statically link C++ programs. First, install the package needed: # yum install glibc-static libstdc++-static. Under GCC 4.4, you can use the -static option as for C programs: $ g++ -static. After GCC 4.5, gcc supports the -static-libstdc++ option: $ gcc -static -static-libstdc++ -static-libgcc. Also note the library order.

Is it possible to use musl instead of glibc for static linking?

TL;DR: I made some GHC binaries for linux that rely on musl instead of glibc for easier static linking. Scroll down for the link. As most of you know, musl is a linux only C standard library that is optimized for static linking.

What is the relationship between glibc and dynamic libraries?

It's a little more complicated than that. glibc has certain function calls which cause dynamic libraries to be loaded, for things like iconv or NSS - glibc NSS includes getpwuid for example, which needs to load pam_unix.so at runtime for account information. Your application is built with glibc X.Y, statically. You give it to a customer.

Is it possible to use static linking in Linux?

You can even use other libc implementation like uClibc or musl libc which are more friendly for static linking. A comparison of C/POSIX standard library implementations for Linux can be found here. Linux binaries are not portable if they are built in normal way even with full static linking.


1 Answers

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.

like image 120
gspr Avatar answered Nov 03 '22 00:11

gspr