GCC ARM 交叉编译,像未定义的引用"__cxa_end_catch@CXXABI_1.3"这样的错误表示什么?

GCC ARM Cross-Compiling, what do errors like undefined reference to `__cxa_end_catch@CXXABI_1.3' indicate?

本文关键字:什么 表示 错误 catch@CXXABI cxa 交叉编译 ARM 未定义 GCC 引用 end      更新时间:2023-10-16

我使用Intel Embedded Development Suite for FPGA SoC为Intel Cyclone V SoC成功构建了一个测试应用程序。此应用程序链接到一些特定于目标系统的库。

由于EDS附带的GCC已经过时,我需要更新的C++功能,我想用我从arm网站下载的arm-linux-gnueabihf-g++的当前版本编译整个程序。

使用最新的GCC编译与原始工具链构建良好的相同项目会导致许多错误,如

pathToNewGcc-ARM/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: intelFPGARootDir/18.1/hld/host/arm32/lib/libalteracl.so: undefined reference to `__cxa_end_catch@CXXABI_1.3'
pathToNewGcc-ARM/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: intelFPGARootDir/18.1/hld/host/arm32/lib/libalteracl.so: undefined reference to `std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream(std::string const&, std::_Ios_Openmode)@GLIBCXX_3.4'
pathToNewGcc-ARM/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: intelFPGARootDir/18.1/hld/host/arm32/lib/libalteracl.so: undefined reference to `std::cerr@GLIBCXX_3.4'
pathToNewGcc-ARM/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../lib/gcc/arm-linux-gnueabihf/8.3.0/../../../../arm-linux-gnueabihf/bin/ld: intelFPGARootDir/18.1/hld/host/arm32/lib/libalteracl.so: undefined reference to `operator delete(void*)@GLIBCXX_3.4'

libalteracl.so是Intel发行的目标系统特定库之一。显然这里有些地方不匹配,但是我不确定到底是什么问题。因此,我需要一些关于如何解释这些错误以及如何修复它们的解释。

由于评论中出现了一些问题,以下是一些附加信息

目标架构是双核ARM Cortex A9。我在上面链接的ARM网站上用硬浮点加载了AArch32目标下列出的ARM(ARM-linux-gnueabihf)

构建由CMake/CLion完成。提取的生成编译器/链接器调用如下:

编译:

pathToNewGcc-ARM/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++  -DCL_HPP_MINIMUM_OPENCL_VERSION=110 -DCL_HPP_TARGET_OPENCL_VERSION=200 -DJUCE_APP_CONFIG_HEADER="myProjectDir/JuceLibraryCode/AppConfig.h" -DOPEN_CL_INTEL_FPGA -D_DEBUG=1 -IsomeFrameworkDir/JUCE/modules -IintelFPGARootDir/18.1/hld/host/include20  -g   -std=gnu++11 -o CMakeFiles/HostApplication.dir/Source/Main.cpp.o -c myProjectDir/Source/Main.cpp

链接:

pathToNewGcc-ARM/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++  -g   -LintelFPGARootDir/18.1/hld/board/de10_standard/arm32/lib -LintelFPGARootDir/18.1/hld/host/arm32/lib -LintelFPGARootDir/18.1/hld/host/arm32/lib -Wl,--no-as-needed -lalteracl -lintel_soc32_mmd -lstdc++ -lelf CMakeFiles/HostApplication.dir/Source/Main.cpp.o CMakeFiles/HostApplication.dir/JuceLibraryCode/include_juce_core.cpp.o  -o HostApplication -lrt -ldl -lpthread

libalteracl.so应该是一个32位库,因为整个目标体系结构是32位

这似乎是因为工具链中的libstdc++不提供版本化符号。。。

在我的主机上,我得到

$ readelf -sW /usr/lib64/libstdc++.so.6 | c++filt | grep std::cerr | grep @
3091: 000000000018d340   272 OBJECT  GLOBAL DEFAULT   25 std::cerr@@GLIBCXX_3.4
$ readelf -sW /usr/lib64/libstdc++.so.6 | grep __cxa_end_catch | grep @
1997: 000000000008fe60   131 FUNC    GLOBAL DEFAULT   11 __cxa_end_catch@@CXXABI_1.3

但我没有看到你提供的链接到的工具链的版本符号:

$ readelf -sW ./arm-linux-gnueabihf/libc/usr/lib/libstdc++.so.6.0.25 | c++filt | grep std::cerr | grep @
(nothing)

所以我认为libalteracl.so已经链接到libstdc++,后者提供了符号的版本。也许您会更幸运地使用来自同一供应商的早期工具链。


来自手册:

先决条件

支持版本化ABI的最低环境:一个受支持的动态链接器,一个具有足够历史的GNU链接器,以理解解映射的C++名称globbing(ld)或Sun链接器,用g++编译的共享可执行文件,以及由具有兼容ABI的编译器(g++)编译的共享库(libgcc_s,libstdc++)。Phew。

除此之外,还有一个额外的限制:libstdc++直到3.1.0版本才尝试对符号进行版本化(或者说优雅地老化)。

大多数现代GNU/Linux和BSD版本,特别是使用GCC 3.1及更高版本的版本,将满足上述要求,Solaris 2.5及更高版也是如此。

配置

事实证明,大多数更改默认行为的配置选项都会影响导出符号的损坏名称,从而影响版本控制和兼容性。

有关配置选项的更多信息,包括ABI影响,请参阅:此处

有一个标志明确处理符号版本控制:--enable-symvers

最终,我成功地使用了apt包管理器提供的arm-linux-gnueabihf-g++,它有点旧,但支持我需要的所有功能,并且似乎具有库所期望的符号命名,因此成功链接。

这现在在目标系统上引入了其他错误,因为FPGA板制造商预先构建的最小Linux中的运行库不包含所有所需的功能,所以我必须手动更新系统,但我可能会对此提出另一个问题。