2012-09-09 13 views
19

Używając GHC w wersji 7.4.2 z flagami takimi jak -O3, wciąż otrzymuję ogromny plik wykonywalny. Rozumiem, że GHC robi linkowania statycznego i zależnościami binarnego wygląda następująco:Zmniejsz rozmiar pliku wykonywalnego wyprodukowanego przez 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 

dotąd wygląda całkiem dobrze, jednak wewnątrz binarny widzę linie:

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. 

i rzeczywiście wiele linii tekstu, w tym nazwy moich funkcji, funkcje zdefiniowane w innych modułach i tak dalej. Pytanie brzmi: czy można usunąć te teksty i czy GHC może wyeliminować nieużywany kod z zewnętrznych bibliotek?

+4

powinieneś rzucić okiem na pytanie: http: //stackoverflow.com/questions/6115459/small-haskell-program-compiled-with-ghc-into-uge-binary? Lq = 1 - Zgłosiłem flagę pytanie jako możliwy jego duplikat. – epsilonhalbe

+0

To nie jest prawda - usunąłem plik i nie było żadnej różnicy w wersji bez pasków. Wciąż szukam sposobu na zmniejszenie rozmiaru pliku binarnego. – jdevelop

+1

i czy próbowałeś dynamicznego linkowania - jak widać w odpowiedzi @ donstewart, ten sposób binarny stał się bardziej zwarty, niż po prostu rozbierać symbole. Ale jestem daleko od eksperta. – epsilonhalbe

Odpowiedz

1

Jeśli używasz backendu gcc, możesz przekazać flagę -optc-Os do ghc, aby zoptymalizować wydruk dla rozmiaru. Być może możesz zmniejszyć swój plik binarny o kilka bajtów. Ale sugerowałbym również stosowanie dynamicznego łączenia zgodnie z sugestiami, z wszystkimi jego zaletami i wadami.

UPDATE:

Kompresja pliku wykonywalnego z UPX http://en.wikipedia.org/wiki/UPX lub gzexe aby zmniejszyć rozmiar pliku wykonywalnego.

+0

za pomocą dynamicznego łączenia jest jak przenoszenie rozmiaru z jednego pliku na drugi.Co jeśli chcę wysłać moją aplikację do użytkowników końcowych? Będę musiał również spakować wszystkie te biblioteki DLL, więc statyczne linkowanie działa świetnie.Jednak rozmiar pliku wykonywalnego wciąż mnie denerwuje. – jdevelop

+0

Dynamiczne łączenie się opłaca, jeśli możesz założyć, że twój klient ma już zainstalowaną bibliotekę dll, w przeciwnym razie dostarczasz bibliotekę dll wraz z aplikacją i łączysz swoją własną wersję (podejście Windows), która ma takie same implikacje przestrzenne jak łączenie statyczne. O co ci chodzi? Wykorzystanie pamięci podczas działania aplikacji lub przestrzeni dyskowej elementu dostarczanego? Jeśli jest to drugie, możesz skompresować swój plik wykonywalny za pomocą 'UPX' (http://en.wikipedia.org/wiki/UPX) lub' gzexe'. –

+0

W rzeczywistości nie podoba mi się to, że plik wykonywalny zawiera wiele dziwnych danych tekstowych. – jdevelop

2

LLVM może zrobić więcej optymalizacji w czasie łączenia niż większość innych kompilatorów. Być może GHC ma backend LLVM i możesz przekompilować i połączyć niektóre/wszystkie twoje zależności z -O4.

Powiązane problemy