注意
本文档适用于 Ceph 的开发版本。
C++17 和 libstdc++ ABI
Ceph 已在 mimic 版本中切换到 C++17。要在没有 GCC-7 的旧发行版上构建 Ceph,需要从附加仓库安装 GCC-7。在 RHEL/CentOS 上,我们使用 devtoolset-7(来自 SCLs)来构建 Ceph。但 devtoolset-7 总是使用旧的 ABI,即使定义了 _GLIBCXX_USE_CXX11_ABI=1。因此,在 RHEL/CentOS 上,仍然使用 std::string 和 std::list 的旧实现。换句话说,在这些发行版上,std::string 仍然是写时复制,std::list::size() 仍然是 O(n)。但在 Ubuntu Xenial 上,Ceph 是使用新 ABI 构建的。因此,由于我们仍然在 RHEL/CentOS 上使用 libstdc++ 和 devtoolset 构建软件包,请不要依赖新 ABI 或旧 ABI 的行为。
对于那些认为“GCC 支持双 ABI!”的人,下面是长篇故事。问题在于系统共享库和 libstdc++_nonshared.a 模型。如果某些符号是从系统共享库导出的,我们必须使用它,不能覆盖它。此外,双 ABI 支持要求几个系统共享库符号的行为有所不同(例如,对于 locale facets,需要注册两倍的次数,一组用于旧 ABI,另一组用于新 ABI)。因此,如果我们希望构建的二进制文件能够在只提供旧 ABI 的 libstdc++ 的旧发行版上运行,我们别无选择,只能坚持使用旧 ABI。