Je rencontre ce problème depuis quelques jours et je n'arrive pas à comprendre ce qui se passe réellement ici ou quel est le problème.
J'ai un fichier makefile avec ces drapeaux:
CC = arm-linux-gnueabihf-gcc-4.6
FLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -ftree-vectorize -mfloat-abi=softfp -std=gnu99
J'ai une bibliothèque dans un fichier .a, qui contient des fichiers objets. Tout ce que j'ai à faire, c'est de les relier à mon exécutable. Je connais les prototypes et tout ça, la seule chose à se plaindre est la suivante:
/usr/bin/ld: error: *EXECUTABLE* uses VFP register arguments, *OBJECTFILE* does not
/usr/bin/ld: failed to merge target specific data of file *OBJECTFILE*
Lorsque je n'utilise pas l'option -mfloat-abi = softfp, j'obtiens une autre erreur relative aux registres à virgule flottante.
Quelqu'un a-t-il une idée de ce qui est à l'origine de ce problème et de ce que je peux faire pour le résoudre, par exemple en faisant en sorte que mon exécutable n'utilise pas les arguments du registre de virgule flottante virtuelle?
x@x:~/Desktop/perf_test$ make
arm-linux-gnueabihf-gcc-4.6 -c -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -ftree-vectorize -std=gnu99 -mfloat-abi=softfp perf_test.c ../baseline/util.c
arm-linux-gnueabihf-gcc-4.6 -o perf_test perf_test.o util.o ../baseline/lib.a
/usr/bin/ld: error: perf_test uses VFP register arguments, perf_test.o does not
/usr/bin/ld: failed to merge target specific data of file perf_test.o
/usr/bin/ld: error: perf_test uses VFP register arguments, util.o does not
/usr/bin/ld: failed to merge target specific data of file util.o
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(a.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(a.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(b.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(b.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(c.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(c.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(d.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(d.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(e.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(e.o)
/usr/bin/ld: error: perf_test uses VFP register arguments, ../baseline/lib.a(f.o) does not
/usr/bin/ld: failed to merge target specific data of file ../baseline/lib.a(f.o)
collect2: ld returned 1 exit status
make: *** [perf_test] Error 1
Votre triplet cible indique que votre compilateur est configuré pour le répertoire hard-float ABI. Cela signifie que la bibliothèque libgcc sera également hardfp. Le message d'erreur indique qu'au moins une partie de votre système utilise soft-float ABI.
Si le compilateur a activé multilib (vous pouvez le savoir avec -print-multi-lib
), vous pouvez utiliser -mfloat-abi=softfp
, mais sinon, cette option ne vous aidera pas beaucoup: gcc générera du code softfp, mais il n'y aura pas de libgcc compatible contre.
Fondamentalement, hardfp et softfp ne sont tout simplement pas compatibles. Vous devez configurer tout votre système dans un sens ou dans l’autre.
EDIT: certaines distributions sont, ou seront "multiarch". Si vous en avez un, il est possible d'installer les deux ABI à la fois, mais pour ce faire, il faut tout doubler - les problèmes de compatibilité persistent.
J'ai trouvé sur un système de bras flottant où glibc binutils et gcc étaient compilés de manière croisée, l'utilisation de gcc donne la même erreur.
Pour le résoudre, exportez-mfloat-abi=hard
en drapeaux, puis gcc sera compilé sans erreur.
De plus, l'erreur peut être résolue en ajoutant plusieurs indicateurs, comme -marm -mthumb-interwork
. Cela m'a été utile d'éviter cette même erreur.
C'est une conjecture, mais vous devrez peut-être fournir tout ou partie des commutateurs liés à la virgule flottante pour l'étage de liaison.
Dans mon cas, CFLAGS = -O0 -g -Wall -I. -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=soft
a aidé. Comme vous pouvez le constater, je l’ai utilisé pour mon stm32f407.
J'ai rencontré le problème en utilisant Atollic pour ARM sur STM32F4 (je suppose que cela s'applique à tous les STM32 avec FPU).
L’utilisation de virgule flottante SW ne fonctionnait pas bien pour moi (donc, compiler correctement).
Lorsque STM32cubeMX génère du code pour TrueStudio (Atollic), il ne définit pas une unité FPU dans les paramètres de construction C/C++ (vous n'êtes pas sûr du code généré pour d'autres IDE).
Définissez une FPU dans "Target" pour (sous les paramètres de construction du projet propriétés):
Ensuite, vous avez le choix de mélanger HW/SW fp ou d’utiliser HW.
Les lignes de commande générées sont ajoutées à cela pour la cible visée:
-mfloat-abi=hard -mfpu=fpv4-sp-d16
Utilisez les mêmes options du compilateur pour lier également.
Exemple:
gcc -mfloat-abi=hard fpu=neon -c -o test.cpp test.o
gcc -mfloat-abi=hard fpu=neon -c test1.cpp test1.o
gcc test.o test1.o mfloat-abi=hard fpu=neon HardTest
Je faisais face au même problème. J'essayais de construire une application Linux pour Cyclone V FPGA-SoC. J'ai fait face au problème ci-dessous:
Erreur: <nom_application> utilise les arguments du registre VFP, contrairement à main.o
J'utilisais la chaîne d'outils arm-linux-gnueabihf-g++
fournie par l'outil de conception de logiciel intégré d'altera.
Pour le résoudre, exportez: mfloat-abi=hard
en drapeaux, puis arm-linux-gnueabihf-g++
est compilé sans erreur. Incluez également les drapeaux dans CC
& LD
.
Dans mon cas particulier, -g -march=armv7-a -mfloat-abi=hard -mfpu=neon -marm -mthumb-interwork
a fonctionné.
Cette réponse peut sembler à la surface sans relation, mais il existe une cause indirecte à ce message d'erreur.
Tout d'abord, le message d'erreur "Utilise le registre VFP ..." provient directement du mélange des options mfloat-abi = soft et mfloat-abi = hard dans votre construction. Ce paramètre doit être cohérent pour tous les objets à lier. Ce fait est bien couvert dans les autres réponses à cette question.
La cause indirecte de cette erreur peut être due à la confusion de l'éditeur Eclipse par une erreur auto-infligée dans le fichier ".cproject" du projet. L'éditeur Eclipse reswizzle fréquemment les liens de fichiers et il se casse parfois lorsque vous apportez des modifications à la structure de vos répertoires ou à l'emplacement de vos fichiers. Cela peut également affecter les paramètres de chemin d'accès à votre compilateur gcc - et uniquement pour un sous-ensemble des fichiers de votre projet. Bien que je ne sois pas encore sûr de la cause exacte de cet échec, le remplacement du fichier .cproject par une copie de sauvegarde a corrigé ce problème. Dans mon cas, j’ai remarqué des erreurs .Java.null.pointer après l’ajout d’un chemin de répertoire d’inclusion et commencé à recevoir les messages «Erreur de registre VFP». Dans le journal de construction, j'ai remarqué qu'un chemin différent vers le compilateur gcc était utilisé pour certaines de mes sources locales, mais pas toutes!!? Les deux compilateurs gcc utilisaient des paramètres float différents pour des raisons inconnues - d’où l’erreur de registre VFP.
J'ai comparé les paramètres de .cproject avec une copie plus ancienne et observé des différences dans les entrées des sources à l'origine du problème, même si le remplacement des paramètres du projet était désactivé. En remplaçant le fichier .cproject par l'ancienne version, le problème a disparu et je laisse cette réponse pour rappeler ce qui s'est passé.