Подтвердить что ты не робот

Ошибка компиляции ARM, зарегистрированный VFP, используемый исполняемым файлом, а не объектным файлом

У меня была эта проблема в течение последних нескольких дней, и я не могу понять, что на самом деле происходит здесь, или в чем проблема.

У меня есть make файл с этими флагами:

CC = arm-linux-gnueabihf-gcc-4.6
FLAGS = -O3 -march=armv7-a -mtune=cortex-a9 -mfpu=neon -ftree-vectorize -mfloat-abi=softfp -std=gnu99

У меня есть библиотека в файле .a, в которой есть некоторые объектные файлы, все, что мне нужно сделать, это связать их с моим исполняемым файлом. Я знаю прототипы и все такое, единственное, что жалуется, следующее:

/usr/bin/ld: error: *EXECUTABLE* uses VFP register arguments, *OBJECTFILE* does not
/usr/bin/ld: failed to merge target specific data of file *OBJECTFILE*

Когда я не использую -mfloat-abi = softfp, я получаю еще одну ошибку, относящуюся к регистру с плавающей запятой.

Кто-нибудь знает, что вызывает это, и что я могу сделать, чтобы исправить это, например, сделать так, чтобы мой исполняемый файл не использовал аргументы регистра виртуальной плавающей точки?

[email protected]:~/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
4b9b3361

Ответ 1

Твой триплет указывает, что ваш компилятор настроен для ABI с твердым поплавком. Это означает, что библиотека libgcc также будет hardfp. Сообщение об ошибке указывает, что, по крайней мере, часть вашей системы использует ABI с плавающей запятой.

Если компилятор включен с поддержкой multilib (вы можете сказать с помощью -print-multi-lib), вы можете использовать -mfloat-abi=softfp, но если нет, то этот параметр вам не поможет: gcc будет с радостью генерировать код softfp, ll не совместим с libgcc для ссылки.

В принципе, hardfp и softfp просто несовместимы. Вам нужно настроить всю вашу систему так или иначе.

EDIT: некоторые дистрибутивы являются или будут "многоархивовыми". Если у вас есть один из них, тогда можно установить оба ABI сразу, но это делается путем удвоения всего - проблемы совместимости все еще существуют.

Ответ 2

Я обнаружил, что в системе hardfloat для рук, где glibc binutils и gcc были скомбинированы, использование gcc дает ту же ошибку.

Он решается путем экспорта -mfloat-abi=hard в флаги, затем gcc компилируется без ошибок.

Ответ 3

Также ошибка может быть решена путем добавления нескольких флагов, таких как -marm -mthumb-interwork. Мне было полезно избежать этой же ошибки.

Ответ 4

Это догадка, но вам может понадобиться предоставить некоторые или все связанные с плавающей точкой переключатели для этапа ссылки.

Ответ 5

В моем случае CFLAGS = -O0 -g -Wall -I. -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=soft помог. Как вы можете видеть, я использовал его для своего stm32f407.

Ответ 6

Используйте те же параметры компилятора для ссылки.

Пример:

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

Ответ 7

Я столкнулся с проблемой, использующей Atollic для ARM на STM32F4 (я думаю, это относится ко всем STM32 с FPU).

Использование плавающей запятой SW для меня не сработало (таким образом, компиляция правильно).

Когда STM32cubeMX генерирует код для TrueStudio (Atollic), он не устанавливает блок FPU в настройках сборки C/С++ (не уверен в сгенерированном коде для других IDE).

Установите FPU в "Цель" для (в настройках сборки проекта):

  • Ассемблер
  • Компилятор C
  • C Linker

Тогда у вас есть выбор: Смешать HW/SW fp или использовать HW.

Сгенерированные командные строки добавляются с этой целью для целевой цели:

-mfloat-abi=hard -mfpu=fpv4-sp-d16

Ответ 8

В моем конкретном случае -g -march=armv7-a -mfloat-abi=hard -mfpu=neon -marm -mthumb-interwork работал.

Ответ 9

Этот ответ может отображаться на поверхности, чтобы быть несвязанным, но есть косвенная причина этого сообщения об ошибке.

Во-первых, сообщение об ошибке "Uses VFP register..." вызвано непосредственно из смешивания mfloat-abi = soft и mfloat-abi = hard options внутри вашей сборки. Этот параметр должен быть согласован для всех объектов, которые должны быть связаны. Этот факт хорошо освещен в других ответах на этот вопрос.

Непосредственная причина этой ошибки может быть вызвана тем, что редактор Eclipse путается с ошибкой, вызванной самим собой, в файле проекта .cproject. Редактор Eclipse часто переписывает ссылки на файлы, и иногда он ломается, когда вы вносите изменения в структуры каталогов или расположения файлов. Это также может повлиять на настройки пути к вашему gcc-компилятору - и только для подмножества ваших файлов проекта. Хотя я еще не уверен, что именно приводит к этой ошибке, заменив файл .cproject резервной копией, исправил эту проблему для меня. В моем случае я заметил ошибки .java.null.pointer после добавления пути к каталогу include и начал получать сообщения об ошибках регистра VFP. В журнале сборки я заметил, что для некоторых из моих источников, которые были локальными для рабочей области, использовался другой путь к компилятору gcc, но не все из них!? Два компилятора gcc использовали разные настройки поплавка по неизвестным причинам - следовательно, ошибка регистра VFP.

Я сравнивал параметры .cproject со старой копией и наблюдал различия в записи для источников, вызывающих проблемы, даже несмотря на то, что переопределение настроек проекта было отключено. Заменив файл .cproject на старую версию, проблема исчезла, и я оставляю этот ответ как напоминание о том, что произошло.