Küçük Haskell programı, GHC ile büyük ikili dosyalar halinde derlendi


127

Önemsiz derecede küçük Haskell programları bile devasa yürütülebilir dosyalara dönüşür.

Küçük bir program yazdım, (GHC ile) ikiliye 7 MB genişleyen boyutta derlenmiş!

Küçük bir Haskell programının bile devasa ikili dosyaya derlenmesine ne sebep olabilir?

Bunu azaltmak için ne yapabilirim?


2
Sadece sıyırmayı denedin mi?
Fred Foo

21
stripSembol tablosunu kaldırmak için programı ikili üzerinde çalıştırın .
Fred Foo

1
@ tm1rbt: Çalıştır strip test. Bu komut, programdan bazı hata ayıklama bilgilerini kaldırır ve daha küçük hale getirir.
Fuz

8
Bir kenara, 3B matematik kitaplığındaki veri türleriniz performans nedenlerinden dolayı daha katı olmalıdır: data M3 = M3 !V3 !V3 !V3ve data V3 = V3 !Float !Float !Float. İle derleyin ghc -O2 -funbox-strict-fields.
Don Stewart

8
Bu gönderi meta üzerinde tartışılıyor .
Patrick Hofman

Yanıtlar:


215

Bakalım neler oluyor, dene

  $ du -hs A
  13M   A

  $ file A
  A: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), 
     dynamically linked (uses shared libs), for GNU/Linux 2.6.27, not stripped

  $ ldd A
    linux-vdso.so.1 =>  (0x00007fff1b9ff000)
    libXrandr.so.2 => /usr/lib/libXrandr.so.2 (0x00007fb21f418000)
    libX11.so.6 => /usr/lib/libX11.so.6 (0x00007fb21f0d9000)
    libGLU.so.1 => /usr/lib/libGLU.so.1 (0x00007fb21ee6d000)
    libGL.so.1 => /usr/lib/libGL.so.1 (0x00007fb21ebf4000)
    libgmp.so.10 => /usr/lib/libgmp.so.10 (0x00007fb21e988000)
    libm.so.6 => /lib/libm.so.6 (0x00007fb21e706000)
    ...      

lddÇıktıdan, GHC'nin dinamik olarak bağlantılı bir yürütülebilir dosya ürettiğini görüyorsunuz , ancak yalnızca C kitaplıkları dinamik olarak bağlantılıdır ! Tüm Haskell kitaplıkları birebir kopyalanır.

Bir kenara: Bu grafik yoğun bir uygulama olduğu için kesinlikle ghc -O2

Yapabileceğiniz iki şey var.

Soyma sembolleri

Kolay bir çözüm: ikiliyi çıkarın:

$ strip A
$ du -hs A
5.8M    A

Strip, nesne dosyasındaki sembolleri atar. Genellikle yalnızca hata ayıklama için gereklidirler.

Dinamik olarak bağlantılı Haskell kitaplıkları

Daha yakın zamanlarda GHC, hem C hem de Haskell kitaplıklarının dinamik olarak bağlanması için destek kazanmıştır. . Çoğu dağıtım artık Haskell kitaplıklarının dinamik olarak bağlanmasını desteklemek için oluşturulmuş bir GHC sürümünü dağıtır. Paylaşılan Haskell kitaplıkları, birçok Haskell programı arasında, her seferinde yürütülebilir dosyaya kopyalanmadan paylaşılabilir.

Linux ve Windows yazılırken desteklenmektedir.

Haskell kitaplıklarının dinamik olarak bağlanmasına izin vermek için, bunları aşağıdaki -dynamicgibi derlemeniz gerekir :

 $ ghc -O2 --make -dynamic A.hs

Ayrıca, paylaşmak istediğiniz tüm kitaplıklar aşağıdakilerle oluşturulmalıdır --enabled-shared:

 $ cabal install opengl --enable-shared --reinstall     
 $ cabal install glfw   --enable-shared --reinstall

Ve hem C hem de Haskell bağımlılıkları dinamik olarak çözülmüş çok daha küçük bir yürütülebilir dosya elde edeceksiniz.

$ ghc -O2 -dynamic A.hs                         
[1 of 4] Compiling S3DM.V3          ( S3DM/V3.hs, S3DM/V3.o )
[2 of 4] Compiling S3DM.M3          ( S3DM/M3.hs, S3DM/M3.o )
[3 of 4] Compiling S3DM.X4          ( S3DM/X4.hs, S3DM/X4.o )
[4 of 4] Compiling Main             ( A.hs, A.o )
Linking A...

Ve voilà!

$ du -hs A
124K    A

daha da küçültmek için soyabileceğiniz:

$ strip A
$ du -hs A
84K A

Dinamik olarak bağlantılı birçok C ve Haskell parçasından oluşan, küçük bir yürütülebilir dosya:

$ ldd A
    libHSOpenGL-2.4.0.1-ghc7.0.3.so => ...
    libHSTensor-1.0.0.1-ghc7.0.3.so => ...
    libHSStateVar-1.0.0.0-ghc7.0.3.so =>...
    libHSObjectName-1.0.0.0-ghc7.0.3.so => ...
    libHSGLURaw-1.1.0.0-ghc7.0.3.so => ...
    libHSOpenGLRaw-1.1.0.1-ghc7.0.3.so => ...
    libHSbase-4.3.1.0-ghc7.0.3.so => ...
    libHSinteger-gmp-0.2.0.3-ghc7.0.3.so => ...
    libHSghc-prim-0.2.0.0-ghc7.0.3.so => ...
    libHSrts-ghc7.0.3.so => ...
    libm.so.6 => /lib/libm.so.6 (0x00007ffa4ffd6000)
    librt.so.1 => /lib/librt.so.1 (0x00007ffa4fdce000)
    libdl.so.2 => /lib/libdl.so.2 (0x00007ffa4fbca000)
    libHSffi-ghc7.0.3.so => ...

Son bir nokta: Yalnızca statik bağlantılı sistemlerde bile, üst düzey işlev başına bir .o dosyası elde etmek için -split-objs kullanabilirsiniz , bu da statik olarak bağlantılı kitaplıkların boyutunu daha da azaltabilir. Bazı sistemlerin yapmayı unuttuğu GHC'nin -split-obj'lerle inşa edilmesi gerekiyor.


7
mac'ta ghc için dinamik bağlantı ne zaman gelecek?
Carter Tazio Schonwald

1
... cabal installkurulu ikili dosyayı varsayılan olarak çıkarmaz mı?
hvr

1
Windows'ta bunu yapmak sonuçta ortaya çıkan dosyayı çalıştırılamaz hale getiriyor gibi görünüyor, libHSrts-ghc7.0.3.dll eksikliğinden şikayet ediyor
is7s

3
bu ikili, bu prosedürlerden sonra diğer Linux makinelerinde çalışacak mı?
ア レ ッ ク ス

1
2011'den Merhaba OP! Ben gelecekten geliyorum ve Ubuntu 16.04 üzerinde Pandoc yürütülebilir 50MB şişman olduğunu söyleyebilir ve onu dayalı değişti gitmeyecek packages.ubuntu.com/zesty/pandoc . Yakın gelecekteki kendine ve başkalarına mesaj: paket sorumlusu ile iletişime geçin ve enable-shareddeğerlendirilip değerlendirilmediğini sorun . launchpad.net/ubuntu/+source/pandoc/+bugs
Stéphane Gourichon

11

Haskell, varsayılan olarak statik bağlantı kullanır. Bu, OpenGL'ye olan tüm bağların programınıza kopyalanmasıdır. Oldukça büyük oldukları için programınız gereksiz yere şişirilir. Varsayılan olarak etkin olmasa da dinamik bağlantı kullanarak bu sorunu çözebilirsiniz.


5
Bu sorunu çözmek için kitaplıkları dinamik olarak bağlayabilirsiniz. Varsayılan olanın neden önemli olduğundan emin değilim, bayrak yeterince basit.
Thomas M. DuBuisson

4
Sorun şu ki, "paylaşılmasını istediğiniz herhangi bir kitaplık kurulmalıdır --enabled-shared", bu nedenle Haskell Platformunuz --enabled sharedsiz olmadan oluşturulmuş kitaplıklarla birlikte gelirse , temel kitaplıkları yeniden derlemeniz oldukça zahmetli olabilir.
nponeccop
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.