Unable to solve error ".o uses VFP register arguments, .elf does not"

Just as the title says, I’m getting this error after linking against static library. I have already tried the following approach where I run this script from platform.ini:

Import("env")

env.Append(CFLAGS=["-mfloat-abi=soft"])

where I tested all three options (namely soft, softfp and hard). In all cases the build returns same errors. Here is error for one of files from static library which (probably) uses floating-point arithmetic:

c:/users/luka/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: failed to merge target specific data of file src\BSEC\Inc\libalgobsec.a(ExpSmoothing.o)
c:/users/luka/.platformio/packages/toolchain-gccarmnoneeabi@1.70201.0/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: error: src\BSEC\Inc\libalgobsec.a(ExpSmoothingBsec.o) uses VFP register arguments, .pio\build\nucleo_f756zg\firmware.elf does not

Any idea what more can I do?

ADDITIONAL INFO:
I’m trying to successfully build and link the BSEC library for BME6xx sensor. The folder with examples provides the following instructions on how to build and link static library, however I think this platform.txt is relevant only for Arduino platform. Whereas I’m trying to figure out how to translate these build flags to platform.ini.

# Algorithm inclusion
 * The static library path needs to be included in the platform.txt file.
 * In the platforms.txt search ‘recipe.c.combine.pattern’ and adding where your library is located after ‘{object_files}’, just like this:
   recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-Wl,--Map={build.path}/{build.project_name}.map" "-L{compiler.sdk.path}/lib" "-L{compiler.sdk.path}/ld" "-L{compiler.sdk.path}/{build.memory_type}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {build.extra_flags} -Wl,--start-group {object_files} "C:\Users\Name\Documents\Projects\Bsec_Library\libalgobsec.a" "{archive_file_path}" {build.extra_libs} {compiler.c.elf.libs} {compiler.libraries.ldflags} -Wl,--end-group -Wl,-EL -o "{build.path}/{build.project_name}.elf"
 * Configurations can be copied to files Selectivity_Config.c & Selectivity_Config.h which is included by default
 * Note to not change the variable name as they are already linked in the repositrory.
  1. CFLAGS only applies to compiling C files, for such global options you should be using CCFLAGS, applying to both C and C++
  2. You should also add those flags to the linking stage, aka LINKFLAGS

-mfloat-abi is one part, it should be I think either softfp or hard to allow VFP register usage, the other part is setting what FPU you have. For a Cortex-M4 that could e.g. be

but if you work with a Cortex-M7 that argument might be different. Per https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html there are quite some options, but matching it to https://developer.arm.com/documentation/100068/0609/migrating-from-armcc-to-armclang/migrating-architecture-and-processor-names-for-command-line-options leads me to believe that something like

Import("env")
env.Append(
    CCFLAGS=[
        "-mfloat-abi=hard", # or softfp
        "-mfpu=fpv5-sp-d16"
    ],
    LINKFLAGS=[
        "-mfloat-abi=hard", # or softp
        "-mfpu=fpv5-sp-d16"
   ]
)

might work.

I can also recommend reading through

I have tried both approaches and the same errors keep popping up. I have seen these flags as valid solution to other people’s errors but this still doesn’t solve mine. Any further idea what to do would be very much appreciated.

Can you just send me this file and your current platformio.ini?

Was any additional info given as to with which -mfpu setting the file was produced with?

Only what I have given above in the Additional info section. Otherwise not any that I would be aware of. I have searched through what is officially given by Bosch BSEC documents.

I can’t send you libalgobsec.a directly however I can copy-paste extra script I’m using for setting flags and exact .ini file I’m using:

Import("env")

env.Append(
    CCFLAGS=[
        "-mfloat-abi=softfp", # or softfp
        "-mfpu=fpv5-sp-d16",
    ],
    LINKFLAGS=[
        "-mfloat-abi=softfp", # or softp
        "-mfpu=fpv5-sp-d16",
   ]
)
; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:nucleo_f756zg]
platform = ststm32
board = nucleo_f756zg
board_build.ldscript = C:/Repository/Code/VSCode/HMS_v0.1/src/HAL/STM32F756ZGTX_FLASH.ld
extra_scripts = SetFlags.py
build_flags = 
	-Isrc
	-Isrc/include
	-Isrc/HAL/Core/Inc
	-Isrc/HAL/Drivers/CMSIS/Device/ST/STM32F7xx/Include
	-Isrc/HAL/Drivers/CMSIS/Include
	-Isrc/HAL/Drivers/STM32F7xx_HAL_Driver/Inc
	-Isrc/BSEC/Inc
	-Isrc/BSEC/Example
	-Lsrc/BSEC/Inc
	-llibalgobsec
build_src_filter = 
	+<*>
	-<BSEC/Config/**/*.c>
	-<BSEC/Config/**/*.h>
	+<BSEC/Config/bme688_sel_18v_3s_4d/bsec_selectivity.c>
	+<BSEC/Config/bme688_sel_18v_3s_4d/bsec_selectivity.h>

;If including BSEC library here by files wouldn't work, try using BSEC package
;lib_deps = boschsensortec/BSEC Software Library@^1.8.1492

Here is link to libalgobsec.a where all other required files are provided to use this library: GitHub - boschsensortec/Bosch-BSEC2-Library: Arduino library to simplify using Bosch Sensortec's BSEC2 library

And here is link with instructions and examples for use with Arduino: GitHub - boschsensortec/BSEC-Arduino-library: Arduino library for BSEC to simplify integration into compatible platforms. To report issues, go to https://community.bosch-sensortec.com/t5/Bosch-Sensortec-Community/ct-p/bst_community

Note that this example folder doesn’t provide libalgobsec.a for Cortex-M7 core. However the official BSEC software, which can be find here under name BSEC 2.x does provide this file.

Ah, the problem was that the flags have to be set accross all construction environments. Also it must be hard float.

Import("env")
Import("projenv")

for e in [env, projenv, DefaultEnvironment()]:
    e.Append(
        CCFLAGS=[
            "-mfloat-abi=hard",
            "-mfpu=fpv5-sp-d16",
        ],
        LINKFLAGS=[
            "-mfloat-abi=hard",
            "-mfpu=fpv5-sp-d16",
        ]
    )

Worked fine with the basic most

[env:nucleo_f756zg]
platform = ststm32
board = nucleo_f756zg
framework = stm32cube
build_flags =
    -Isrc/BSEC/Inc
    -Lsrc/BSEC
    -lalgobsec
extra_scripts = SetFlags.py

and a src/main.c of just

#include <stm32f7xx_hal.h>
/* BSEC header files are available in the inc/ folder of the release package */
#include "bsec_interface.h"
#include "bsec_datatypes.h"

int main() {
    bsec_version_t ver;
    bsec_get_version(&ver);
    return 0;
}

grafik

1 Like

Thank you so much… I was kind of giving up as it seemed I found no other cases with same issue. Judging from how much I’m familiar with PIO, I think I would never figure this out on my own.

Can you just explain what did you do different in the script? I get it that e is some kind of object through which you can modify various build flags and similar properties. What means “across all construction environments”? Should I set flags like so each time I’m adding extra flags or just in this particular case and why?

Again, thank you for helping out with this issue!

e loops through the objects defined in the list.

Depends on where you need those flags applied – see the linked documentation for construction environments above. If you want them applied globally, then yes.

And just to clarify, this script was only needed because it couldn’t be done via build_flags (which is already global), since that doesn’t affect env[LINKFLAGS].