no implementation of __fpclassify in armhf

636 Views Asked by At

I'm cross-compiling for Raspberry Pi 4B using ARM's 10.3-2021.07 GCC toolchain (specifically this file uncompressed into ARMGCC). I'm also using the latest Raspberry OS image as sysroot (loop-mounted into RPISYSROOT). The host is an Ubuntu Xenial VM on a Windows host.

When using this compilation line (edited for readability, CFLAGS inspired by the Pi's /proc/cpuinfo, gentoo and GNU):

${ARMGCC}/bin/arm-none-linux-gnueabihf-g++ -std=c++11 \
-v -w -fexceptions -fpermissive --sysroot=$RPISYSROOT \
-pipe -mcpu=cortex-a72 -mfpu=neon-vfpv4 -mfloat-abi=hard -g \
-I . -I .. -I libA/include -I libB/include \
-I ${ARMGCC}/arm-none-linux-gnueabihf/libc/usr/include \
-I ${RPISYSROOT}/usr/include/arm-linux-gnueabihf \
-c file.cpp -o obj/debug/file.o

I get the following error:

$ARMGCC/arm-none-linux-gnueabihf/libc/usr/include/bits/mathcalls-helper-functions.h:20:24: error: ‘__fpclassify’ has not been declared
   20 | __MATHDECL_ALIAS (int, __fpclassify,, (_Mdouble_ __value), fpclassify)
      |                        ^~~~~~~~~~~~

I see uses of __fpclassify in ARMGCC, RPISYSROOT and Raspberry Pi's tools git repo and they seem to be all iterations of the same files:

usr/include/math.h
usr/include/bits/mathcalls-helper-functions.h

(paths may vary slightly). However, none of these provide declarations or implementations of __fpclassify. This seems to come from libm which, I think, has been a part of libc for a while now. I've already installed libc onto RPISYSROOT.
The only implementation I've found is from uCLibc but I don't think mixing libc implementations is a good idea.

Also, since the Raspberry Pi is armhf, should I be seeing these errors?

1

There are 1 best solutions below

1
On BEST ANSWER

The issue here is a mixing of the two sets of headers, those of the build chain (ARMGCC) and those of the specified system root (RPISYSROOT). In particular, presuming a file.cpp which looks something like:

#include <cmath>

void function(void) {}

your compilation command will perform the following nested includes:

  • ${ARMGCC}/arm-none-linux-gnueabihf/include/c++/10.3.1/cmath
  • ${RPISYSROOT}/usr/include/math.h
  • ${ARMGCC}/arm-none-linux-gnueabihf/libc/usr/include/bits/mathcalls-helper-functions.h

The specific error you are receiving (mentioning __fpclassify) is a bit misleading, because what is most relevantly undefined at that point is the __MATHDECL_ALIAS function-like macro, which is defined in ${ARMGCC}/arm-none-linux-gnueabihf/libc/usr/include/math.h.

If you look at the same file under RPISYSROOT, you can see that it uses __MATHDECL_1 instead:

/* Classify given number.  */
__MATHDECL_1 (int, __fpclassify,, (_Mdouble_ __value))
     __attribute__ ((__const__));

which is defined in ${RPISYSROOT}/usr/include/math.h.

So what you need to do is ensure that ${RPISYSROOT}/usr/include/arm-linux-gnueabihf/bits/mathcalls-helper-functions.h is included instead of the ARMGCC counterpart, which you can do by changing the order of includes in your compilation command. Reducing your command to its essentials, we have:

${ARMGCC}/bin/arm-none-linux-gnueabihf-g++ \
  --sysroot=${RPISYSROOT} \
  -I ${ARMGCC}/arm-none-linux-gnueabihf/libc/usr/include \
  -I ${RPISYSROOT}/usr/include/arm-linux-gnueabihf \
  -c file.cpp \
  -o obj/debug/file.o

which fails as above. Changing this to:

${ARMGCC}/bin/arm-none-linux-gnueabihf-g++ \
  --sysroot=${RPISYSROOT} \
  -I ${RPISYSROOT}/usr/include/arm-linux-gnueabihf \
  -I ${ARMGCC}/arm-none-linux-gnueabihf/libc/usr/include \
  -c file.cpp \
  -o obj/debug/file.o

compiles successfully.

In fact, for this case we can remove the explicit reference to any ARMGCC includes, with the following:

${ARMGCC}/bin/arm-none-linux-gnueabihf-g++ \
  --sysroot=${RPISYSROOT} \
  -I ${RPISYSROOT}/usr/include/arm-linux-gnueabihf \
  -c file.cpp \
  -o obj/debug/file.o

which also compiles.