在RHEL6和RHEL7上禁用_GLIBCXX_USE_CXX11_ABI?

时间:2018-06-13 11:31:18

标签: c++ libstdc++ rhel7 rhel6 devtoolset

我在RHEL6和RHEL7上有gcc 5.2.1,看起来_GLIBCXX_USE_CXX11_ABI被禁用了。即使我手动运行-D_GLIBCXX_USE_CXX11_ABI=1 -std=c++14,它也无法正常工作。这意味着我不会得到小的字符串优化功能。例如,以下代码的输出始终为8,并且“未设置为微”。对于SSO,如果我们查看代码位/ basic_string.h,std :: string的大小应该至少为16。任何解决方法?

#include <string>
#include <iostream>

int main()
{
    std::cout << sizeof(std::string) << std::endl;

#if _GLIBCXX_USE_CXX11_ABI
    std::cout << "macro set" << std::endl;
#else
    std::cout << "macro not set" << std::endl;
#endif

}

2 个答案:

答案 0 :(得分:3)

bugzilla.redhat有以下回复

  

Jakub Jelinek 2018-02-19 06:08:00 EST

     

我们已经努力了,但不可能支持这一点,也不可能   RHEL6也不在RHEL7上,这就是它被强制禁用的原因。它会   在RHEL8中工作(也是默认设置)。

答案 1 :(得分:-1)

这取决于您的libstdc++版本,请确保您的包含/链接/运行时路径正确无误。在系统中搜索该宏,然后使用它,只需确保链接到正确的stdlib / abi库。

如果你没有,你可以自己构建它,但要注意,如果你使用旧的ABI的其他程序,它们将不适用于你的新libstdc++

编辑:考虑到这一点,您是否为-std=指定了正确的g++标志?你试过-std=gnu11吗?这可能是微不足道的。如果没有,请继续阅读。不要手动指定该定义,您将破坏与libstdc++的ABI兼容性,从而导致精彩崩溃的级联。唯一一次你可以指定这样的东西就是你自己构建stdlib时。

其余部分有点矫枉过正,但它解释了如何构建和/或选择您想要使用的stdlib。

当使用libc++的版本2 ABI时,我遇到了类似的问题,其中链接的所有内容都必须使用正确的标头进行重建,从而使用正确的ABI(小字符串优化就是其中之一) 。

例如,在构建C ++对象时,我使用以下标志来指定自定义stdlib头路径的位置,而不是使用提供的操作系统(我使用Clang但原理类似):

-nostdinc++ -I/usr/local/sdk/llvm.6.0.1/include/c++/v1/

然后在链接阶段我使用$ORIGIN相对运行时搜索路径,因为在生产机器上标准库安装在一个更理智的位置,但是您可以指定一个固定的到您想要的stdlib。您还希望确保链接器在与-L的静态链接期间找到适当的stdlib。

-Wl,-rpath,'$ORIGIN/../lib' -L/usr/local/sdk/llvm.6.0.1/lib

您需要链接-lstdc++-lsupc++(如果静态链接,顺序很重要),只要您提供正确的库搜索路径,静态链接器应该找到它们是GCC / GNU C ++ stdlib和ABI支持库。

请注意,如果您更换系统libstdc +,那么任何与旧ABI布局链接的程序如果动态链接都会中断,所以要小心。