我正在交叉编译树莓派4B使用ARM的10.3-2021.07GCC工具链(特别是这个文件未压缩到ARMGCC
)。我还使用最新的树莓OS映像作为sysroot(循环安装到RPISYSROOT
)。主机是Windows主机上的Ubuntu XenialVM。
使用此编译行时(为易读性而编辑,CFLAGS
灵感来自Pi的/proc/cpuinfo
、Gentoo和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
我收到以下错误:
$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)
| ^~~~~~~~~~~~
我看到__fpclassify
在ARMGCC
,RPISYSROOT
和Raspberry Pi的工具git repo中的使用,它们似乎都是相同文件的迭代:
usr/include/math.h
usr/include/bits/mathcalls-helper-functions.h
(路径可能略有不同)。然而,这些都没有提供__fpclassify
的声明或实现。这似乎来自libm
,我认为它已经成为libc
的一部分一段时间了。我已经在RPISYSROOT
上安装了libc。
我发现的唯一实现来自uCLibc,但我认为混合libc实现不是一个好主意。
此外,由于Raspberry Pi是armhf,我应该看到这些错误吗?
这里的问题是两组标头的混合,构建链的标头(ARMGCC
)和指定系统根的标头(RPISYSROOT
)。特别是,假设一个file. cpp
看起来像:
#include <cmath>
void function(void) {}
您的编译命令将执行以下嵌套包含:
${ARM GCC}/arm-no-linux-gnu ea bih f/include/c /10.3.1/cmath
${RP IS YS ROOT}/us r/include/数学。h
${ARM GCC}/arm-no-linux-gnu ea bih f/li bc/us r/include/bits/数学调用-助手-函数。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/数学. 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
它也编译。