Vamos a ver lo que está pasando, tratar
$ 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)
...
que se ve desde la salida ldd
que GHC ha producido un ejecutable enlazado dinámicamente, pero sólo las bibliotecas de C están vinculados dinámicamente! Todas las bibliotecas de Haskell están copiadas textualmente.
Aparte: ya que esta es una aplicación de uso intensivo de gráficos, sin duda compilar con ghc -O2
Hay dos cosas que puede hacer.
símbolos desprendimiento
una solución fácil: Tira el binario:
$ strip A
$ du -hs A
5.8M A
Strip descarta símbolos desde el archivo de objeto. Por lo general, solo son necesarios para la depuración.
vinculada de forma dinámica las bibliotecas de Haskell
Más recientemente, GHC ha ganado el apoyo de dynamic linking of both C and Haskell libraries. La mayoría de las distribuciones ahora distribuyen una versión de GHC construida para admitir el enlace dinámico de las bibliotecas de Haskell. Las bibliotecas compartidas de Haskell se pueden compartir entre muchos programas Haskell, sin copiarlos en el ejecutable cada vez.
En el momento de escribir Linux y Windows son compatibles.
para permitir que las bibliotecas de Haskell para vincularse dinámicamente, debe compilar con -dynamic
, así:
$ ghc -O2 --make -dynamic A.hs
Además, ninguna biblioteca que desea ser compartida debe ser construido con --enabled-shared
:
$ cabal install opengl --enable-shared --reinstall
$ cabal install glfw --enable-shared --reinstall
Y terminará con un ejecutable mucho más pequeño, que tiene las dependencias C y Haskell resueltas dinámicamente.
$ 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...
Y, voilà!
$ du -hs A
124K A
que se puede quitar para hacer aún más pequeño:
$ strip A
$ du -hs A
84K A
un ejecutable eensy weensy, construido a partir de muchas piezas C y Haskell de enlace dinámico:
$ 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 => ...
Uno punto final: incluso en sistemas con enlace estático solamente, puede use -split-objs, para obtener un archivo .o por nivel superior la función el, que puede reducir aún más el tamaño de las bibliotecas vinculadas estáticamente. Necesita que GHC se genere con -split-objs on, algo que algunos sistemas olvidan hacer.
¿Has intentado simplemente despojarlo? –
No sé lo que eso significa –
Ejecute el programa 'strip' en el binario para eliminar la tabla de símbolos. –