Fedora 22 将随 GCC 5 一起发布,它带来了一大堆 增强功能,其中有一个新的默认 C++ ABI。 在本文中,我们将介绍 ABI 转换将如何工作 Fedora.
背景——什么是 ABI,它为什么会发生变化,这对开发人员意味着什么?
简而言之,二进制兼容性意味着在操作系统和特定硬件架构的组合上编译的应用程序将在操作环境的不同实例中类似地加载和运行。 应用程序二进制文件由可执行文件和动态共享对象(DSO——共享库的正式名称)组成,兼容性级别由特定的应用程序二进制接口 (ABI) 定义。
编译器、库和相关工具中新功能的开发——尤其是这些工具支持的任何新语言标准——可能会导致 ABI 发生变化,需要重新构建某些二进制文件,或者新构建的二进制文件不直接与现有的二进制文件兼容。
当编译器使用来自上游社区源的默认选项构建时,GCC 5 实现了这样的 ABI 更改。 它执行此命令是为了实现新的 C++11 语言标准。 这以二进制兼容性为代价为开发人员提供了新功能——某些 C++ 核心类的 C++11 要求需要更改 ABI。
GCC 5 还提供了一个开箱即用的编译器开关,默认情况下切换回使用较旧的 ABI,代价是一些 C++11 一致性。 无论哪个 ABI GCC 被配置为默认使用,开发人员都可以通过定义一个宏来覆盖默认值,以每个文件为基础使用另一个。
FESCo 围绕 GCC 5 的决定和理由 Fedora 22
1 月中旬,GCC 的维护者在 Fedora 提议将 GCC 5 纳入 Fedora 22. 该提案是向 FESCo 提出的,该机构拥有确定每个版本的主要功能的总体权力 Fedora.
该问题在最近的 FESCo 会议上进行了辩论,维护者参加了会议,最终决定发布 GCC 5,但与
默认启用旧 ABI。
该决定的核心是 FESCo 优先考虑 Fedora 22 时间表。 大规模重建所有人 Fedora 包是不可能的,如果 Fedora 22是准时发货。 考虑了“mini-mass-rebuild”,只重建 C++ 包(所以 Fedora 可以转向使用 C++11 和新的 ABI)。 这里的想法是减少必须重建的软件包数量以节省时间。 然而,该提议也被拒绝了,因为 FESCo 认为即使是小规模重建也会影响 Fedora 22 时间表。
这给 FESCO 留下了两个选择。 要么通过 GCC 4.9 保留 Fedora 22 循环,然后升级到 GCC 5 Fedora 23,或使用 GCC 5,但使用旧的 C++ ABI Fedora 22,然后用新的 ABI 向前迈进 Fedora 23.
继续使用 GCC 4.9 可以最大限度地减少 Fedora 22 GCC 包装, Fedora 22. Fedora 然而,GCC 开发周期是互惠互利的,因此将 GCC 5 从 Fedora 对 GCC 5 的上游开发有副作用。
继续使用 GCC 4.9 也会离开 Fedora 用户无法轻松获得 GCC 5 带来的所有其他好处。 GCC 5 的删除甚至可能被误解为表明 GCC 5 还没有准备好用于生产。
最后,继续使用 GCC 4.9 也会影响使用 Red Hat 的 RHEL 工具的开发人员,例如 Red Hat Developer Toolset – GCC 5 不会广泛使用 Fedora 在加入红帽产品组合之前测试红帽的需求。
使用 GCC 5 的选项,但使用旧的 ABI,允许开发人员从所有上游社区的功能和错误修复工作中受益。 这些活跃用户反过来又使 GCC 和 Fedora 直接做项目。 Fedora 默认情况下不会启用新的 C++11 ABI,但这也将允许开发人员单独处理对 GCC 5 的一般升级到新的 ABI,预计将在 Fedora 23.
那么我需要知道什么 Fedora 22 和 Fedora 23 作为开发者?
这一决定的一个后果是 Fedora 22 和 Fedora 23 都将具有 GCC 5,但它们将有根本的不同。 C++ 库 (libstdc++.so) 将是
F22 和 F23 之间兼容(实际上会几乎完全一样,
以上游的一些额外补丁为模,这些补丁可能会被拉入后来的 F23 构建中)。 不同之处在于链接到它的所有其他 DSO。 这对 Fedora 开发商注意。
具体来说,FESCo 的决定意味着由 FESCo 安装的 C++ 标准库头文件
libstdc++-devel RPM 将为 _GLIBCXX_USE_CXX11_ABI 宏(F22 中的 0 和 F23 中的 1)提供不同的默认值,但 libstdc++.so 库在 F22 和 F23 中将基本相同,因为该库包含所有符号定义旧 ABI 和新 ABI,因此同一个库适用于两种情况。
但是,当使用 GCC 5 编译另一个 DSO(例如 libboost_filesystem.so)时,它将使用旧 ABI 或新 ABI 进行编译,但不能同时使用两者,并且链接到该 DSO 的程序通常需要使用相同的 ABI 以避免链接器错误。 作为 C++ 库的一部分 Fedora 22 将使用旧 ABI 构建,但它们将使用新 ABI 构建 Fedora 23. 开发人员可能需要使用新的 ABI 重新编译他们的程序,以便链接到 C++ 库 Fedora 23. 同样,使用 _GLIBCXX_USE_CXX11_ABI 宏覆盖默认值的开发人员可能需要重建他们依赖的其他库,以确保这些库也使用非默认 ABI 构建。
如果你碰巧在 Fedora 它提供了一个库供其他包使用,你甚至可以考虑做一些类似于 libstdc++ 的事情 Fedora 22/23,即提供两组公共符号——一组用于旧 ABI,一组用于新 ABI。 这是否值得努力实现很大程度上取决于库的消费者数量、库包含的符号数量以及用户对 ABI 变化的敏感程度。 本质上,您需要确定哪些符号受到影响。 一种方法是为 C++98 构建 [gcc -D_GLIBCXX_USE_CXX11_ABI=0 -Wabi-tags in your rpmbuild]然后分别用于 C++11 [gcc -D_GLIBCXX_USE_CXX11_ABI=1 -Wabi-tags in your rpmbuild],然后将两个 DSO 与 比迪夫 (libabigail 的一部分) [abidiff old-abi/libfoo.so new-abi/libfoo.so]. 确定受影响的符号后,确保将这些符号与未受影响的符号分开编译到它们自己的文件中,这样您就可以编译它们两次(不重复未受影响的符号)。 这不是微不足道的,但需要考虑的事情。
总体而言,关于 GCC 5,需要牢记三个关键事项: Fedora 22. 首先, Fedora 22 GCC 组件仍将来自完整的上游版本。 其次,ABI 的选择是通过标准的配置时间标志来完成的——该选项可以在该开关反转的情况下进行重建。 第三,ABI 与 F21 的兼容性实际上保持在 Fedora 22(尽管开发人员可以选择通过 -D_GLIBCXX_USE_CXX11_ABI=1 启用较新的 C++11 ABI)。
这对 RHEL 开发人员意味着什么?
为 Red Hat Enterprise Linux 构建应用程序、使用 Red Hat 工具构建二进制文件和共享库的开发人员不受这些变化的影响。
最后的想法
希望这篇文章有助于解释 GCC 5 的发布计划 Fedora,FESCo 是如何做出决定的,以及这意味着什么 Fedora 和红帽企业 Linux 开发人员。
随时提出问题或提供反馈。