référence indéfinie à l’erreur __sync_val_compare_and_swap_4 lors de la compilation, à l’aide de gcc 4.1.1 et 4.2.0 pour la cible Sparc v8

À l’ aide de scripts crosstool , j’ai compilé sous Cygwin les compilateurs suivants gcc-4.1.1 et 4.2.0 20061024 (version préliminaire) pour l’architecture Sparc:

$ ./sparc-unknown-linux-gnu-gcc -v Using built-in specs. Target: sparc-unknown-linux-gnu Configured with: /crosstool-0.43/build/sparc-unknown-linux-gnu/gcc-4.1.1-glibc-2.3.6/gcc-4.1.1/configure --target=sparc-unknown-linux-gnu --host=i686-host_pc-cygwin --prefix=/opt/crosstool/gcc-4.1.1-glibc-2.3.6/sparc-unknown-linux-gnu --with-headers=/opt/crosstool/gcc-4.1.1-glibc-2.3.6/sparc-unknown-linux-gnu/sparc-unknown-linux-gnu/include --with-local-prefix=/opt/crosstool/gcc-4.1.1-glibc-2.3.6/sparc-unknown-linux-gnu/sparc-unknown-linux-gnu --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long Thread model: posix gcc version 4.1.1 

et

 $ ./sparc-unknown-linux-gnu-gcc -v Using built-in specs. Target: sparc-unknown-linux-gnu Configured with: /crosstool-0.43/build/sparc-unknown-linux-gnu/gcc-4.2-20061024- glibc-2.3.6/gcc-4.2-20061024/configure --target=sparc-unknown-linux-gnu --host=i 686-host_pc-cygwin --prefix=/opt/crosstool/gcc-4.2-20061024-glibc-2.3.6/sparc-un known-linux-gnu --with-headers=/opt/crosstool/gcc-4.2-20061024-glibc-2.3.6/sparc -unknown-linux-gnu/sparc-unknown-linux-gnu/include --with-local-prefix=/opt/cros stool/gcc-4.2-20061024-glibc-2.3.6/sparc-unknown-linux-gnu/sparc-unknown-linux-g nu --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atex it --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long Thread model: posix gcc version 4.2.0 20061024 (prerelease) 

Il est nécessaire pour moi que je puisse utiliser dans mes programmes la fonction __sync_val_compare_and_swap associée à Atomic-Builtins , qui prend en charge la version 4.1. * De gcc.

J’essaie de comstackr du code C simple:

 long cmpxchg( long* value, long comp_val, long new_val ) { return __sync_val_compare_and_swap( value, comp_val, new_val ); } int main() { return 0; } 

Mais j’ai l’erreur suivante: (sur les deux compilateurs):

 $ ./sparc-unknown-linux-gnu-gcc test_cas.c -o test_cas /tmp/ccREXHsP.o: In function `cmpxchg': test_cas.c:(.text+0x24): undefined reference to `__sync_val_compare_and_swap_4' collect2: ld returned 1 exit status 

Quel est le problème? Peut-être que je me trompe de compilateurs Peut-être que l’architecture Sparc (SPARC v8) ne prend pas en charge cette fonctionnalité? J’ai essayé de comstackr mes autres programmes – tous bons (compilés et exécutés).

    Comme décrit ici: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html __sync_val_compare_and_swap sur certaines cibles donnera lieu à un appel de fonction (lorsque la génération directe de code n’est pas disponible ou pas encore mis en œuvre). Cela se passe dans votre cas. En supposant que cela ne soit pas un problème pour vous, vous devez ensuite lier la bibliothèque qui définit __sync_val_compare_and_swap_4 et ses amis, ce qui, je suppose, est libgcc_s (ajoutez donc -lgcc_s à votre ligne de lien).

    Il semble y avoir un bug lié à gcc:

    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40134

    Peut-être essayer un nouveau gcc?

    Je suis tombé sur un problème similaire lors de la compilation de NodeJS (basé sur le moteur V8) sur la plate-forme ARMv5.

    En gros, votre GCC n’a pas cette fonction intégrée, soit parce que vous utilisez une ancienne version, soit parce que ces fonctions ne sont pas encore implémentées sur votre plate-forme. Il est donc possible que le “-lgcc_s” n’aide pas.

    Après Google pendant des heures, j’ai trouvé cette page de blog ( http://vincesoft.blogspot.fr/2012/04/how-to-solve-undefined-reference-to.html ), qui explique la cause de manière assez claire et a donné une solution :

    Saisissez le code source de votre plate-forme avec ces fonctions à partir du code GCC, générez le code dans une bibliothèque, installez-la, puis liez vos applications à cette bibliothèque.

    Je n’ai pas suivi les procédures exactes décrites dans ce blog, mais l’idée est la même et ça marche.

    J’espère que ça aide.

    sur Android, j’ai pu résoudre le problème avec les drapeaux suivants LOCAL_CFLAGS + = -O3 -fopenmp LOCAL_LDFLAGS + = -O3 -fopenmp -lgcc -latomic -lgomp

    Pour moi, l’échec ci-dessus signifiait “vous utilisez un compilateur croisé gcc / mingw, alors -march = native ne fonctionne pas” (je suppose). Voir https://stackoverflow.com/a/24213278/32453 (vous pouvez en principe le contourner en spécifiant manuellement le paramètre -march).