Enable VPF libraries (hard) with arm-gcc - gcc

I'm trying to build an application that links a library that is built with VFP. I have added the flags -mfpu=fpv4-sp-d16 -mfloat-abi=hard to my arm-gcc command, but it complains about that the standard C library (libm.a and the like) is not built using VFP.
I have noticed that in my arm-gcc toolchain directory, in lib, there is a folder called hard which is supposed to contain the arm standard C libraries built with VFP.
How can I make this library folder the standard one for the arm toolchain?

It seems that I had some missing flags. Below I list all of them:
-mcpu=cortex-m7 -mthumb -mabi=aapcs -mfpu=fpv5-d16 -mfloat-abi=hard

Related

link time warning about VPF registers

I'm trying to port a project from Cortex M0 to Cortex M4 with hardware floating point extension, the new target soc is nRF52832.
The error I am getting from the linker is the following
arm-unknown-eabi/bin/ld: error: x.o uses VFP register arguments, firmware does not
where firmware is the name of the output file fro the linker.
This is an issue with the arm ABI for floating point, I want to use the FPU as it is requested by
the FreeRTOS port I want to use but I don't get how to tweak my linker flags to make it possible.
This is the set of linker flags I'm currently using
-L/path/to/nrfx/mdk
-Wl, --no-undefined
-Wl,--as-needed -march=armv7e-m+fp -mthumb -mfloat-abi=hard -mabi=aapcs
-Wl, --start-group support/libs/libQRCode.a support/libs/libSPIFFS.a
-Wl, --no-undefined
-Wl, --as-needed
-Wl, --gc-sections --specs=nosys.specs -T/path/to/linker_script.ld /toolchain/path/to/lib/libm.a
-Wl, --end-group
The -mfloat-abi flag is a compiler-only flag, so there is no point in passing it to the linker.
In order to be able to build a firmware image that uses the hard-float ABI, all object files passed to the linker must be compiled to use that ABI. You issue is most likely due to the fact that you are passing to the linker one or more object files compiled with the soft-float ABI instead; for example, the /toolchain/path/to/lib/libm.a file path in your linker command line looks suspicious, you should use the hard-float version of libm.a, which you will likely find in the hard/ sub-folder of your toolchain library path.

Mingw gcc, "-shared -static" passing together

When studying Scintilla's makefile for MinGW under windows, I noticed that it is passing -shared and -static together as LDFLAGS to gcc.
LDFLAGS=-shared -static -mwindows $(LDMINGW)
I googled, and only find some information from clang: https://reviews.llvm.org/D43811
[MinGW, CrossWindows] Allow passing -static together with -shared
In these combinations, link a DLL as usual, but pass -Bstatic instead of -Bdynamic to indicate prefering static libraries.
My question is: Would GCC do the same?
I haven't find any proof yet.
You can pass both -static and -shared in a GCC linkage. Their
combined effect is the same as you found described in your llvm link,
and this has always been the case for GCC.
-shared directs a GCC linkage to produce a shared library rather than a program,
which it achieves by passing on the option -shared to its invocation of
the linker.
-static directs a GCC linkage to ignore shared libraries when resolving
input library options -lname. By default -lname would be resolved by
searching the specified or default linker search directories for either
the shared library libname.so (on Windows, [lib]name.dll)
or the static library libname.a (on Windows also [lib]name.lib) and to prefer
the shared library if both of them are found in the same directory. -static
simply excludes all shared libraries from the search. GCC achieves this by passing the option -Bstatic
through to its invocation of the linker at a position in the generated linker
commandline that precedes all of the -lname options.
The GNU linker documentation of -Bstatic is explicit
that this option is consistent with -shared and that the effect is to produce a shared library
all of whose dependent libraries have been statically resolved.
-Bstatic
-dn
-non_shared
-static
Do not link against shared libraries. This is only meaningful on platforms for which shared libraries are supported.
The different variants of this option are for compatibility with various systems. You may use this option multiple times on the command line:
it affects library searching for -l options which follow it. This option also implies --unresolved-symbols=report-all.
This option can be used with -shared. Doing so means that a shared library is being created but that all of the library’s external references must be resolved by pulling in entries from static libraries.
(emphasis mine).
Although static linkage of shared library is in principle just a linkage restricted
in the same way as static linkage of a program, in practice it frequently encounters
a snag on Unix and Linux because all the object code linked into an ELF shared library
libname.so must be Position Independent Code,
as produced by the GCC compilation option -fPIC, whereas object files that are destined to be
archived in static libraries are customarily not compiled with -fPIC. Linkages using
-shared ... -static are thus apt to fail because necessary static libraries contain
non-PIC object files.
You do not have this worry with GCC on Windows, however, because there
is no such distinction as PIC v. non-PIC in Windows PE
object code.

QtWebengine build error with opus and silk codecs

I am trying to build Qt5.9.1 with QtWebengine for an arm platform.
These are some architecture based arguments i am passing to the build.
QMAKE_CFLAGS_RELEASE += -march=armv7-a -mcpu=cortex-a9
QMAKE_CXXFLAGS_RELEASE += -march=armv7-a -mcpu=cortex-a9
By default i can see that the build is going for these values as well.
-mfloat-abi=hard -mtune=generic-armv7-a -mfpu=vfpv3-d16 -mthumb
THIS is the error i am facing.
As far as i know, in cortex-a9 neon is optional and my particular SoC does not support neon.
Also the -print-multi-lib gives this
arm400-linux-g++ -print-multi-lib
armv5te_arm9;#mcpu=arm926ej-s
a9;#mcpu=cortex-a9
a7;#mcpu=cortex-a7
armv5te_arm9_soft;#mcpu=arm926ej-s#mfloat-abi=soft
armv5te_arm9_vfp;#mcpu=arm926ej-s#mfloat-abi=softfp#mfpu=vfp
a9_soft;#mcpu=cortex-a9#mfloat-abi=soft
a9_softfp_vfp;#mcpu=cortex-a9#mfloat-abi=softfp#mfpu=vfp
a9_softfp_vfpv3-d16;#mcpu=cortex-a9#mfloat-abi=softfp#mfpu=vfpv3-d16
a7_soft;#mcpu=cortex-a7#mfloat-abi=soft
a7_softfp_vfpv4;#mcpu=cortex-a7#mfloat-abi=softfp#mfpu=vfpv4
a7_softfp_neon-vfpv4;#mcpu=cortex-a7#mfloat-abi=softfp#mfpu=neon-vfpv4
a7_hard_neon-vfpv4;#mcpu=cortex-a7#mfloat-abi=hard#mfpu=neon-vfpv4
I have tried passing these three possible architecture arguments in the mkspecs.
QMAKE_CFLAGS_RELEASE += -march=armv7-a -mcpu=cortex-a9 -mfloat-abi=soft
QMAKE_CXXFLAGS_RELEASE += -march=armv7-a -mcpu=cortex-a9 -mfloat-abi=soft
For this i got
"arm400-linux-g++: error: -mfloat-abi=soft and -mfloat-abi=hard may not be used together".
I also tried passing these arguments
-mcpu=cortex-a9 -mfloat-abi=softfp -mfpu=vfp
-mcpu=cortex-a9 -mfloat-abi=softfp -mfpu=vfpv3-d16
But it had the same effect.
libxxxx.a(yyyyy.o) uses VFP register arguments, libQt5WebEngineCore.so.5.9.1 does not
I am running out of options here. Why is this issue coming up ?
You have to build all the libs with the same VFP option as your source code.
According to ATPCS(ARM-Thumb procedure call standard), float parameters are passed by VFP registers if available. Otherwise, they are passed by the ARM integer registers.
If lib A is compiled with the soft-float option, you cannot call its functions due to the ABI conflict from lib B or vice versa.
If you don't have certain lib's source code but the binary, your only option is to match the other projects build options to the lib's.
However, chances are good that you will find different versions of the library with various build options.

GCC Cortex-M4 -mfpu=vfpv4 vs. -mfpu=fpv4-sp-d16

I'm using a Freescale K22 (Cortex-M4F) with Kinetis Design Studio, which includes a GNU toolchain. I'm trying to use a binary-only library provided by Invensense, and they compiled it with GCC for use on a the Cortex-M4F using the compiler's CPU options "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=vfpv4"
The Freescale toolchain defaults to "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16". When I try to link my program with the vendor binary-only library, I get link errors like:
c:/freescale/kds_1.1.1/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/../../../../arm-none-eabi/bin/ld.exe: error: ./startup/startup.o uses VFP register arguments, 22F_eval_spi_to_invensense_CHECKED_IN.elf does not
c:/freescale/kds_1.1.1/toolchain/bin/../lib/gcc/arm-none-eabi/4.8.0/../../../../arm-none-eabi/bin/ld.exe: failed to merge target specific data of file ./startup/startup.o
I can rebuild the Kinetis platform library for -mfpu=vfpv4, but I still get the link errors, presumably because other Kinetis libraries are compiled with
"-mfpu=fpv4-sp-d16".
Since both are intended for the Cortex-M4 with FPU, is there any actual difference between GCC generated code for vpfv4 and fpv4-sp-d16? Are they actually incompatible, or is the linker just overly pedantic?

Linking a shared library using gcc

I have a shared library (*.so) created using Real View Compiler Tools (RVCT 3.2) on windows target. Then I try to link this *.so file with my application using gcc on linux system.
What is the gcc option to link this shared library with my application linux?
My question is, is the -shared option, which is used as
gcc -shared myfile.so
..., used to create the SO file or to link the SO file? I believe it creates something like:
gcc -lmyfile.so
Is this enough? Or is there any other switch to tell the linker that it's a dynamic library (shared object)?
What worked for me was:
gcc -L. -l:myfile.so
gcc -lmyfile should be enough (provided that your library is named libmyfile.so). The linker searches for shared objects when possible and AFAIK prefers them.

Resources