linux haskell heroku static-linking yesod

linux - Implementando Yesod a Heroku, no puede construir estáticamente



haskell static-linking (3)

No tengo idea de qué es Yesod, pero sé exactamente qué significa cada uno de tus otros errores.

Primero, no deberías tratar de vincular estáticamente. La advertencia que recibe es exactamente correcta: si realiza un enlace estático y utiliza una de las rutinas para las que recibe la advertencia, debe organizar la ejecución en un sistema con exactamente la misma versión de libc.so.6 que la Usaste en tiempo de compilación.

Contrariamente a la creencia popular, la vinculación estática produce menos , no más, ejecutables portátiles en Linux.

Sus otros errores de enlace (estáticos) son causados ​​por la falta de libopenssl.a en el momento del enlace.

Pero supongamos que va a tomar la ruta "cuerda" y usar enlaces dinámicos.

Para la vinculación dinámica, Linux (y la mayoría de los demás UNIX) admiten compatibilidad con versiones anteriores: un binario antiguo continúa funcionando en sistemas más nuevos. Pero no admiten compatibilidad con versiones anteriores (un sistema binario integrado en un sistema más nuevo generalmente no se ejecutará en uno anterior).

Pero eso es lo que intenta hacer: construyó un sistema con glibc-2.14 (o más reciente) y está ejecutando un sistema con glibc-2.13 (o anterior).

La otra cosa que debes saber es que glibc está compuesto por más de 200 binarios que deben coincidir exactamente . Dos binarios clave son /lib/ld-linux.so y /lib/libc.so.6 (pero hay muchos más: libpthread.so.0 , libnsl.so.1 , etc., etc.). Si algunos de estos archivos binarios provienen de diferentes versiones de glibc, generalmente se bloquea. Y eso es exactamente lo que obtuviste cuando trataste de colocar tu glibc-2.14 libc.so.6 en LD_LIBRARY_PATH , ya no coincide con el sistema /lib/ld-linux .

Entonces, ¿cuáles son las soluciones? Hay varias posibilidades (en dificultad creciente):

  1. Puede copiar ld-2.14.so (el objetivo del enlace simbólico /lib/ld-linux ) al sistema de destino e invocarlo explícitamente:

    /path/to/ld-2.14.so --library-path <whatever> /path/to/your/executable

    Esto generalmente funciona, pero puede confundir una aplicación que mira a argv[0] , y se rompe para las aplicaciones que se ejecutan nuevamente.

  2. Puedes construir en un sistema anterior.

  3. Puedes usar appgcc (esta opción ha desaparecido, mira this para una descripción de lo que solía ser).

  4. Puede configurar un entorno chroot que coincida con el sistema de destino y construir dentro de ese chroot.

  5. Podrías construir un crosscompiler Linux-to-oldLinux

Soy nuevo en Yesod y tengo problemas para construir Yesod estáticamente, así que puedo implementarlo en Heroku.

He cambiado el archivo .cabal predeterminado para reflejar la compilación estática

if flag(production) cpp-options: -DPRODUCTION ghc-options: -Wall -threaded -O2 -static -optl-static else ghc-options: -Wall -threaded -O0

Y ya no se construye. Recibo un montón de advertencias y luego un montón de referencias indefinidas como esta:

Linking dist/build/personal-website/personal-website ... /usr/lib/ghc-7.0.3/libHSrts_thr.a(Linker.thr_o): In function `internal_dlopen'': Linker.c:(.text+0x407): warning: Using ''dlopen'' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/ghc-7.0.3/unix-2.4.2.0/libHSunix-2.4.2.0.a(HsUnix.o): In function `__hsunix_getpwent'': HsUnix.c:(.text+0xa1): warning: Using ''getpwent'' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/ghc-7.0.3/unix-2.4.2.0/libHSunix-2.4.2.0.a(HsUnix.o): In function `__hsunix_getpwnam_r'': HsUnix.c:(.text+0xb1): warning: Using ''getpwnam_r'' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/libpq.a(thread.o): In function `pqGetpwuid'': (.text+0x15): warning: Using ''getpwuid_r'' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/libpq.a(ip.o): In function `pg_getaddrinfo_all'': (.text+0x31): warning: Using ''getaddrinfo'' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/ libHSnetwork-2.3.0.2.a(BSD__63.o): In function `sD3z_info'': (.text+0xe4): warning: Using ''gethostbyname'' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/ libHSnetwork-2.3.0.2.a(BSD__164.o): In function `sFKc_info'': (.text+0x12d): warning: Using ''getprotobyname'' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/ghc-7.0.3/site-local/network-2.3.0.2/ libHSnetwork-2.3.0.2.a(BSD__155.o): In function `sFDs_info'': (.text+0x4c): warning: Using ''getservbyname'' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/libpq.a(fe-misc.o): In function `pqSocketCheck'': (.text+0xa2d): undefined reference to `SSL_pending'' /usr/lib/libpq.a(fe-secure.o): In function `SSLerrmessage'': (.text+0x31): undefined reference to `ERR_get_error'' /usr/lib/libpq.a(fe-secure.o): In function `SSLerrmessage'': (.text+0x41): undefined reference to `ERR_reason_error_string'' /usr/lib/libpq.a(fe-secure.o): In function `initialize_SSL'': (.text+0x2f8): undefined reference to `SSL_check_private_key'' /usr/lib/libpq.a(fe-secure.o): In function `initialize_SSL'': (.text+0x3c0): undefined reference to `SSL_CTX_load_verify_locations'' (... snip ...)

Si solo compilo con -optl-static y sin -optl-static todo se compilará bien, pero la aplicación se bloquea cuando intenta iniciarse en Heroku.

2011-12-28T01:20:51+00:00 heroku[web.1]: Starting process with command `./dist/build/personal-website/personal-website -p 41083` 2011-12-28T01:20:51+00:00 app[web.1]: ./dist/build/personal-website/ personal-website: error while loading shared libraries: libgmp.so.10: cannot open shared object file: No such file or directory 2011-12-28T01:20:52+00:00 heroku[web.1]: State changed from starting to crashed

Traté de agregar libgmp.so.10 a LD_LIBRARY_PATH como se sugiere here y luego obtuve el siguiente error:

2011-12-28T01:31:23+00:00 app[web.1]: ./dist/build/personal-website/ personal-website: /lib/libc.so.6: version `GLIBC_2.14'' not found (required by ./dist/build/personal-website/personal-website) 2011-12-28T01:31:23+00:00 app[web.1]: ./dist/build/personal-website/ personal-website: /lib/libc.so.6: version `GLIBC_2.14'' not found (required by /app/dist/build/personal-website/libgmp.so.10) 2011-12-28T01:31:25+00:00 heroku[web.1]: State changed from starting to crashed 2011-12-28T01:31:25+00:00 heroku[web.1]: Process exited

Parece que la versión de libc contra la que estoy compilando es diferente. Intenté también agregar libc al lote de bibliotecas de la misma manera que lo hice para libgmp, pero esto da como resultado un error de segmentación cuando la aplicación comienza en el lado de Heroku.

Todo funciona bien en mi PC. Estoy ejecutando archlinux de 64 bits con ghc 7.0.3. La entrada del blog en el blog oficial de Yesod parecía bastante fácil, pero estoy perplejo en este momento. ¿Alguien tiene alguna idea? Si hay una forma de hacer que esto funcione sin construir estáticamente, estoy abierto a eso también.

EDITAR

Por Employed Russians respondo que hice lo siguiente para solucionar esto.

Primero creé un nuevo directorio lib en el directorio del proyecto y copié las bibliotecas compartidas faltantes en él. Puede obtener esta información ejecutando ldd path/to/executable y heroku run ldd path/to/executable y comparando la salida.

Luego hice la heroku config:add LD_LIBRARY_PATH=./lib para que cuando la aplicación se inicie, el enlazador dinámico busque las bibliotecas en el nuevo directorio lib.

Finalmente, creé una máquina virtual ubuntu 11.10 y la desarrollé e implementé en Heroku desde allí, esto tiene un glibc bastante antiguo que funciona en el host Heroku.

Editar: Desde entonces he escrito un tutorial sobre el wiki de Yesod


Tienes varios problemas

No debe construir binarios de producción en distribuciones de borde sangrante. Las bibliotecas en el sistema de producción no serán compatibles con versiones anteriores.

No debe vincular glibc estáticamente, siempre intentará cargar bibliotecas adicionales en el tiempo de ejecución. Por ejemplo ensamblaje basado en CPU. De eso se tratan tus primeras advertencias.

Los últimos errores del vinculador parecen estar relacionados con una biblioteca de openssl faltante en la línea de comandos.

Pero, en definitiva, rebaja tu distribución.


Tuve problemas similares al iniciar Heroku (que usa glibc-2.11) donde tenía una aplicación que requería glibc-2.14, pero no tenía acceso a la fuente y no pude volver a compilarla. Intenté muchas cosas y nada funcionó.

Mi solución fue lanzar el servicio en Amazon Elastic Beanstalk y solo proporcionar una interfaz API.