3

我正在使用 ARM 的10.3-2021.07 GCC 工具链对 Raspberry Pi 4B 进行交叉编译(特别是这个文件未压缩到ARMGCC. 我还使用最新的 Raspberry OS映像作为 sysroot(循环安装到RPISYSROOT)。主机是 Windows 主机上的 Ubuntu Xenial VM。

使用此编译行时(为便于阅读而编辑,CFLAGS灵感来自 Pi's /proc/cpuinfogentooGNU):

${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

我收到以下错误:

$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)
      |                        ^~~~~~~~~~~~

我看到了__fpclassifyin和 Raspberry Pi 的工具ARMGCCgit repo 的使用,它们似乎都是相同文件的所有迭代:RPISYSROOT

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

(路径可能略有不同)。但是,这些都没有提供__fpclassify. libm我认为,这似乎是其中的一部分,现在已经有libc一段时间了。我已经将libc安装到RPISYSROOT.
我发现的唯一实现来自uCLibc,但我不认为混合 libc 实现是一个好主意。

另外,由于 Raspberry Pi 是 armhf,我应该看到这些错误吗?

4

1 回答 1

1

这里的问题是混合了两组标头,即构建链 ( ARMGCC) 的标头和指定系统根 ( RPISYSROOT) 的标头。特别是,假设 afile.cpp看起来像:

#include <cmath>

void function(void) {}

您的编译命令将执行以下嵌套包含:

  • ${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

您收到的具体错误(提到__fpclassify)有点误导,因为此时最相关未定义的是__MATHDECL_ALIAS类似函数的宏,它在${ARMGCC}/arm-none-linux-gnueabihf/libc/usr/include/math.h.

如果您查看 下的同一个文件RPISYSROOT,您会发现它使用的是__MATHDECL_1

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

中定义${RPISYSROOT}/usr/include/math.h

因此,您需要做的是确保${RPISYSROOT}/usr/include/arm-linux-gnueabihf/bits/mathcalls-helper-functions.h包含而不是ARMGCC对应项,您可以通过更改编译命令中包含的顺序来做到这一点。将您的命令减少到其本质,我们有:

${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

如上所述失败。将其更改为:

${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

编译成功。

事实上,对于这种情况,我们可以删除对任何ARMGCC包含的显式引用,如下所示:

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

这也可以编译。

于 2021-09-13T04:26:10.010 回答