2013-01-11 72 views
7

我正在使用Debian/MIPS + QEMU構建MIPS ports of PortFusion(TCP隧道解決方案)。產生的二進制文件與GNU libc鏈接。因此,他們不能被複制和使用在與uclibc,而不是eglibc(似乎與GNU libc二進制兼容)的香草OpenWrt上。GHC:爲ARM和MIPS處理器靜態鏈接Linux二進制文件


  • 能GHC 7.4沒有靜態鏈接的libc(+ libgmp等)的Linux二進制文件ARM和MIPS處理器?
  • 如何查看GHC是否使用完全靜態編譯生成?

-static忽視了MIPS:

[email protected]:~# cat hello.hs 
main = print 2 
[email protected]:~# ghc --make hello.hs 
[1 of 1] Compiling Main    (hello.hs, hello.o) 
Linking hello ... 
[email protected]:~# 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) 
[email protected]:~# rm hello 
[email protected]:~# ghc --make -static hello.hs 
Linking hello ... 
[email protected]:~# 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:

[email protected]:~# 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)?

+1

「-static -optl-pthread -optl-static」有幫助嗎? – gspr

+1

如果我沒有記錯,'-optl-static'確保C庫的鏈接器被告知靜態鏈接。 AFAIK它還需要被告知包含pthreads,然後由於庫的一些排序被搞砸了。我認爲這些標誌對於x86上的完全靜態二進制也是必需的。 – gspr

+1

@gspr它確實有用!你應該把它作爲答案。 –

回答

8

In fact-static標誌只是告訴GHC避免動態鏈接到哈斯克爾庫。要靜態鏈接到C庫,您還需要通過-optl-pthread -optl-static。後者告訴鏈接器靜態鏈接到C庫,而前者是(AFAIK)需要的,因爲鏈接庫的某些排序在執行此操作時會被搞亂。

對於x86上的完全靜態二進制文件,您也需要相同的標誌,因此這不是針對ARM和MIPS的。

+1

我相信在['PortFusion.cabal'](http://hackage.haskell.org/packages/archive/PortFusion/1.2.1/PortFusion.cabal)x86上有'ld-options:-static'就足夠了,我構建並驗證了Linux x86-64和x86-32二進制文件的靜態,而不使用-pthread。感謝您指出了兩個!在ARM和MIPS上'-pthread'似乎是嚴格需要的。 –

+1

啊,很高興知道。謝謝! – gspr