如何在GCC 5中处理双重ABI
How to handle dual ABI in GCC 5?
我试图了解如何克服GCC 5中引入的双重ABI的问题。然而,我无法做到这一点。这里有一个非常简单的例子来重现错误。GCC I使用的版本是5.2。正如你所看到的,我的主要功能(在main.cpp文件中)非常简单:
// main.cpp
#include <iostream>
#include <string>
int main()
{
std::string message = "SUCCESS!";
std::cout << message << std::endl;
}
当我键入时
/home/aleph/gcc/5.2.0/bin/g++ main.cpp
我收到以下错误消息:
/tmp/ccjsTADd.o: In function `main':
main.cpp:(.text+0x26): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&)'
main.cpp:(.text+0x43): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
main.cpp:(.text+0x5c): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
main.cpp:(.text+0x8c): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()'
collect2: erreur: ld a retourné 1 code d'état d'exécution
如果我将_GLIBCXX_USE_CXX11_ABI
的值更改为0,问题就会消失。
但是,如何使用默认ABI使事情正常工作呢?
编辑:更简单的问题(删除cmake脚本)
我通过向gcc(-v标志)添加更多详细信息找到了解决方案。如果您有同样的问题,您需要告诉gcc在包含您的发行版的libstdc++版本的存储库中搜索库。换句话说,你应该试试这样的东西:
/home/aleph/gcc/5.2.0/bin/g++ -L /home/aleph/gcc/5.2.0/lib64 main.cpp
之后应正确执行链接步骤。但是,您可能无法运行程序。进入
./a.out
可能导致以下错误:
./a.out: relocation error: ./a.out: symbol _ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_, version GLIBCXX_3.4.21 not defined in file libstdc++.so.6 with link time reference
实际上,您可以通过键入来检查可执行文件是否依赖于错误版本的libstdc++
ldd a.out
这应该会导致类似的情况:
linux-vdso.so.1 => (0x00007ffebb722000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x0000003a71400000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x0000003d03a00000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x0000003a71000000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x0000003d02e00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003d02a00000)
将LD_LIBRARY_PATH设置为您自己版本的libstdc++的路径将解决问题:
LD_LIBRARY_PATH=/home/aleph/gcc/5.2.0/lib64 ./a.out
希望它能有所帮助!
EDIT:正如Marc所注意到的,可以修改rpath,而不是修改环境变量LD_LIBRARY_PATH。下面是一个CMake配置脚本
project (example CXX)
add_executable(main main.cpp)
if(GCC_ROOT)
set(CMAKE_CXX_COMPILER ${GCC_ROOT}/bin/g++)
target_link_libraries(main ${GCC_ROOT}/lib64/libstdc++.so)
link_directories(${GCC_ROOT}/lib64)
endif(GCC_ROOT)
这个脚本可以与通常的组合一起使用
cmake ..
make
在"build"子目录中。但是,也可以通过提供GCC发行版的根路径来选择我们自己的编译器:
cmake -D GCC_ROOT=/home/aleph/gcc/5.2.0 ..
make
编写该脚本时,libstdc++的版本与输入GCC发行版的版本相对应。
相关文章:
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用流处理接收到的数据
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 基于多个条件处理地图中的所有元素
- 如何用数字处理log(0)
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- 错误处理.将系统错误代码映射到泛型
- 从文本文件中读取时钟时间和事件时间并进行处理
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 用于矢量处理的多个线程
- 对字符串进行排序时,在c++中处理sort()
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- 编译器在 C/C++ 中通过指针调用函数时如何正确处理 ABI
- C++ABI如何处理RVO和NRVO?
- 如何在GCC 5中处理双重ABI