2012-09-09 51 views
19

使用GHC版本7.4.2和-O3等標誌,我仍然得到巨大的可執行文件。據我所知,GHC做靜態鏈接,以及二進制的依賴關係是這樣的:減少GHC生成的可執行文件的大小

linux-vdso.so.1 (0x00007fff49bff000) 
    libpcre.so.1 => /usr/lib/libpcre.so.1 (0x00007fe658d6c000) 
    librt.so.1 => /usr/lib/librt.so.1 (0x00007fe658b64000) 
    libutil.so.1 => /usr/lib/libutil.so.1 (0x00007fe658961000) 
    libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fe65875d000) 
    libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fe658541000) 
    libcurl.so.4 => /usr/lib/libcurl.so.4 (0x00007fe6582e3000) 
    libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fe658074000) 
    libm.so.6 => /usr/lib/libm.so.6 (0x00007fe657d7a000) 
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fe657b65000) 
    libc.so.6 => /usr/lib/libc.so.6 (0x00007fe6577be000) 
    /lib/ld-linux-x86-64.so.2 (0x00007fe658fca000) 
    libssh2.so.1 => /usr/lib/libssh2.so.1 (0x00007fe657595000) 
    libssl.so.1.0.0 => /usr/lib/libssl.so.1.0.0 (0x00007fe65732b000) 
    libcrypto.so.1.0.0 => /usr/lib/libcrypto.so.1.0.0 (0x00007fe656f22000) 
    libz.so.1 => /usr/lib/libz.so.1 (0x00007fe656d0c000 

到目前爲止,它看起來相當不錯,但二進制裏面我可以看到行:

GHCi runtime linker: fatal error: I found a duplicate definition for symbol 
* Specifying the same object file twice on the GHCi command line 

    ....BlockedIndefinitelyOnMVar.......BlockedIndefinitelyOnSTM........AsyncException..base....GHC.IO.FD.......FD......GHC.IO.FD.setSize. 

,實際上一很多文本行,包括我的函數的名字,在其他模塊中定義的函數等等。問題是 - 是否可以刪除這些文本,並且GHC可以從外部庫中刪除未使用的代碼?

+4

你應該看看問題:http://stackoverflow.com/questions/6115459/small-haskell-program-compiled-with-ghc-into-huge-binary?lq = 1 - 我已經標記你的問題作爲它可能的重複。 – epsilonhalbe

+0

這不是真的 - 我剝離了該文件,並沒有得到任何與未劃分版本的區別。所以我仍在尋找縮小二進制大小的方法。 – jdevelop

+1

並且您是否嘗試了動態鏈接 - 正如您在@ donstewart的回答中所看到的,這使得二進制方式更加緊湊,而不僅僅是剝離符號。但我遠離專家。 – epsilonhalbe

回答

1

如果您使用gcc後端,您可以將-optc-Os標誌傳遞給ghc以優化輸出的大小。也許你可以減少一些字節的二進制文件。 但我也建議使用前面建議的動態鏈接,以及它的優點和缺點。

UPDATE:

壓縮可執行文件用UPX http://en.wikipedia.org/wiki/UPX或gzexe減少可執行文件的大小。

+0

使用動態鏈接就像將文件大小從一個文件移動到另一個文件一樣。如果我想將應用程序發送給最終用戶,該怎麼辦?我還需要打包所有這些DLL,因此靜態鏈接效果很好。然而,可執行文件的大小仍然讓我難過。 – jdevelop

+0

如果你可以假設你的客戶已經安裝了DLL,那麼動態鏈接就會有好處,否則你就會在應用程序中傳遞DLL並鏈接自己的版本(Windows方法),它與靜態鏈接具有相同的空間含義。你關心什麼?應用程序運行時的內存使用情況或可交付的磁盤空間?如果是後者,可以使用'UPX'(http://en.wikipedia.org/wiki/UPX)或'gzexe'壓縮可執行文件。 –

+0

實際上,我不喜歡可執行文件裏面有很多奇怪的文本數據。 – jdevelop

2

與大多數其他編譯器相比,LLVM可以在鏈接時進行更多優化。也許GHC有一個LLVM後端,你可以用-O4重新編譯和鏈接你的一些/所有的依賴關係。