2017-01-01 2 views
3

Lorsque vous utilisez ce qui suit dans mon stack.yaml à (tentative) de compiler un binaire statique par Stack:Haskell Stack statique déplacement binaire R_X86_64_32 contre `__TMC_END__ » ne peut pas être utilisé lors d'un objet partagé

ghc-options: 
    "*": -static -optc-static -optl-static -optl-pthread -fPIC 

Je reçois cette erreur:

usr/bin/ld: /usr/lib/gcc/x86_64-amazon-linux/4.8.3/crtbeginT.o: relocation R_X86_64_32 against `__TMC_END__' can not be used when making a shared object; recompile with -fPIC 
/usr/lib/gcc/x86_64-amazon-linux/4.8.3/crtbeginT.o: could not read symbols: Bad value 
collect2: error: ld returned 1 exit status 
`gcc' failed in phase `Linker'. (Exit code: 1) 

J'utilise la pile avec docker activé et une image Linux Amazon sur mesure pour la construction d'un binaire statique pour une utilisation avec AWS Lambda.

Je n'ai aucune expérience antérieure avec la compilation binaire statique, donc je suis un peu perplexe sur cette erreur de l'éditeur de liens. Des idées s'il vous plaît?

est ici les args utilisant gcc -v:

/usr/bin/gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-Wl,--hash-size=31' -Wl,--reduce-memory-overheads -Wl,--no-as-needed -Wl,-rpath<snipped LOADS> -lHSghc<SNIPPED LOADS> -lpq -lz -lrt -lutil -ldl -lgmp 
+2

Il serait utile si vous pouviez fournir l'invocation 'gcc' défaillante. Ajouter probablement '-v' à cette ligne' ghc-options' le ferait. –

+1

quelque chose comme ça? https://ghc.haskell.org/trac/ghc/ticket/12759 – d8d0d65b3f7cf42

+0

Hmm, est-ce un bug alors? Mise à jour post avec appel gcc –

Répondre

3

@Reid Barton est juste, en ce qui concerne la cause du problème. Le vrai problème ici est que la pile construit un binaire partagé par défaut. En passant les options -static ou ghc-options: -optl-static nous adressons seulement respectivement la couche ghc et la couche ld.

stack 
|_ cabal 
     |_ ghc 
      |_ gcc 
       |_ ld (linker) 

La bonne façon de résoudre le problème est de dire cabale que nous voulons un binaire statique, comme il pilote la construction.

La réponse sur la façon de faire qui a été fourni par sausade sur reddit: il vous suffit d'ajouter ce qui suit à votre fichier .cabal dans la section exécutable:

directive: 

`ld-options: -static` 

Cela allusion à la cabale que nous voulons un binaire statique et ainsi il ne passera pas -shared à ghc.

Donc, une fois que vous avez ajouté cette directive dans votre fichier cabale, il vous suffit de lancer:

stack install --ghc-options="-fPIC"

et le tour est joué!

PS: Si vous ne disposez pas de bibliothèques statiques sur votre système (comme avec Archlinux) ld vont passer en mode à dynamique reliant


Réponse précédente:

C'est un vieux problème gcc que personne ne soin de réparer. https://bugs.launchpad.net/ubuntu/+source/gcc-4.4/+bug/640734

Pour votre problème d'origine, voici deux liens utiles pour vous montrer comment le faire:

2

Je devine ici un peu, mais je pense que c'est juste un cas de casser des choses en allant derrière le dos du système de construction.

Il est faux d'écrire

ghc-options: 
    "*": -static 

parce que le choix de construire des bibliothèques dynamiques ou statiques a des répercussions sur la façon dont le reste de la construction doit aller. Ici, on dirait que Stack ou Cabal a dit ghc pour construire une bibliothèque dynamique et ce drapeau a dépassé votre tentative de définir -static. Par conséquent gcc a probablement fini avec la combinaison d'options -shared -static qui a conduit au bug mentionné dans la réponse d'Erèbe. (Si votre drapeau -static avait gagné plus de -dynamic, alors ghc aurait pu réussir à construire une bibliothèque statique mais alors Stack/Cabal serait probablement confus sur ce qu'il faut faire ensuite.)

La bonne façon de le faire est de ne pas utiliser -static dans ghc-options, mais à la place dire à Stack de ne pas construire une bibliothèque partagée en premier lieu. Je ne sais pas comment vous faites ça dans Stack, mais le drapeau de la Cabale est --disable-shared.