Red Hat Enterprise Linux 9:应用程序兼容性指南
Red Hat Enterprise Linux 9:
应用程序兼容性指南
2022 年 5 月
备注:本文讨论了 Red Hat Enterprise Linux 9 的应用程序兼容性。对于 Red Hat Enterprise Linux 8,请查看 Red Hat Enterprise Linux 8:应用程序兼容性指南。
目录
执行摘要
本指南旨在为软件开发人员提供有关红帽在多个 Red Hat® Enterprise Linux® 平台上支持第三方应用程序的指导方针。通过在应用程序开发过程中遵循这些指导方针,ISV 和客户应用程序可以减少或避免 Red Hat® Enterprise Linux® 主和次版本之间的迁移问题。
本文档描述了推荐使用系统应用程序编程接口(API)和二进制接口(ABI),旨在在 Red Hat® Enterprise Linux® 版本之间提供兼容性。它概述了判断应用程序是否兼容的分层框架。
简介
本文档的目的是提供有关为 RHEL 编写的应用程序和库的稳定性,以及在较新版本的 RHEL 下运行的指导。本文档主要关注软件向后兼容性的问题。虽然向后兼容是目标,但新功能的开发或安全关注有时会使这变得不切实际。因此,指南和发布的政策有时可能有时会被为我们的客户提供最具竞争力、最安全、最强大的系统的目标所覆盖;始终推荐进行情境测试。
如果需要对这些兼容性指南的进一步澄清,请与您的红帽代表联系。
术语
以下是本文档中使用的基本术语:
-
应用程序编程接口(API)
API 是一个由软件程序实现的公共接口,能使它与其他软件(包括操作系统组件)进行交互。API 在编译时强制生效,并决定了源码兼容性,也就是说,应用程序源代码是否在不同版本的操作环境中进行类似的编译。它涵盖了详情,例如:-
开发人员使用的 C 和 C++ 标头
-
语言语法,但只适用于已公布的标准
-
公共接口定义
-
命令行界面,但只适用于记录在案的公共接口
-
-
应用程序二进制接口(ABI)
ABI 是一组运行时约定,其与编译的程序二进制表示进行交互。ABI 在运行时强制执行,它描述了应用程序和操作环境之间的低级接口。它涵盖了详情,例如:-
数据类型、大小和对齐
-
聚合类型的布局、C++ 运行时类型信息、虚函数表
-
调用标准,其定义了如何传递函数参数,以及如何检索返回值
-
对象文件和程序库的二进制格式
-
(异步)堆栈回溯 (unwinding) 信息的存在和格式
-
函数和/或数据符号名称及其版本,以及符号大小(用于数据符号)
-
字节码或任何中间表示,以及虚拟机的公共接口
编译器、链接器、运行时库等工具和操作系统本身需要与 ABI 一起使用。CLI 工具的输出不被视为一个稳定的 ABI。
-
-
ABI 一致性
如果编译器生成的代码遵循该 ABI 枚举的所有规格,则编译器符合 ABI。如果库是按照 ABI 实现的,则库符合 ABI。如果应用程序使使用符合该 ABI 的工具构建的,且不包含更改 ABI 指定的行为或绕过 ABI 行为的源代码,则应用程序符合 ABI。 -
二进制兼容性
二进制兼容性意味着为特定 ABI (通常为 RHEL 和特定硬件架构的组合)编译的应用程序二进制文件将在不同的 RHEL 版本中能够以相似的方式加载和运行。应用程序二进制文件由可执行文件、动态共享对象(DSO)、源、用于解释的即时编译的字节码及其所需的数据文件组成。 -
核心持久系统基础设施
核心持久系统基础设施指的是接口和外部可用的数据结构,它们代表系统状态,或者提供一种与系统(例如,系统调用和头文件)进行通信的方法。 -
虚拟化环境中的兼容性
虚拟环境模拟裸机环境,以便在裸机环境上运行的非特权应用程序将在相应的虚拟环境中未经修改地运行。虚拟环境呈现了物理资源的简化抽象视图,因此可能存在一些差异。 -
容器化环境中的兼容性
容器环境提供与主机操作系统的隔离,并且至少允许应用程序以独立于主机操作系统库和二进制文件的方式运行,但仍然与主机上的所有其他容器共享同样的 OS 内核。 -
主和次发行版本
红帽主发行版本代表产品开发中的重要一步(大规模变更通常保留给主版本)。次发行版本在主发行版本范围内频繁出现,通常代表较小的增量开发步骤。 -
组件
可在 RHEL 上运行的可安装的语言、应用程序、数据库或其他软件包的功能集合。组件以多种格式提供,请参阅 软件包清单 以了解更多详细信息。 -
SystemTap 静态探测
SystemTap 静态探测是 SystemTap 分析和追踪框架的一部分。探测被集成到关键系统库中,以支持对应用和库的分析和调试。 -
文件层次结构标准(FHS)
为各种文件类型和目录定义名称、位置和权限的文件系统结构。符合 FHS 的文件系统相互兼容,并可将 /usr/ 分区挂载为只读。后者很重要,因为分区包含常见的可执行文件,不应被用户更改。 -
CodeReady Linux Builder 存储库
CodeReady Linux Builder 存储库包含开发人员在开发其 RHEL 应用程序过程中使用的组件,但不打算在生产环境中部署它们。详情请查看 Red Hat Enterprise Linux 9 软件包清单 中的 CodeReady Linux Builder 参考。
兼容性级别
Red Hat Enterprise Linux 中的所有组件和软件包被分为以下四个兼容性级别之一:
-
兼容性级别 1
- API 和 ABI 在主版本的生命周期中是稳定的,ABI 在下两个主发行本中也是稳定的。发行版引入了一个新的或修订的 ABI,以及以下两个主版本(n, n+1, n+2)。对于本文档,版本 n 从 Red Hat Enterprise Linux 9 开始。如果对库的更改会导致与现有二进制文件的不兼容,则将提供带有旧 ABI 的单独的库版本,以便在不修改的情况下运行应用程序。
-
兼容性级别 2
- 在一个主版本的生命周期内,API 和 ABI 都是稳定的。兼容性级别 2 应用程序接口不会随小版本而改变,应用程序在主版本期间依赖其保持稳定。兼容性级别 2 对于 Red Hat Enterprise Linux 9 中的软件包是默认设置。未识别为有另一个兼容性级别的软件包可能被视为兼容性级别 2。
-
兼容性级别 3
-
这个级别适用于语言、工具和 Red Hat Enterprise Linux 中包含的作为应用程序流的应用程序。详情请查看 Red Hat Enterprise Linux 应用程序流生命周期。每个组件都将指定一个生命周期,在此周期内将支持 API 和 ABI 。更新版本(如 PHP 8.1 和 PHP 8.2)将尽可能在不同版本之间保持尽可能高的 API 和 ABI 兼容性。但是,无法保证版本之间的兼容性。
-
接收持续更新(称为滚动流)的组件和开发人员工具应被视为兼容性级别 3。详情请查看 Red Hat Enterprise Linux 应用程序流生命周期。开发人员应谨慎行事,并了解这些组件如何随每个发行版本而变化。
-
-
兼容性级别 4
- 不提供兼容性。ABI 和 API 可在任何时候更改。这些组件不应被需要长期支持的应用程序所使用。
对兼容性级别的备注
用于裸机配置的兼容性级别也适用于虚拟化和容器化配置,直接与硬件进行交互的功能除外。这些直接与硬件相关的功能没有 API 或 ABI 兼容性级别。例如,依赖于图形处理单元(GPU)功能的应用程序不能期望二进制兼容性。
红帽要求应用程序开发人员验证它们所依赖的任何行为是否在正式的 API 文档中被明确定义,以防止引入对未指定的特定实现的行为依赖或对 API 的特定实现中的 bug 的依赖。例如,如果应用使用未记录在案的 API 或依赖于未定义的行为,则 GNU C 库(glibc)的新版本可能与旧版本不兼容。
您的支持代表将很高兴通过您可能遇到的任何具体问题对您进行指导。
兼容性例外
以下是 RHEL 中兼容性的例外。
SystemTap 静态探测
- 目前,不保证集成的 SystemTap 静态探测将继续有同样的探测名称、探测位置或解释或参数数量。由于探测主要用于深度分析和调试,因此探测必须能够随着底层实现的变化而变化。
与 C/C++ 运行时的静态链接
- 不支持与 C/C 运行时的静态链接。这包括与是 'glibc-static' 或 'libstdc'-static 软件包一部分的任何文件的链接。您可以选择静态链接,但如果安装中的任何软件包更改了,则产生的应用程序二进制文件可能无法运行。
C/C++ 应用程序应用程序检测工具(Sanitizer)
- 使用编译器选项
-fsanitize=[option]构建的 C/C++ 应用程序无法享受本文档中所提供的 API 或 ABI 保障。实现检测工具运行时的检测工具库是兼容性级别 4 的一部分,没有兼容性保障。
CodeReady Linux Builder 存储库
-
CodeReady Linux Builder 存储库中的所有软件包都不被支持。此存储库中的软件包由开发人员维护,通常适用于特定的用例。欢迎开发人员使用这些软件包,但请理解,它们不适用任何兼容性级别。
-
如果发行版中的二进制 RPM 包含只能通过 CodeReady Linux Builder 开发软件包访问的功能(如标头或共享对象符号链接),则这些功能应被视为仅在 CodeReady Linux Builder 中可用。
保留二进制兼容性的指南
红帽建议应用程序开发人员采用以下原则来提高二进制兼容性:
-
仅使用适合应用程序需要的兼容性级别中列出的库和应用程序。
-
使用发布的库的接口构建应用程序。未发布的(内部)接口可以随时改变,如果依赖这些接口,可能会在其依赖的应用程序中导致不稳定。
-
如果库提供了开发软件包,则必须安装并使用该开发软件包(包括任何提供的标头),以进行您自己的开发。如果库不提供开发软件包,或者没有提供用于链接的一组标头和共享对象,那么任何兼容性保证都不涵盖该库的 API 和 ABI。
-
您必须链接您的应用程序所需的所有的库。无法链接所有必需的库被称为"underlinking"。未链接的应用程序无法利用 ABI 兼容性。
-
如果应用程序动态调用一个 ELF 版本化的符号,则必须使用 glibc
dlvsymAPI ,以便请求该特定版本的特定符号。如果使用dlsymAPI (未指定版本),则您会始终获得符号的最新版本,因此最新的 API 行为可能不适用于您的应用程序。
-
-
只有当应用程序在与它所构建的环境一样新或更新的环境中执行时,才能保证它能正确运行。例如,在 Red Hat Enterprise Linux 9.0 上编译应用程序意味着只能保证您的应用程序在 Red Hat Enterprise Linux 9.0 或更高版本上正确运行,具体取决于您所依赖的组件的兼容性级别。
-
应用程序开发人员应验证他们所依赖的任何行为均在公布的 API 文档中描述了,以防止对未指定的特定于实现的语义引入依赖或对 API 的特定实现中 bug 引入依赖。例如,如果旧行为与发布的规范不一致,则 GNU C 库的新版本无法保证与旧版本兼容。
-
避免库(C/C++)的静态链接。静态链接导致可执行文件有自己版本的库。这会增加应用程序无法在更新版本的操作系统上运行的可能性,因为这些库依赖可能在此过程中发生了改变。强烈建议动态链接应用程序,以避免出现这个问题。
-
使用 RPM 机制打包应用程序。RPM 提供了一种软件打包机制,其包括应用程序依赖项的一个详细规范。在创建 RPM 时,应该注意以下几点:
-
使用合适的 RPM 语法明确说明所有必需的运行时和构建依赖项。建议您尽可能依赖自动依赖项跟踪,并避免通过 AutoReqProv、AutoReq 和 AutoProv 标签禁用自动依赖。
-
不要修改、替换或重新编译红帽提供的软件包管理的文件。这样做可能导致无法预测的行为。
-
考虑依赖项时,请勿假定所有可能的软件包都将安装在每个 Red Hat Enterprise Linux 系统上。默认安装的软件包可能会在主版本之间、在相同版本的产品变体之间以及在客户系统上有变化。始终依赖应用程序正常工作所需的所有软件包,且不期望间接依赖项将保持不变。
-
-
在安装程序时,遵循文件系统层次结构标准(FHS)版本 2.3 或更高版本。第三方软件应安装到 '/opt' 子目录下。有关 FHS 的更多信息,请访问 http://www.pathname.com/fhs/。
-
不要设计依赖于系统软件包或其他组件提供的配置文件的应用程序。除非上游社区明确承诺保留它们,否则这些文件可能会在版本之间有所变化。
-
不要安装与红帽提供的系统组件名称相同的软件包、模块或其他全局标识符。这包括 RPM 软件包名称(包括 Provides)、共享对象名称(soname,例如,libpthread.so.0)和符号名称(如日志),但也包括 Python 软件包名称和系统使用的 D-Bus 总线端点。
-
如果您需要目前还没有在任何应用程序兼容性级别中列出的组件的功能,或者您希望组件移到不同的兼容性级别,请联系您的支持代表进行审核。
-
不要依赖于比您的应用程序更短的兼容性保证的组件。有关软件包列表及其兼容性级别的信息,请参阅 特定软件包和库的兼容性级别。
-
不要依赖于特定的 Linux 内核版本。避免从 proc、sys 和 debug 文件系统,或者任何其他伪文件系统(pseudo-filesystem)读取。避免使用 ioctls 来直接与硬件进行交互。
备注:在主版本的生命周期中,红帽做出了合理的商业努力,来维护所有次发行版本及勘误公告中运行时环境的二进制兼容性。如有必要,红帽可能会对严重影响安全性或其他重要问题的兼容性目标进行例外处理。另外,如上及 特定软件包和库的兼容性级别 中所述,Red Hat Enterprise Linux 的主版本仅包含有限的一组在之前主版本中包含的向后兼容库,以帮助轻松迁移应用程序。通常,红帽会以这种方式应用更改,来最小化更改量,并保持二进制兼容性。
特定软件包和库的兼容性级别
对于每个兼容性级别,红帽定义了二进制软件包,其提供了是兼容性级别一部分的 API 和 ABI。可以在 Red Hat Enterprise Linux 9 软件包清单 中查看每个软件包的特定的兼容性级别。
Comments