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 -dynamic
gibi 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.