Incluso los programas trivialmente pequeños de Haskell se convierten en ejecutables gigantes.
¡He escrito un pequeño programa, que fue compilado (con GHC) en el binario con un tamaño de 7 MB!
¿Qué puede causar que incluso un pequeño programa de Haskell se compile en el gran binario?
¿Qué puedo hacer para reducir esto?
strip
en el binario para eliminar la tabla de símbolos.strip test
. Este comando elimina parte de la información de depuración del programa y la hace más pequeña.data M3 = M3 !V3 !V3 !V3
ydata V3 = V3 !Float !Float !Float
. Compilar conghc -O2 -funbox-strict-fields
.Respuestas:
Veamos qué está pasando, intenta
Como puede ver en el
ldd
resultado, GHC ha producido un ejecutable vinculado dinámicamente, ¡pero solo las bibliotecas C están vinculadas dinámicamente ! Todas las bibliotecas de Haskell se copian al pie de la letra.Aparte: dado que esta es una aplicación intensiva en gráficos, definitivamente compilaría con
ghc -O2
Hay dos cosas que puedes hacer.
Símbolos de pelado
Una solución fácil: tira el binario:
Strip descarta los símbolos del archivo objeto. Por lo general, solo son necesarios para la depuración.
Bibliotecas Haskell vinculadas dinámicamente
Más recientemente, GHC ha obtenido soporte para la vinculación dinámica de las bibliotecas C y Haskell . La mayoría de las distribuciones ahora distribuyen una versión de GHC creada para admitir el enlace dinámico de las bibliotecas Haskell. Las bibliotecas Haskell compartidas se pueden compartir entre muchos programas Haskell, sin copiarlas en el ejecutable cada vez.
Al momento de escribir, Linux y Windows son compatibles.
Para permitir que las bibliotecas de Haskell se vinculen dinámicamente, debe compilarlas de esta
-dynamic
manera:Además, todas las bibliotecas que desee compartir deben compilarse con
--enabled-shared
:Y terminará con un ejecutable mucho más pequeño, que tiene las dependencias C y Haskell resueltas dinámicamente.
¡Y voilá!
que puedes quitar para hacer aún más pequeño:
Un ejecutable eensy weensy, creado a partir de muchas piezas de C y Haskell vinculadas dinámicamente:
Un último punto: incluso en sistemas con enlace estático solamente, puede usar -split-objs , para obtener un archivo .o por función de nivel superior, lo que puede reducir aún más el tamaño de las bibliotecas enlazadas estáticamente. Necesita que GHC se construya con -split-objs, algo que algunos sistemas olvidan hacer.
fuente
cabal install
el binario instalado por defecto?enable-shared
fue considerado launchpad.net/ubuntu/+source/pandoc/+bugsHaskell usa enlaces estáticos por defecto. Es decir, todos los enlaces a OpenGL se copian en su programa. Como son bastante grandes, su programa se infla innecesariamente. Puede solucionar este problema mediante el uso de enlaces dinámicos, aunque no está habilitado de forma predeterminada.
fuente
--enabled-shared
", por lo que si su plataforma Haskell viene con bibliotecas creadas sin--enabled shared
que tenga que volver a compilar las bibliotecas base, lo que puede ser bastante doloroso.