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