C++ ABI 问题定位解决

C++ ABI 问题定位解决

当编译链接时遇到报错undefined reference to "std::__cxx11 ***",那基本就是遇到了C++ ABI问题了。所谓ABI,是指应用程序二进制接口(Application Binary Interface, ABI)。

1、ABI 问题的出现

在GCC 5.1 版本发布的libstdc++中,添加了包含std::stringstd::list的新的实现方法的ABI。而由于std::basic_string被广泛使用着,因此有很多标准库都会受影响。为了实现与现存代码兼容,libstdc++的库名没有进行修改,而且老的实现也依然保留着与新的实现并存。并存是怎么实现的呢,就是在内联命名空间中定义了新的实现,因此新、旧实现在链接时就有不同的名字,比如 新版本的std::list<int>被定义为了std::__cxx11::list<int>。也正是因为新的实现有不同的名字,使得新、旧实现能够在同一个库中并存。

2、ABI 问题的解决

2.1 GLIBCXX_USE_CXX11_ABI

当你升级GCC版本后,如果把整个代码都全部重新编译一遍,那么你基本上不会遇到ABI问题的。但是如果你还依赖于其他第三方编译出来的动态库,而它们是用老版本的GCC(如:GCC 4.8)编译出来的,那么就有可能会遇到ABI的问题。这个时候,在编译的时候添加一个定义-D_GLIBCXX_USE_CXX11_ABI=0,那么应该就不会有什么问题了。

2.2 本地GCC版本冲突

稳住,别慌。如果明明别人提供第三方库也是GCC 5.3 编译的,你本地也是指定的GCC 5.3版本,但是还是有ABI问题,那我猜你是不是本地默认的GCC版本是4.x,或者你链接了libstdc++.a静态库?我就遇到了这个情况。

我本地默认GCC版本是4.8,在另一个目录/buildtools/gcc5.3安装了GCC 5.3。在编译时指定了CMAKE_CXX_COMPILER为GCC5.3的对应目录。但是编译时依然会报ABI的问题。被这个问题折磨了一天后,又和第三方对齐了一下cmake版本,然后将cmake升级为最新版本,它居然多了个报警:

CMake Warning at CMakeLists.txt:75 (add_executable):
  Cannot generate a safe linker search path for target MyBinary because
  files in some directories may conflict with libraries in implicit
  directories:

    link library [libstdc++.a] in /build_tools/gcc-5.3.21/lib64 may be hidden by files in:
      /usr/lib/gcc/x86_64-redhat-linux/4.8.5

  Some of these libraries may not be found correctly.

仔细看看这个报警,说的是某些目录中的文件可能与隐式目录中的库冲突,指定的GCC 5.3目录下的库可能被系统目录下GCC 4.8的库隐藏。也就是说我明明指定的是GCC 5.3,但实际链接时却链接到了GCC 4.8上面,也因此导致ABI问题的出现。当我们把/usr/lib/gcc目录挪走之后,链接就没有问题了。

困扰了我好几天的问题因此解决。

参考资料

  1. 双重ABi Dual ABI
  2. GCC5 and the C++11 ABI
  3. Why-we-need-D_GLIBCXX_USE_CXX11_ABI=0
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值