Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reduce size of executable produced by GHC

Tags:

Using GHC version 7.4.2 with flags like -O3, I still get huge executable produced. I understand that GHC does static linking, and dependencies of the binary looks like:

    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

so far it looks quite good, however inside the binary I can see the lines:

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.

and actually a lot of text lines, including names of my functions, functions defined in other modules and so on. The question is - is it possible to remove those texts, and can GHC eliminate unused code from external libraries?

like image 890
jdevelop Avatar asked Sep 09 '12 08:09

jdevelop


People also ask

Why is GHC so big?

Because GHC isn't a compiler for just "Haskell -- the standardized language". It also implements a huge number of optional language extensions. Simple languages often require complex compilers if they are to run fast. You need to do more analysis of the program structure to squeeze out performance.

Why are Haskell binaries so big?

Since Haskell executables are statically compiled by default, all the transitive dependencies are included in the output. This 103-megabyte binary is big enough that it takes a non-trivial amount of time to transfer over the wire if it needed to be downloaded or uploaded.


2 Answers

LLVM can do more optimization at link time than most other compilers. Maybe GHC has an LLVM backend and you can recompile and link some/all of your dependencies with -O4.

like image 117
Andrew Wagner Avatar answered Oct 06 '22 20:10

Andrew Wagner


If you use the gcc backend, you can pass the -optc-Os flag to ghc to optimize the output for size. Perhaps you can reduce your binary by some bytes. But I would also suggest using dynamic linking as suggested before, with all it's pros and cons.

UPDATE:

Compress your executable with UPX http://en.wikipedia.org/wiki/UPX or gzexe to reduce the size of the executable.

like image 22
Falco Hirschenberger Avatar answered Oct 06 '22 22:10

Falco Hirschenberger