Déployer Yesod à Heroku, ne peut pas construire statiquement

je suis très nouveau à Yesod et j'ai de la difficulté à construire Yesod statiquement pour que je puisse me déployer à Heroku.

j'ai changé la valeur par défaut .cabale fichier pour prendre en compte la compilation statique

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

et il ne construit plus. Je reçois un tas d'avertissements et puis un flopée de indéfinie des références comme ceci:

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 je viens de le compiler avec juste -static et sans -optl-static tout se construit bien, mais l'application s'écrase quand elle essaie de démarrer sur 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

j'ai essayé d'ajouter libgmp.alors?10 à LD_LIBRARY_PATH comme suggéré dans ici et puis a obtenu l'erreur suivante:

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

Il semble que la version de la libc que je compile contre est différent. J'ai essayé aussi d'ajouter libc au lot de bibliothèques même que j'ai fait, pour libgmp mais cela entraîne une erreur de segmentation quand L'application commence du côté D'Heroku.

Tout fonctionne très bien sur mon PC. Je suis courant 64bit archlinux avec ghc 7.0.3. Le blog sur le site officiel Yesod blog semblait assez facile mais je suis perplexe à ce point. N'importe qui ont des idées? Si il y a un moyen pour obtenir cette chose de travail sans construire statiquement je suis ouvert à cela aussi.

EDIT

Par Employed Russians réponse j'ai fait ce qui suit pour corriger la situation.

tout d'Abord créé un nouveau répertoire lib sous le répertoire du projet et copié les bibliothèques partagées manquantes. Vous pouvez obtenir cette information en exécutant ldd path/to/executable et heroku run ldd path/to/executable et comparer la sortie.

j'ai fait ensuite de heroku config:add LD_LIBRARY_PATH=./lib ainsi, lorsque l'application est lancée, le linker dynamique recherchera des bibliothèques dans le nouveau répertoire lib.

finalement j'ai créé une machine virtuelle ubuntu 11.10 et construit et déployé à Heroku à partir de là, cela a une glibc assez vieille pour fonctionner sur L'hôte Heroku.

Modifier: Depuis, j'ai écrit un tutoriel sur l' Yesod wiki

25
demandé sur rubik 2011-12-28 19:40:56
la source

3 ответов

je n'ai aucune idée de ce que Yessod est, mais je sais exactement ce que chacune de vos autres erreurs signifie.

tout d'Abord, vous devez essayez d'établir un lien statique. L'avertissement que vous obtenez est exactement ça: si vous liez statiquement, et utilisez l'une des routines pour lesquelles vous recevez l'avertissement, alors vous devez vous arranger pour exécuter sur un système avec exactement la même version de libc.alors?6 comme celui que vous avez utilisé à construire temps.

contrairement à la croyance populaire, les liens statiques produisent moins, pas plus, exécutables portables sous Linux.

vos autres erreurs de lien (statique)sont causées parlibopenssl.a à l'heure du lien.

mais supposons que vous allez suivre la route "saine", et utiliser la liaison dynamique.

pour la liaison dynamique, Linux (et la plupart des autres UNIXes) supporte la rétrocompatibilité: un vieux binaire continue de fonctionner sur les nouveaux systèmes. Mais ils ne supportent pas que la compatibilité ascendante (binaire construit un nouveau système sera généralement exécuter sur un plus ancien).

mais c'est ce que vous essayez de faire: vous avez construit sur un système avec glibc-2.14 (ou plus récent), et vous utilisez un système avec glibc-2.13 (ou plus ancien).

l'autre chose que vous devez savoir est que glibc est composé de quelques 200 + binaires qui doivent tous correspondre exactement. Deux clés binaires /lib/ld-linux.so et /lib/libc.so.6 (mais il y a beaucoup plus: libpthread.so.0,libnsl.so.1, etc. etc.) Si certains de ces binaires proviennent de différentes versions de glibc, vous obtenez généralement un accident. Et c'est exactement ce que vous avez obtenu, quand vous avez essayé de placer votre glibc-2.14 libc.so.6 sur le LD_LIBRARY_PATH -- il ne correspond plus au système /lib/ld-linux.

Alors, quelles sont les solutions? Il y a plusieurs possibilités (difficulté croissante):

  1. Vous pouvez copier ld-2.14.so (la cible de /lib/ld-linux lien symbolique) à la système cible, et l'invoquer explicitement:

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

    cela fonctionne généralement, mais peut confondre une application qui regarde argv[0], et des pauses pour les applications qui ressortent d'elles-mêmes.

  2. Vous pouvez construire sur un système plus ancien.

  3. Vous pouvez utiliser appgcc (cette option a disparu, voir pour une description de ce qu'il utilisé pour être).

  4. Vous pourriez mettre en place un chroot environnement correspondant au système cible, et construire à l'intérieur de ce chroot.

  5. vous pourriez construire vous-même un crosscompiler Linux-to-olderLinux

51
répondu Employed Russian 2015-03-28 06:50:07
la source

Vous avez plusieurs questions.

vous ne devez pas construire des binaires de production sur des distributions de bord de saignement. Les bibliothèques du système de production ne seront pas compatibles avec les versions ultérieures.

vous ne devez pas lier glibc statiquement - il sera toujours à l'exécution essayer de charger des bibliothèques supplémentaires. Par exemple processeur de l'assemblée. C'est l'objet de vos premiers avertissements.

les dernières erreurs de linker semblent être liées à une bibliothèque openssl manquante sur la commande ligne.

mais tout en tout - dégrade votre distribution.

5
répondu user239558 2011-12-28 20:29:38
la source

j'ai eu des problèmes de lancement similaires à Heroku (qui utilise glibc-2.11) où j'avais une application qui nécessitait glibc-2.14, mais je n'avais pas accès à la source et ne pouvais pas la reconstruire. J'ai essayé beaucoup de choses et rien n'a fonctionné.

ma solution était de lancer le service sur Amazon Elastic Beanstalk et juste de fournir une interface API.

0
répondu idrinkpabst 2013-07-13 01:38:54
la source

Autres questions sur