2017-07-31 259 views
8

我们收到了一些为linux编译的库(.a)(可能使用GCC 6.x编译)。_GLIBCXX_USE_CXX11_ABI,GCC 4.8和ABI兼容性

我们正在使用GCC 4.8,并且在尝试链接时遇到类型错误: undefined reference to std::__cxx11::basic_string

正常情况下,可以通过确保所有单位已使用相同的_GLIBCXX_USE_CXX11_ABI标志进行编译来解决此问题。但是,如果我理解正确,这是由GCC 5.1和以上引入的。

  1. 有没有办法使这项工作与GCC 4.8或我们需要问人们重新编译与不同_GLIBCXX_USE_CXX11_ABI库?
  2. 我想如果我们能够切换到GCC> = 5.1,我们可以使这项工作?

谢谢!

+0

另请参阅Red Hat博客上的[GCC5和C++ 11 ABI](https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/) ,GCC手册中的[Dual ABI](https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html)和[由于符号与abi :: cxx11?相关联的问题](https:// stackoverflow.com/q/36159238/608639)堆栈溢出。这给我们带来了很多问题,特别是当Clang不是GCC5/C++ 11时。这看起来像你的dup,但它没有答案:[我应该如何处理gcc-4.9和gcc-5之间的ABI不兼容问题](https://stackoverflow.com/q/37145066/608639) – jww

回答

3

可以使用C++ 11 ABI和gcc 4.8.2,但这是一个危险的破解;如果可能的话,要求供应商发布使用C++ 03 ABI(-D_GLIBCXX_USE_CXX11_ABI=0)编译的库或升级到GCC 5或更高版本,您将会变得更好。

您需要下载并安装gcc 5,以便您可以使用它的libstdC++头文件和库,然后直接使用gcc 4.8来优先使用它们。此外,因为gcc 4.8缺少gcc 5附带的libstdC++所需的一些内在函数,所以您需要破解它们的用法。

例如,编译包括一个简单的单文件应用<string>

/usr/local/gcc-4.8.2/bin/g++ \ 
    -std=c++11 \ 
    -D_GLIBCXX_USE_CXX11_ABI=1 \ 
    -D'__is_trivially_copyable(...)=0' \ 
    -D'__is_trivially_constructible(...)=0' \ 
    -D'__is_trivially_assignable(...)=0' \ 
    -nostdinc++ \ 
    -isystem /usr/local/gcc-5.4.0/include/c++/5.4.0/ \ 
    -isystem /usr/local/gcc-5.4.0/include/c++/5.4.0/x86_64-unknown-linux-gnu \ 
    -L /usr/local/gcc-5.4.0/lib64 
    a.cpp 

这是危险的,因为在gcc 5.4的libstdC++不被设计用gcc 4.8工作,并重新定义所使用的内在(__is_trivially_copyable等)可能会改变结构的布局,否则会导致程序与供应商的库之间的二进制不兼容。

为了运行生成的可执行文件,你还需要确保动态链接加入到/usr/local/gcc-5.4.0/lib64/etc/ld.so.conf,或使用-Wl,-rpath /usr/local/gcc-5.4.0/lib64找到兼容的libstdC++,例如。

+0

可能有意义添加'', - 'rrp'也是。 – yugr

+0

哇,这是可怕的(和酷)的东西!更好地降低风险并遵循安全路径并要求重新编译。 – Tanasis