ARM编译错误,VFP注册由可执行文件使用,而不是目标文件

时间:2012-03-17 21:09:57

标签: gcc compilation arm

过去几天我一直遇到这个问题,我无法理解这里真正发生的事情,或者问题是什么。

我有一个包含这些标志的makefile:

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时,我得到另一个与浮点寄存器有关的错误。

有没有人知道造成这种情况的原因,以及我可以做些什么来解决这个问题,比如让我的可执行文件不使用Virtual Floating Point Register参数?

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

11 个答案:

答案 0 :(得分:46)

您的目标三元组表示您的编译器已配置为 hard-float ABI。这意味着libgcc库也将是hardfp。错误消息表明至少部分系统正在使用 soft-float ABI。

如果编译器启用了multilib(你可以告诉-print-multi-lib)那么你可以使用-mfloat-abi=softfp,但如果没有,则该选项对你没有多大帮助:gcc将很乐意生成softfp代码,但是没有兼容的libgcc可以链接。

基本上,hardfp和softfp不兼容。您需要以某种方式配置整个系统。

编辑:一些发行版是或将是“multiarch”。如果您有其中一个,那么可以同时安装两个 ABI,但这是通过将所有内容加倍来完成的 - 兼容性问题仍然存在。

答案 1 :(得分:14)

我发现在一个arm hardfloat系统中,glibc binutils和gcc被交叉编译,使用gcc会产生同样的错误。

通过将-mfloat-abi=hard导出到标志来解决,然后gcc编译没有错误。

答案 2 :(得分:4)

此外,可以通过添加多个标志来解决错误,例如-marm -mthumb-interwork。对我来说避免同样的错误是有帮助的。

答案 3 :(得分:3)

这是猜测,但您可能还需要为链接阶段提供部分或全部浮点相关开关。

答案 4 :(得分:3)

我在STM32F4上使用Atollic for ARM遇到了这个问题(我猜它适用于所有带FPU的STM32)。

使用SW浮点对我来说效果不佳(因此编译正确)。

当STM32cubeMX为TrueStudio(Atollic)生成代码时,它不会在C / C ++构建设置中设置FPU单元(不确定是否为其他IDE生成了代码)。

“目标”中设置FPU(在项目属性构建设置下):

  • 汇编
  • C编译器
  • C Linker

然后您可以选择混合HW / SW fp或使用HW。

为此目标添加生成的命令行:

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

答案 5 :(得分:2)

使用相同的编译器选项进行链接。

示例:

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

答案 6 :(得分:2)

就我而言,CFLAGS = -O0 -g -Wall -I. -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=soft有所帮助。如您所见,我将它用于我的stm32f407。

答案 7 :(得分:2)

我遇到了同样的问题。我正在尝试为Cyclone V FPGA-SoC构建linux应用程序。我遇到了如下问题:

Error: <application_name> uses VFP register arguments, main.o does not

我使用的是altera的嵌入式软件设计工具提供的工具链mfloat-abi=hard

通过导出解决: arm-linux-gnueabihf-g++到标志,然后CC编译没有错误。还包括LD和{}中的标志。 {{1}}。

答案 8 :(得分:0)

在我的特定情况-g -march=armv7-a -mfloat-abi=hard -mfpu=neon -marm -mthumb-interwork工作。

答案 9 :(得分:0)

此答案可能在表面上显示为无关,但此错误消息存在间接原因。

首先,“使​​用VFP寄存器...”错误消息是由于在构建中混合使用mfloat-abi = soft和mfloat-abi = hard选项而引起的。对于要链接的所有对象,此设置必须一致。这一事实在这个问题的其他答案中得到了很好的阐述。

此错误的间接原因可能是由于Eclipse编辑器对项目的“.cproject”文件中的自身错误感到困惑。 Eclipse编辑器经常重新调用文件链接,有时当您更改目录结构或文件位置时,它会自行中断。这也会影响gcc编译器的路径设置 - 并且只会影响项目文件的子集。虽然我还不确定是什么原因造成这种失败,但用备份副本替换.cproject文件可以解决这个问题。在我的情况下,我注意到添加了一个包含目录路径并开始接收“VFP寄存器错误”消息后出现了.java.null.pointer错误。在构建日志中,我注意到gcc编译器的不同路径被用于工作区本地的一些源,但不是全部!由于未知原因,两个gcc编译器使用了不同的浮点设置 - 因此VFP寄存器错误。

我将.cproject设置与较旧的副本进行了比较,并观察到导致问题的源的条目差异 - 即使已禁用项目设置的覆盖。通过用旧版本替换.cproject文件,问题就消失了,我将这个答案留下来作为发生事件的提醒。

答案 10 :(得分:0)

“请注意,硬浮和软浮ABI不兼容链接;您必须使用相同的ABI编译整个程序,并使用一组兼容的库进行链接。” https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html arm-none-eabi-gcc.exe

Silicon Labs“ kjostera”“雇员”对EFR32 Flex Gecko(交叉引用Cortex-M4F)的回应:“因此,使用softfp ABI编译的代码与使用hardfp ABI编译的代码在链接时间上不兼容。因此,由于我们目前仅支持RAIL使用softfp ABI编译的库,这意味着您还必须使用softfp ABI来构建应用程序。” “请注意,使用softfp ABI并不意味着您的代码不能使用FPU指令。任何进行浮点运算的代码都将在编译器认为有意义的情况下使用FPU。” 然后,“ kjostera”继续说明GCC 7为-mfloat-abi=softfp-mfloat-abi=hard的情况生成了程序集,调用了vmul.f32指令,并且{{1 }}和softfp的9。 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