【问题标题】:_GLIBCXX_USE_CXX11_ABI disabled on RHEL6 and RHEL7?_GLIBCXX_USE_CXX11_ABI 在 RHEL6 和 RHEL7 上禁用?
【发布时间】:2018-11-22 23:19:07
【问题描述】:

我在 RHEL6 和 RHEL7 上安装了 gcc 5.2.1,看起来 _GLIBCXX_USE_CXX11_ABI 被禁用了。即使我手动运行-D_GLIBCXX_USE_CXX11_ABI=1 -std=c++14,它也不起作用。这意味着我不会获得小字符串优化功能。例如,以下代码的输出总是有 8 和 'micro not set'。对于 SSO,如果我们查看 code bits/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

}

【问题讨论】:

  • 定义“不按预期工作”?请注意,1 是该宏的默认值。
  • 你的 GCC 是从哪里安装的?
  • Gcc 是坚定的。假设它是 RHEL 发行版的一部分?
  • 您使用的是不支持新 ABI 的 devtoolset 版本的 GCC。我将更改问题上的标签以说明这一点,因为这就是您看到的行为的原因。

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


【解决方案1】:

bugzilla.redhat有以下回复

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

我们已经尽力了,但无法支持这一点,在 RHEL6 也不在 RHEL7 上,这就是它被强制禁用的原因。它会 在 RHEL8 中工作(并且也是那里的默认值)。

【讨论】:

    【解决方案2】:

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

    如果您没有它,您可以随时自己构建它,但请注意,如果您拥有的其余程序使用旧 ABI,它们将无法与您的新 libstdc++ 一起使用。


    编辑: 考虑到这一点,您是否为g++ 指定了正确的-std= 标志?你试过-std=gnu11吗?它可能像那样微不足道。如果没有,请继续阅读。不要手动指定该定义,您将破坏 ABI 与 libstdc++ 的兼容性,从而导致级联的奇妙崩溃。只有在自己构建标准库时才能指定此类内容。


    剩下的内容有点矫枉过正,但它解释了如何构建和/或选择您想要使用的标准库。

    在使用libc++ 的第 2 版 ABI 时,我遇到了类似的问题,其中链接到它的所有内容都必须使用正确的标头和正确的 ABI 重新构建(例如小字符串优化就是其中之一)。

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

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

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

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

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

    当心,如果你用这个替换你的系统 libstdc+ 任何与旧 ABI 布局链接的程序如果动态链接的话都会中断,所以要小心。

    【讨论】:

    • 但是我的“宏集”代码应该和libstdc++无关吧?
    • 试过 g++ -D_GLIBCXX_USE_CXX11_ABI=1 -std=c++14 g++ -D_GLIBCXX_USE_CXX11_ABI=1 -std=gnu++14 和'-D'。我们的测试显示“未设置宏”。
    • 标头(至少在 libc++ 上)暴露了结构布局等 ABI 细节,通过更改它们并与它们一起构建,您实际上是在链接不兼容的 stdlib,因为它不仅仅是标头,它具有相当一些期望布局相同的编译部分。您可以构建自己的标准库,但您将破坏与操作系统标准库链接的每个 C++ 共享对象的 ABI 兼容性。
    • 这个答案相当具有误导性。没有-std 选项会改变ABI,并且libstdc++ 中的新ABI 并没有使所有对象和库不兼容,这就是库SONAME 没有改变的原因。有关详细信息,请参阅gcc.gnu.org/onlinedocs/libstdc++/manual/using_dual_abi.html
    猜你喜欢
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    • 2020-12-21
    • 1970-01-01
    • 2018-01-07
    • 2016-03-08
    • 1970-01-01
    • 2018-04-04
    相关资源
    最近更新 更多