2012-09-09 49 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重新编译和链接你的一些/所有的依赖关系。