Erreur de liaison lors de la compilation de l'opération atomique gcc en mode 32 bits

StackOverflow https://stackoverflow.com/questions/130740

  •  02-07-2019
  •  | 
  •  

Question

J'ai le programme suivant:

~/test> cat test.cc
int main()
{
  int i = 3;
  int j = __sync_add_and_fetch(&i, 1);
  return 0;
}

Je compile ce programme à l'aide de GCC 4.2.2 sous Linux s'exécutant sur un ordinateur Intel multi-processeurs 64 bits:

~/test> uname --all
Linux doom 2.6.9-67.ELsmp #1 SMP Wed Nov 7 13:56:44 EST 2007 x86_64 x86_64 x86_64 GNU/Linux

Lorsque je compile le programme en mode 64 bits, il compile et lie bien:

~/test> /share/tools/gcc-4.2.2/bin/g++ test.cc
~/test>

Lorsque je le compile en mode 32 bits, le message d'erreur suivant s'affiche:

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 test.cc
/tmp/ccEVHGkB.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
~/test>

Bien que je ne puisse jamais utiliser de processeur 32 bits, il me faut un exécutable 32 bits pour pouvoir établir une liaison avec des bibliothèques 32 bits.

Mes deux questions sont les suivantes:

  1. Pourquoi une erreur de lien survient-elle lorsque je compile en mode 32 bits?

  2. Existe-t-il un moyen de faire en sorte que le programme soit compilé et lié, tout en restant capable de se lier à une bibliothèque 32 bits?

Était-ce utile?

La solution

Extrait de la page GCC sur Atomic Builtins :

  

Toutes les opérations ne sont pas supportées par   tous les processeurs cibles. Si un particulier   opération ne peut pas être mis en œuvre sur le   processeur cible, un avertissement sera   généré et un appel externe   fonction sera générée. le   fonction externe portera le même   nommer comme intégré, avec un   suffixe additionnel `_n 'où n est le   taille du type de données.

À en juger par la sortie de votre compilateur, qui fait référence à __ sync_add_and_fetch_4 , voici ce qui se passe. Pour une raison quelconque, GCC ne génère pas correctement la fonction externe.

C’est probablement pour cette raison que vous n’obtenez une erreur qu’en mode 32 bits: lors de la compilation en mode 64 bits, la compilation est plus précise pour votre processeur. Lors de la compilation pour 32 bits, il se peut que vous utilisiez un arch générique (i386, par exemple) qui ne prend pas nativement en charge ces fonctionnalités. Essayez de spécifier une architecture spécifique pour votre famille de puces (Xeon, Core 2, etc.) via -mcpu et voyez si cela fonctionne.

Si ce n'est pas le cas, vous devrez comprendre pourquoi GCC n'inclut pas la fonction appropriée qu'il devrait générer.

Autres conseils

La réponse de Dan Udey était proche, suffisamment proche en fait pour me permettre de trouver la vraie solution.

Selon la page de manuel " -mcpu " est un synonyme déconseillé pour "-mtune". et signifie simplement "optimiser pour un processeur particulier (mais toujours fonctionner sur des processeurs plus anciens, bien que moins optimaux)". J'ai essayé ceci et cela n'a pas résolu le problème.

Cependant, "-march =" signifie "générer du code pour un processeur particulier (et ne pas s'exécuter sur des processeurs plus anciens)". Lorsque j’ai essayé, le problème a été résolu: spécifier l’erreur de lien en spécifiant un processeur supérieur ou égal à i486.

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32  test.cc
/tmp/ccYnYLj6.o(.text+0x27): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i386 test.cc
/tmp/ccOr3ww8.o(.text+0x22): In function `main':
: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=i486 test.cc

~/test> /share/tools/gcc-4.2.2/bin/g++ -m32 -march=pentium test.cc
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top