【问题标题】:GCC ARM Cross-Compiling, what do errors like undefined reference to `__cxa_end_catch@CXXABI_1.3' indicate?GCC ARM 交叉编译,诸如 undefined reference to `__cxa_end_catch@CXXABI_1.3' 之类的错误表示什么?
【发布时间】:2019-10-07 18:14:48
【问题描述】:

我使用面向 FPGA SoC 的英特尔嵌入式开发套件成功地为英特尔 Cyclone V SoC 构建了一个测试应用程序。此应用程序链接到一些目标系统特定的库。

由于 EDS 附带的 GCC 已经过时并且我需要更新的 C++ 功能,我想用我从 ARM 网站下载的here 的当前版本的 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 是英特尔分发的目标系统特定库之一。显然这里有些东西不匹配,但是我不确定确切的问题是什么。所以,我需要解释一下如何解释这个错误以及可以做些什么来修复它们。

由于 cmets 提出了一些问题,这里有一些额外的信息

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

构建由 CMake / CLion 完成。提取生成的 Compiler/Linker 调用如下:

编译:

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 位的

【问题讨论】:

  • 看起来您使用的是 C 编译器而不是 C++ 编译器。如果您提供了一些源代码、编译/链接命令和实际输出,我们可以肯定地说。
  • libalteracl.so 是 32 位库吗?
  • 按照@jww 的建议,我在原始问题中添加了 cmets 中要求的一些附加信息

标签: c++ linux gcc arm


【解决方案1】:

看来,原因是你的工具链中的 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++ 相关联。也许您会更幸运地使用同一供应商提供的早期工具链。


来自the manual

先决条件

支持版本化 ABI 的最低环境:受支持的动态链接器、足以理解解构 C++ 名称通配 (ld) 或 Sun 链接器的 GNU 链接器、使用 g++ 编译的共享可执行文件和共享库(libgcc_s、libstdc++ ) 由具有兼容 ABI 的编译器 (g++) 编译。唷。

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

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

配置

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

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

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

【讨论】:

  • 这真的很有趣,谢谢!我认为像 libstdc++ 的符号这样的东西是非常标准化的。任何关于为什么这对于不同的工具链不同的信息将不胜感激!是否有某种方法可以为我想与匹配符号名称一起使用的工具链手动构建最新的 libstdc++?
  • @PluginPenguin 取决于环境和配置选项。查看 ARM/linaro 工具链提供的清单文件中存在的配置标志并没有给我足够的洞察力。 是否有某种方法可以为我想要使用匹配符号名称的工具链手动构建最新的 libstdc++? 是的。我更新了答案以提供指针。 libstdc++ 生活在 gcc 树中。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2020-12-25
    • 2012-02-11
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    • 2011-08-20
    • 2015-12-20
    • 1970-01-01
    • 2014-11-14
    相关资源
    最近更新 更多