Ошибка компиляции 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, я получаю еще одну ошибку, связанную с регистрами с плавающей запятой.
Кто-нибудь знает, что является причиной этого, и что я могу сделать, чтобы исправить это, например, сделать так, чтобы мой исполняемый файл не использовал аргументы Виртуального регистра с плавающей запятой?
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
13 ответов
Ваш целевой триплет указывает, что ваш компилятор настроен для жесткого плавающего ABI. Это означает, что библиотека libgcc также будет hardfp. Сообщение об ошибке указывает, что по крайней мере часть вашей системы использует программный интерфейс с плавающей запятой.
Если компилятор включил мультибиблиотеку (вы можете сказать с -print-multi-lib
) тогда вы можете использовать -mfloat-abi=softfp
, но если нет, то эта опция вам не очень поможет: gcc с радостью сгенерирует код softfp, но тогда не будет совместимого libgcc для ссылки.
По сути, hardfp и softfp просто не совместимы. Вам нужно настроить всю систему так или иначе.
РЕДАКТИРОВАТЬ: некоторые дистрибутивы являются или будут "многоархивом". Если у вас есть один из них, то можно установить оба ABI одновременно, но это делается путем удвоения всего - проблемы совместимости все еще существуют.
Я обнаружил в системе hardfloat, где glibc binutils и gcc были скомпилированы, использование gcc дает ту же ошибку.
Это решается путем экспорта-mfloat-abi=hard
на флаги, то gcc компилируется без ошибок.
Также ошибка может быть решена путем добавления нескольких флагов, таких как -marm -mthumb-interwork
, Мне было полезно избежать этой же ошибки.
В моем случае CFLAGS = -O0 -g -Wall -I. -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=soft
помогло. Как вы можете видеть, я использовал его для моего stm32f407.
Это догадка, но вам может потребоваться предоставить некоторые или все связанные с плавающей запятой переключатели для стадии соединения.
Я столкнулся с проблемой использования Atollic для ARM на STM32F4 (я думаю, это относится ко всем STM32 с FPU).
Использование плавающей запятой SW не помогло мне (поэтому компилируется правильно).
Когда STM32cubeMX генерирует код для TrueStudio (Atollic), он не устанавливает модуль FPU в настройках сборки C/C++ (не уверен в сгенерированном коде для других IDE).
Установите FPU в "Target" для (в настройках сборки свойств проекта):
- ассемблер
- Компилятор Си
- C Linker
Тогда у вас есть выбор, чтобы смешать HW/SW fp или использовать HW.
Сгенерированные командные строки добавляются с этим для намеченной цели:
-mfloat-abi=hard -mfpu=fpv4-sp-d16
Я столкнулся с той же проблемой. Я пытался собрать приложение Linux для Cyclone V FPGA-SoC. Я столкнулся с проблемой, как показано ниже:
Ошибка:использует аргументы регистра VFP, main.o не
Я использовал набор инструментов arm-linux-gnueabihf-g++
обеспечивается встроенным программным обеспечением для проектирования инструмента altera.
Это решается путем экспорта:mfloat-abi=hard
на флаги, то arm-linux-gnueabihf-g++
компилируется без ошибок. Также включите флаги в оба CC
& LD
,
Используйте те же параметры компилятора для ссылок также.
Пример:
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
Этот ответ может показаться на поверхности несвязанным, но существует косвенная причина этого сообщения об ошибке.
Во-первых, сообщение об ошибке "Использование регистра VFP..." напрямую вызвано смешиванием опций mfloat-abi=soft и mfloat-abi=hard в вашей сборке. Этот параметр должен быть согласован для всех объектов, которые должны быть связаны. Этот факт хорошо освещен в других ответах на этот вопрос.
Косвенная причина этой ошибки может быть из-за того, что редактор Eclipse запутался из-за собственной ошибки в файле проекта.cproject. Редактор Eclipse часто перезаписывает ссылки на файлы, а иногда разрывается, когда вы вносите изменения в структуру каталогов или расположение файлов. Это также может повлиять на настройки пути к вашему компилятору gcc - и только для подмножества файлов вашего проекта. Хотя я пока не уверен, что именно является причиной этой ошибки, замена файла.cproject резервной копией исправила эту проблему для меня. В моем случае я заметил ошибки.java.null.pointer после добавления пути к каталогу включений и начал получать сообщения "Ошибка регистрации VFP" совершенно неожиданно. В журнале сборки я заметил, что для некоторых из моих источников, локальных по отношению к рабочему пространству, использовался другой путь к компилятору gcc!? Два компилятора gcc использовали разные настройки float по неизвестным причинам - отсюда ошибка регистра VFP.
Я сравнил настройки.cproject со старой копией и обнаружил различия в записях для источников, вызывающих проблему - даже если переопределение настроек проекта было отключено. Заменив файл.cproject старой версией, проблема исчезла, и я оставляю этот ответ как напоминание о том, что произошло.
В моем конкретном случае -g -march=armv7-a -mfloat-abi=hard -mfpu=neon -marm -mthumb-interwork
работал.
Другая причина этой проблемы заключается в том, что вы пропустили спецификацию архитектуры процессора конечной двоичной цели.
Например, даже если ваш
-mfloat-abi
а также
-mfpu
переключатели согласуются между всеми модулями и окончательным двоичным кодом, вы все равно можете запутаться
-mcpu
.
В моем случае, опуская
-mcpu=cortex-m4
для окончательного двоичного файла компоновщик по умолчанию использовал другую архитектуру процессора. Это также привело к тому же сообщению о регистрах VFP.
"Обратите внимание, что ABI с жесткой плавающей точкой и с мягкой плавающей точкой несовместимы с компоновкой; вы должны скомпилировать всю свою программу с одним и тем же ABI и скомпилировать с совместимым набором библиотек". https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.htmlarm-none-eabi-gcc.exe
Ответ Silicon Labs "kjostera" "Сотрудник" на EFR32 Flex Gecko (перекрестная ссылка Cortex-M4F): "Таким образом, код, скомпилированный с помощью softfp ABI, несовместим по времени компоновки с кодом, скомпилированным с помощью hardfp ABI. Итак, поскольку в настоящее время мы поддерживаем только библиотеку RAIL, скомпилированную с использованием ABI softfp, это означает, что вам также придется создавать свое приложение, используя ABI softfp ". "Обратите внимание, что использование softfp ABI не означает, что ваш код не может использовать инструкции FPU. Любой код, выполняющий арифметические операции с плавающей запятой, будет использовать FPU, когда компилятор сочтет это целесообразным". Затем "kjostera" демонстрирует, что GCC 7 сгенерировал Assembly для обоих случаев
-mfloat-abi=softfp
и
-mfloat-abi=hard
, то
vmul.f32
вызывается инструкция, и количество инструкций равно 10 для
softfp
и 9 для
hard
.https://www.silabs.com/community/mcu/32-bit/forum.topic.html/enable_fpu_in_rail-p-SEYr https://www.silabs.com/documents/public/data-sheets/efr32fg1-datasheet.pdf https://www.silabs.com/documents/public/reference-manuals/efr32xg12-rm.pdf https://www.silabs.com/documents/public/reference-manuals/efr32xg13-rm.pdf https://www.silabs.com/documents/public/reference-manuals/efr32xg14-rm.pdf
У меня была аналогичная проблема из-за статической привязки моего проекта к какой-то внешней библиотеке для Raspberry. Любой из упомянутых вариантов компилятора может помочь. Сравнивая результаты readelf моих объектных файлов и объектных файлов статической библиотеки, которую я связывал, я решил использовать другой кросс-компилятор. С теми же параметрами компилятора, которые я использовал, как и раньше, проблема больше не возникала. Так что, возможно, вам просто нужно использовать правильный кросс-компилятор, поддерживающий правильную версию ABI.
Подсказка: версия ABI закодирована в имени компилятора на вашем хосте.