2012-09-09 30 views
19

GHC sürüm 7.4.2'yi -O3 gibi bayraklarla kullanmak, yine de çok büyük bir yürütülebilir dosya oluşturuyor. Ben GHC statik bağlama yapar anlamak ve ikili bağımlılıkları gibi görünür:GHC tarafından üretilen yürütülebilir dosyanın boyutunu azaltın

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. 

ve aslında bir:

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 

şimdiye kadar ben satırları görebilirsiniz ancak ikili programdaki oldukça iyi görünüyor işlevlerimin adları, diğer modüller ve diğer işlevler de dahil olmak üzere birçok metin satırı. Soru şu: bu metinleri kaldırmak mümkün ve GHC kullanılmayan kodu harici kütüphanelerden eleyebilir mi?

+4

Sorulara bir göz atmalısınız: http: //stackoverflow.com/questions/6115459/small-haskell-program-compiled-with-ghc-into-huge-binary? Lq = 1 - Ben sizi işaretledim. bunun olası bir kopyası olarak sorgulayın. – epsilonhalbe

+0

gerçekten doğru değil - Dosyayı kesip çıkarılmamış sürümüyle herhangi bir fark alamadım. Yani hala ikili boyutunu küçültmenin yolunu arıyorum. – jdevelop

+1

ve dinamik bağlantıyı denediniz mi - @ donstewart'un yanıtında gördüğünüz gibi bu, sembollerin sıyrılmasından ziyade ikili yolu daha kompakt hale getirdi. Ama ben bir uzmanın uzağındayım. – epsilonhalbe

cevap

1

Gcc arka ucunu kullanırsanız, çıktı boyutunu en iyi duruma getirmek için -optc-Os bayrağını ghc geçirebilirsiniz. Belki de ikilinizi birkaç byte azaltabilirsiniz. Ama daha önce önerildiği gibi, tüm artıları ve eksileri ile dinamik bağlantı kullanmanızı da öneririm.

GÜNCELLEME:

UPX http://en.wikipedia.org/wiki/UPX ile yürütülebilir sıkıştırın veya yürütülebilir boyutunu azaltmak için gzexe.

+0

sanmıyorum bir dosyadan diğerine taşıma boyutu gibidir.Ya benim uygulamayı son kullanıcılara göndermek istiyorsam, tüm bu DLL'leri de paketlemek istiyorum, bu yüzden statik bağlantı büyük çalışıyor.Ancak, yürütülebilir dosya boyutu hala beni üzüyor. – jdevelop

+0

Müşterinizin dll yüklendiğini varsayabilirseniz, dinamik bağlantı, ödeme yapar, aksi takdirde dll'yi uygulamanızla birlikte gönderirsiniz ve statik alan adıyla aynı alanla ilişkili olan kendi sürümünüzü (windows yaklaşımı) bağlarsınız. Tam olarak ne endişen var? Uygulama çalışırken bellek kullanımı veya çıktıların disk alanı mı? İkincisi ise, çalıştırıcınızı 'UPX' (http://en.wikipedia.org/wiki/UPX) veya' gzexe' ile sıkıştırabilirsiniz. –

+0

Aslında, yürütülebilir dosyanın içinde çok sayıda garip metinsel veri bulunması gerçeğini beğenmiyorum. – jdevelop

2

LLVM, bağlantı zamanlarında diğer çoğu derleyiciden daha fazla optimizasyon yapabilir. Belki GHC'nin bir LLVM arka planı vardır ve bağımlılıklarınızın bir kısmını/tamamını -O4 ile yeniden birleştirebilir ve bağlayabilirsiniz.

İlgili konular