Le déploiement de Yessod de Heroku, ne peut pas construire de façon statique
Je suis très nouveau à Yesod et je vais avoir du mal à constituer Yessod de manière statique
donc, je peux déployer sur 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 n'est plus construit. Je reçois tout un tas de mises en garde 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 s'appuie bien, mais l'application se bloque lorsqu'il 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.donc.10 à la 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érentes. J'ai essayé aussi d'ajouter de la libc pour le lot des bibliothèques de l'
même que j'ai fait, pour libgmp mais cela entraîne une erreur de segmentation
lorsque l'application démarre sur le Heroku côté.
Tout fonctionne bien sur mon PC. Je suis sous archlinux 64 bits avec ghc
7.0.3. Le billet de blog sur le site officiel Yesod blog avait l'air 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 bâtiment statiquement je suis ouvert à ça aussi.
MODIFIER
Par Employed Russians
réponse j'ai fait les opérations suivantes pour résoudre ce problème.
D'abord créé un nouveau répertoire lib
sous le répertoire de projet et copié le manque des bibliothèques partagées en elle. Vous pouvez obtenir cette information en cours d'exécution ldd path/to/executable
et heroku run ldd path/to/executable
et en comparant la sortie.
Puis j'ai fait un heroku config:add LD_LIBRARY_PATH=./lib
ainsi, lorsque l'application est démarrée à l'éditeur de liens dynamique va chercher les bibliothèques dans le nouveau répertoire lib.
Enfin, j'ai créé un ubuntu 11.10 de la machine virtuelle et construit et déployé sur Heroku à partir de là, ce qui a un assez vieux glibc qu'il fonctionne sur le Heroku hôte.
Edit:
Depuis, j'ai écrit un tutoriel sur la Yesod wiki
Vous devez vous connecter pour publier un commentaire.
Je n'ai aucune idée de ce que Yessod est, mais je sais exactement ce que chacun de vos erreurs d'autres moyens.
Tout d'abord, vous devez pas essayer de lier statiquement. L'avertissement que vous obtenez est tout à fait exact: si vous lier statiquement, et d'utiliser l'une des routines pour laquelle vous obtenez le message d'avertissement, puis vous devez prendre des dispositions pour s'exécuter sur un système avec exactement la même version de la libc.donc.6 comme celle que vous avez utilisée au moment de la construction.
Contrairement à la croyance populaire, la liaison statique produit moins, pas plus, portable exécutables sous Linux.
Vos autres (statique) lien erreurs sont causées par le manque de
libopenssl.a
au moment de la liaison.Mais supposons que vous allez y aller, la "saine" de l'itinéraire, et d'utiliser la liaison dynamique.
Pour la liaison dynamique, Linux (et la plupart des autres systèmes Unix) une compatibilité descendante: un vieux binaire continue à travailler sur de nouveaux systèmes. Mais ils ne supportent pas que la compatibilité ascendante (binaire construit un nouveau système sera généralement pas fonctionner sur une version plus ancienne).
Mais c'est ce que vous essayez de faire: vous construit sur un système avec glibc-2.14 (ou plus récent), et vous êtes en cours d'exécution sur un système avec glibc-2.13 (ou plus).
L'autre chose que vous devez savoir, c'est que la glibc est composé de quelque 200+ binaires qui doivent tous correspondre exactement. Deux clés binaires sont
/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 fichiers sont venus de différentes versions de la glibc, vous obtenez généralement un crash. Et c'est exactement ce que vous avez, lorsque vous avez essayé de placer votre version de la glibc-2.14libc.so.6
sur leLD_LIBRARY_PATH
-- il ne correspond plus au système/lib/ld-linux
.Alors, quelles sont les solutions? Il y a plusieurs possibilités (en difficulté croissante):
Vous pouvez copier
ld-2.14.so
(la cible de/lib/ld-linux
lien symbolique) vers le système cible, et à l'appeler explicitement:En général, cela fonctionne, mais peut confondre une application qui ressemble à
argv[0]
, et les pauses pour les applications qui re-exec eux-mêmes.Vous pouvez construire sur un système plus ancien.
Vous pouvez utiliser
appgcc
(cette option a disparu, voir cette pour la description de ce qu'il était).Vous pourriez mettre en place un environnement de chroot correspondant au système cible, et de construire à l'intérieur que l'environnement chroot.
Vous pouvez construire vous-même un Linux-à-olderLinux crosscompiler
ld-2.14.so
dans mon heroku construire aveclibc.so.6
etlibgmp.so.10
de mon système et a changé le heroku commande exécuter pour celui que vous avez spécifié. Désormais, l'application se bloque en mode silencieux (au moins il n'y a pas de sortie de l'accident dans le heroku les journaux, à l'état de simples changements de départ s'est écrasé). Si je lanceheroku run ./lib/ld-linux-x86-64.so.2 --list /path/to/executable
toutes les dépendances de la bibliothèque sont remplis, mais la plupart sont satisfaits par le système de bibliothèques. Dois-je copier tous bibliothèques de l'utilisation par l'application de mon système?-static
et amis, GHC regroupera le GHC RTS avec votre exécutable (dont vous avez besoin, depuis Heroku n'a sans doute pas le GHC runtime disponible comme une lib), sauf si vous explicitement compiler avec l'-dynamic
drapeau. Par défaut, les bibliothèques utilisé par la RTS sont appréciés de façon dynamique, ce qui serait bon pour votre cas. Voir aussi: stackoverflow.com/questions/699908/...libc
est plus récente que celle que sur le Heroku hôtes, commeEmployed Russian
suggéré.ldd theproducedbinary
devrait montrernot a dynamic executable
et dépendent donc pas de.so
fichiers à tous, et il ne doit pas être tous les avertissements commewarning: Using '...' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
; cela peut être réalisé par exemple en utilisantmusl
au lieu deglibc
. Si elles sont vraies, alors statiquement exécutables sont beaucoup plus portable.musl
?Vous avez plusieurs questions.
Vous ne devriez pas construire de production binaires sur la pointe des distributions. Les bibliothèques sur le système de production ne sera pas compatible.
Vous ne devriez pas le lien de la glibc, de manière statique, il sera toujours au moment de l'exécution essayez de charger d'autres bibliothèques. Par exemple processeur de l'assemblée. Qu'est-ce que votre premier avertissements sont sur.
Le dernier éditeur de liens erreurs se ressemblent, ils sont liés à un manque bibliothèque openssl sur la ligne de commande.
Mais dans l'ensemble - downgrade de votre distribution.
J'ai eu des problèmes similaires, lancement de Heroku (qui utilise la glibc-2.11) où j'ai eu une demande qui exige de la glibc, 2.14, mais je n'ai pas accès à la source et ne pouvait pas re-construire. J'ai essayé beaucoup de choses et rien n'a fonctionné.
Ma solution est de lancer le service sur Amazon Elastic Beanstalk et il suffit de fournir une interface API.