Crear un ejecutable estático de Haskell Linux


No es frecuente que dos cosas que amo tanto se junten para causarme tanta molestia (además de mis hijos). He escrito un programa Haskell en el trabajo que utiliza bibliotecas como text, xml-enumerator, attoparsec-text, etc. Lo tengo funcionando correctamente en mi máquina Windows en el trabajo, mi máquina virtual Ubuntu en el trabajo (32 bits), mi escritorio Ubuntu (32 bits de nuevo) y una instancia EC2 ejecutando Ubuntu (64 bits).

Nuestro cliente está ejecutando CentOS 5.3, 64-bit. No puedo por mi vida conseguir esto ejecutable para que se ejecute correctamente. Intenté crear un ejecutable estático usando:

ghc --make myprog.hs -optl-static -optl-pthread

Pero cuando intento ejecutar ese ejecutable en el servidor CentOS, recibo un mensaje de error:

openFile: invalid argument (Invalid argument)

Asumo que esto está relacionado con el error descrito aquí. He intentado compilar desde Ubuntu de 32 y 64 bits, he probado compilaciones estáticas y compartidas, nada funciona (aunque ocasionalmente obtengo valores de segmento en lugar del mensaje de error anterior). Puedo intentar descargar CentOS 5.3 y crear una máquina virtual para ello, pero tomará un tiempo para descargar, y no estoy seguro de qué versión de GHC funcionará en él (traté de conseguir GHC 7 en su servidor, pero me encontré con un problema libc).

En este punto, se me han ocurrido algunos enfoques posibles, pero me gustaría evitar estos si es posible:

  • Reescribir en un lenguaje diferente (la idea de hacer esto en Java me da náuseas, aunque podría ser un buen momento para probar Cal/OpenQuark).
  • Tal vez probar un compilador alternativo, como jhc. Pero no estoy muy seguro de cómo empezar a instalar todas las dependencias para este programa en jhc; si la gente tiene experiencia y sabe que text/attoparsec/etc funciona en jhc, me encantaría escucharlo.
  • Hack de todos los hacks: construir un ejecutable de Windows, instalar wine en su servidor y ejecutarlo de esa manera.

Como un total aparte, estas son las situaciones donde yo realmente deseo que tuviéramos un motor JVM para GHC. Supongo que podría probar LambdaVM también. Pero me encantaría escuche consejos de la comunidad sobre qué hacer aquí.

Author: Don Stewart, 2011-05-10

3 answers

Este simple ejemplo "funciona para mí":

$ cat A.hs
main = print "yes"

$ ghc -O2 --make -static -optc-static -optl-static A.hs -fvia-C -optl-pthread

$ ldd A
    not a dynamic executable
$ ./A
"yes"

(y he utilizado este proceso, vía.cabal, para enviar ejecutables para clientes en el último par de años).

Creo que la mejor opción es archivar errores y hacer que esto funcione. El IHG también puede financiar trabajos como este, pero estoy bastante seguro de que el equipo de GHC consideraría esto una alta prioridad, si está tratando de enviar productos.

 29
Author: Don Stewart,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-10 17:13:01

Está relacionado con la antigua biblioteca glibc en CentOS. Tienes que compilar con la misma versión de glibc instalada en CentOS.

Tuve exactamente el mismo problema. Haskell ejecutable compilado en arch (o ubuntu) no se ejecutará en CentOS. En mi caso, aunque tuve suerte, porque nuestro administrador acaba de quitar CentOS e instalado Arch para servidor de aplicaciones.

 7
Author: Vagif Verdi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-10 17:21:06

Descubrí el problema. Parece que el enlace a la página de Biohaskell es exacto: este es un problema al cargar iconv. Esto ocurre cuando se llama openFile, pero no cuando se llama openBinaryFile. Dado que xml-enumerator utiliza este último, funcionó muy bien. Cambiar el resto del código para usar openBinaryFile en su lugar (a través de Data.Enumerator.Binary.enumFile) hizo que todo funcionara.

Esta es una buena solución para mi caso de uso, pero el error todavía existe.

 4
Author: Michael Snoyman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-05-11 08:52:41