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?
我使用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中的运行库不包含所有所需的功能,所以我必须手动更新系统,但我可能会对此提出另一个问题。
- 函数名称表示什么等等
- 什么是表示?
- 什么"!<number> 在 C/C++ 中表示
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- C++中抽象语法树最常用的表示法是什么
- 这个片段中关于 n 在 pc[i] 中的表示发生了什么
- 在 C++17 中表示 std::byte 文字的正确方法是什么?
- 指针符号在参数规范中表示什么,例如:(char16 *缓冲区,int32 大小)?C++
- 对于eigen sparsematrix,InnerIndExptr()和exout indExptr()准确表示什么
- 此代码的 Big-O 表示法是什么?
- 在C++中将数据结构表示为字符串的首选方法是什么?
- C 中的运算符(::类型*)0表示什么意思
- GCC ARM 交叉编译,像未定义的引用"__cxa_end_catch@CXXABI_1.3"这样的错误表示什么?
- 表示图像矩阵的理想数据结构是什么?
- 在 C++11 中表示日内时间 HH:MM:SS 的最佳方法是什么?
- 与类型的二进制表示相关的技术词是什么?
- 在 C++ 中用什么来表示 lambda 字符
- 这段代码的 Big-O 表示法是什么
- scanf在c++中的表示是什么
- 什么..表示函数内部参数(const char*值,..)