Mari kita lihat apa yang terjadi, coba
$ 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)
...
Anda melihat dari ldd
output bahwa GHC telah menghasilkan executable yang terhubung secara dinamis, tetapi hanya perpustakaan C yang terhubung secara dinamis ! Semua perpustakaan Haskell disalin dalam kata demi kata.
Selain itu: karena ini adalah aplikasi intensif grafis, saya pasti akan mengompilasinya ghc -O2
Ada dua hal yang bisa Anda lakukan.
Simbol pengupasan
Solusi mudah: lepaskan biner:
$ strip A
$ du -hs A
5.8M A
Lepaskan simbol dari file objek. Biasanya hanya diperlukan untuk debugging.
Pustaka Haskell yang ditautkan secara dinamis
Baru-baru ini, GHC telah mendapatkan dukungan untuk menghubungkan dinamis kedua perpustakaan C dan Haskell . Kebanyakan distro sekarang mendistribusikan versi GHC yang dibangun untuk mendukung tautan dinamis perpustakaan Haskell. Pustaka Haskell bersama dapat dibagikan di antara banyak program Haskell, tanpa menyalinnya ke dalam executable setiap kali.
Pada saat penulisan Linux dan Windows didukung.
Agar perpustakaan Haskell terhubung secara dinamis, Anda harus mengompilasinya -dynamic
, seperti:
$ ghc -O2 --make -dynamic A.hs
Juga, semua perpustakaan yang ingin Anda bagikan harus dibangun dengan --enabled-shared
:
$ cabal install opengl --enable-shared --reinstall
$ cabal install glfw --enable-shared --reinstall
Dan Anda akan berakhir dengan executable yang jauh lebih kecil, yang memiliki dependensi C dan Haskell yang diselesaikan secara dinamis.
$ 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...
Dan, voila!
$ du -hs A
124K A
yang bisa Anda cabut menjadi lebih kecil:
$ strip A
$ du -hs A
84K A
Eksekusi weensy eensy, dibangun dari banyak potongan C dan Haskell yang terhubung secara dinamis:
$ 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 => ...
Satu poin terakhir: bahkan pada sistem dengan tautan statis saja, Anda dapat menggunakan -sit-objs , untuk mendapatkan satu file .o per fungsi tingkat atas, yang selanjutnya dapat mengurangi ukuran perpustakaan yang terhubung secara statis. Perlu GHC dibangun dengan -sit-objs, yang lupa dilakukan oleh beberapa sistem.