Check if your crross-compiler GCC toolchain is supporting hard-float
I recently recognized my GCC toolchains are not consistent regarding floating-point support.
If you want to check your toolchain against hard-float, too, keep on reading.
Let's have a look at, for example, arm-cortex-a8___gcc-8.3.0___glibc-2.29___linux-4.4.174___float-auto___ctng-crosstool-ng-1.24.0
:
This nicely named crosstool-ng (a toolchain generator) build toolchain states float=auto
, which means GCC may choose the right floating-point engine like the crosstool-ng ARCH_FLOAT_AUTO config option expresses:
config ARCH_FLOAT_AUTO
bool
prompt auto (let gcc decide)
help
Instead of explicitly passing a float option, don't
pass any float options and let gcc figure it out.
Unfortunately, this does not mean crosstool-ng ist choosing the floating-point option, instead of it\'s saying the resulting compiler is deciding. However, the compiler can only make this decision if we have a multi-lib compiler containing hard-float and soft-float variants, which this one do not have:
./arm-none-linux-gnueabi-gcc -print-multi-lib
lti-lib
.;
A multi-lib compiler would list something like:
armv7-ar/thumb/softfp;@mthumb@march=armv7@mfloat-abi=softfp@mfpu=vfpv3-d16
armv7-ar/thumb/fpu;@mthumb@march=armv7@mfloat-abi=hard@mfpu=vfpv3-d16
Additionally, we may check by grepping the compiler verbose:
./arm-none-linux-gnueabi-gcc -v 2>&1 | grep -oP '\-\-(en|dis)able-multilib'
--disable-multilib
So I assumed its a soft-float compiler. Let\'s do some more checks:
./arm-unknown-linux-gnueabihf-gcc -v 2>&1 | grep float
is not telling us something about hard-float, which would be --with-float=hard
. So next check:
./arm-none-linux-gnueabi-gcc -dumpspecs | grep float
This is telling us what the toolchain expects in case of building for hard-float. The resulting text contains something like:
%{mfloat-abi=hard:hf}.so.1;:%{mfloat-abi=hard:/lib/ld-linux-armhf.so.3}
%{mfloat-abi=soft*:/lib/ld-linux.so.3}
%{!mfloat-abi=*:/lib/ld-linux.so.3}
Which means, if we have an hard-float toolchain we should find ld-linux-armhf.so* in the toolchain folder:
find . -name ld-linux-armhf.so*
But it found nothing. Some more testing. We are compiling a simple hello world, and checking the resulting binary:
readelf -h a.out | grep Flags
Flags: 0x5000200, Version5 EABI, soft-float ABI
Which states explicitly soft-float ABI. Or, for older compilers:
readelf -A a.out
Should list Tag_ABI_VFP_args: VFP floating-point registers a hard-float one would have, but it does not. Last one: Explicitly compiling for hard-float:
arm-none-linux-gnueabi-c++ -mfloat-abi=hard ~/main.cpp
fatal error: gnu/stubs-hard.h: No such file or directory
# include <gnu/stubs-hard.h>
^~~~~~~~~~~~~~~~~~
compilation terminated.
So, for sure, no hard float support.
Further Reading:
Demystifying ARM Floating Point Compiler Options - greate ARM floating-point compiler options overview