Red Hat Enterprise Linux 8: 应用程序兼容性指南
Red Hat Enterprise Linux 8:
应用程序兼容性指南
2019 年 5 月
备注:本文讨论了 Red Hat Enterprise Linux 8 的应用程序兼容性。对于 Red Hat Enterprise Linux 7,请查看 Red Hat Enterprise Linux 7:应用程序兼容性指南。
内容表
摘要
本指南旨在为独立开发人员提供有关在多个 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 内核。 -
主版本和次版本
红帽主(major)版本代表了一个产品的主要开发成果(对一个产品的整体变化通常包括在主版本中)。次发行版本会出现在主发行版本范围内,通常代表一个较小的增量开发成果。 -
组件
一个在 RHEL 上运行的可安装的语言、应用程序、数据库或其他软件包集。组件可以打包为模块、软件集合或传统的 RPM。容器镜像中可能会提供组件。 -
应用程序流
应用程序流提供了可以在 RHEL 系统中使用的组件的多个版本。每个不同的版本都被称为一个流(stream)。PHP 7.2 是一个流,PHP 7.3 也是一个流。应用程序流可以打包为 SCL、模块或传统的 RPM。许多应用程序流都有一个特定的生命周期(如 3 年)和兼容性级别(如兼容性级别 3),如下所述。 -
软件集合 (Software Collection,简称 SCL)
作为一个特殊单元发布的一组集成的、并经过测试的软件包。软件包集合提供与 Red Hat Enterprise Linux 搭配使用的较新版本的组件版本。 -
模块化
模块是一个包含了一组带有相关元数据的 RPM 集合,它作为一个组进行安装或作为一个组进行卸载。模块是一些大型组件(如数据库)用于提供多个版本的一个机制。模块可以包括在一个或多个流中。一个模块流通常代表了一个软件的一个主版本,用户可以选择要使用的软件包版本。模块可用于应用程序流,也可以是其他模块的一个依赖模块。没有在模块 API 中列出的 RPM 被视为是实现详情,不受模块提供的兼容性的保证。 -
SystemTap 静态探测
SystemTap 静态探测是 SystemTap 分析和追踪框架的一部分。探测被集成到关键的系统库中,以支持对应用程序和库进行分析和调试。 -
文件层次结构标准(File Hierarchy Standard,简称FHS)
一个文件系统结构,用于定义各种文件类型和目录的名称、位置和权限。符合 FHS 的文件系统彼此兼容,并可以只读模式挂载 /usr/ 分区。以只读方式挂载非常重要,因为分区中包含常见的可执行文件,用户不应更改它们。 -
CodeReady Linux Builder 仓库
CodeReady Linux Builder 仓库包含开发人员在开发其 RHEL 应用程序时使用的、但不会部署到生产环境中的组件。CodeReady Linux Builder 仓库中的组件不被支持。
兼容性级别
Red Hat Enterprise Linux 中的所有组件和软件包分为以下四个兼容性级别之一:
-
兼容性级别 1
- API 和 ABI 在一个主版本的整个生命周期内是稳定的,ABI 在后续的两个主版本中也是稳定的;引入新的或修订的 ABI 的版本,以及随后的两个主版本(n、n+1、n+2)。对于本文档,版本 n 从 Red Hat Enterprise Linux 8 开始。如果对库的更改导致与现有二进制文件不兼容,则在提供旧的 ABI 外还同时提供一个单独版本的库,以便可以在不进行修改的情况下运行应用程序。
-
兼容性级别 2
- API 和 ABI 在一个主版本的整个生命周期内是稳定的。兼容性级别 2 的应用程序接口在不同的次发行版本间没有变化,这可以保证应用程序在主版本的整个生命期间内是稳定的。兼容性级别 2 是 Red Hat Enterprise Linux 8 中软件包的默认设置。当软件包没有被明确指明为另外一个兼容性级别时,被视为兼容性级别 2。
-
兼容性级别 3
- 该级别适用于 Red Hat Enterprise Linux 中包含的语言、工具和应用程序。每个组件都将指定一个生命周期,在此期间 API 和 ABI 会被支持。较新的版本(如 PHP7.2 和 PHP7.3)将尽量在不同版本间保持 API 和 ABI 兼容。但是,并不法保证在不同版本间的兼容性。
- 组件和开发者工具程序(称为工具集)会持续更新,应被视为兼容性级别 3。对于这个级别的组件,开发人员应非常谨慎,并了解这些组件在不同发行版本中的改变。
-
兼容性级别 4
- 不提供兼容性。ABI 和 API 可能会随时改变。这些组件不应在需要长期支持的应用程序中使用。
兼容性级别备注
裸机配置的兼容性级别也适用于虚拟化和容器化配置,虚拟化和容器化设置中需要直接与硬件进行交互的功能除外。与硬件直接相关的功能没有 API 或 ABI 兼容性级别。例如,依赖图形处理单元 (GPU) 功能的应用程序应该没有二进制兼容性。
红帽要求应用程序开发人员验证他们所依赖的所有行为都在正式的 API 文档中明确定义,以防止出现依赖未被明确指定行为的情况,或防止出现依赖一个 API 实现中的程序错误的情况。例如,如果一个应用程序使用了一个没有包括在正式文档中的 API,或依赖于一个未被定义的行为,则新的 GNU C 库 (glibc) 版本可能与它不兼容。
如果您有任何特定的问题,请联系红帽的支持团队。
兼容性例外
以下是 RHEL 中兼容性的例外。
SystemTap 静态探测
- 目前,不保证集成的 SystemTap 静态探测器将继续具有相同的探测器名称、探测器位置或以相同的方式处理参数。因为探测器主要是为深入分析和调试而设计的,所以探测器需要根据底层实现的变化而进行相应的修改。
使用 C/C++ 运行时的静态链接
- 不支持使用 C/C++ 运行时的静态链接。这包括与作为 glibc-static 或 libstdc++-static 软件包的任何文件的链接。您可以选择静态链接,但如果安装中的任何软件包已更改,则生成的应用程序二进制文件可能无法运行。
C/C++ 应用程序清理器
- 使用编译器选项 “-fsanitize=[option]” 构建的 C/C++ 应用程序不适用于本文档中介绍的 API 或 ABI 保证。实施 sanitizer 运行时的 sanitizer 库是兼容性级别 4 的一部分,没有兼容性保证。
CodeReady Linux Builder 仓库
- CodeReady Linux Builder 仓库中的所有软件包都不被支持。此仓库中的软件包由开发人员维护,通常适用于特定的用例。开发人员可以选择使用这些软件包,但应考虑到它们的兼容性。
- 如果在发行版中的二进制 rpm 中包括了只通过 CodeReady Builder 开发软件包实现的功能(如标头或共享对象符号链接),则这些功能应被视为仅由 CodeReady Linux Builder 提供。
保留二进制代码兼容性指南
为了提供二进制的兼容性,红帽建议应用程序开发人员遵循以下原则:
-
仅使用符合您的应用程序需要的兼容性级别中列出的库和应用程序。
-
使用一个库所公布的接口来构建应用程序。未公布的(内部)接口可能会随时有改变,这会影响到依赖它的应用程序。
- 如果库提供了一个开发软件包,则需要安装并使用开发软件包(包括它所提供的头文件)来开发自己的应用程序。如果库没有提供开发软件包,或者没有提供用于链接的一组头文件和共享对象,则库的 API 和 ABI 将不适用于任何兼容性保证。
- 您需要链接应用程序所需的所有库。没有使用所有要求的库进行链接被称为 "underlink"。 一个 underlink 的应用程序无法利用 ABI 兼容性所提供的益处。
- 如果应用程序需要动态调用一个 ELF 版本化符号,则必须使用 glibc dlvsym API 来请求该特定版本的特定符号。如果使用 dlsym API (没有版本指定符),则会始终使用符号的最新版本。但需要注意,最新版本的 API 的行为可能不适用于您的应用程序。
-
只有在其运行的环境与其构建的环境一样新或更新时,才可以保证应用程序可以正常运行。例如,在 Red Hat Enterprise Linux 8.0 上编译的应用程只保证在 Red Hat Enterprise Linux 8.0 或更高版本中可以正常运行,具体取决于您依赖的组件的兼容性级别。
-
应用程序开发人员需要验证,应用程序依赖的任何行为都在正式的 API 文档中明确定义,以防止出现依赖未被明确指定行为的情况,或防止出现依赖一个 API 实现中的程序错误的情况。
-
例如,当旧版本的行为与正式公布的规格不一致时,一个新版本的 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)、共享对象名称(sonames,例如,libpthread.so.0)和符号名(如 log),另外还包括 Python 软件包名以及系统使用的 D-Bus 端点。
- 如果您需要使用来自当前还没有处于任何应用程序兼容性级的组件的功能,或您希望将一个组件从一个级别移到另一个级别,请联系您的支持代表进行审核。
- 不要依赖于其兼容性保证比您的应用程序的兼容性保证更短的组件。有关软件包及其兼容性级别列表,请查看附录。
- 不要依赖于特定的 Linux 内核版本。避免读取 proc、sys 和 debug 文件系统,或者任何其他伪文件系统(pseudo-filesystem)。避免使用 ioctls 直接与硬件交互。
备注:在主版本的生命周期内,红帽以合理的商业投入,维护所有次发行版本及勘误公告中内核运行时环境的二进制兼容性。但是如有必要,红帽会就安全影响级别为“关键(Critical)”的安全问题或者其他严重问题在兼容性方面做例外处理。另外,如以上和附录 A 所述,Red Hat Enterprise Linux 的主版本包含一组有限的、与以前主版本中包括的库向后兼容的库,以方便用户轻松迁移应用程序。通常,红帽会使用这种方式应用更改,从而最大程度降低变化带来的影响并保持二进制兼容性。
附录 A:特定软件包和库的兼容性等级
对于每个兼容性级别,我们定义提供兼容级别的 API 和 ABI 的二进制软件包。为方便起见,我们列出了构建二进制 RPM 的源 RPM,但源 RPM 不被视为是兼容性级别的一部分。
兼容性级别 1 (CL1):在三个主版本(从 RHEL 8 开始)中,API 和 ABI 是稳定的。
源 RPM (仅供参考) | 级别 1 中的二进制 RPM |
---|---|
glibc | glibc (不包含软件包 glibc-static) |
gcc | libstdc++, libgcc, libgomp, libatomic |
elfutils | elfutils-libelf (不包括软件包 elfutils-libelf-static-devel) |
krb5 | krb5-libs |
libxml2 | libxml2 |
libxslt | libxslt |
libglvnd | libglvnd-glx, libglvnd-egl, libglvnd-gles, libglvnd-opengl |
mesa-libGLU | mesa-libGLU |
pam | pam |
vulkan-loader | vulkan-loader |
zlib | zlib |
兼容性级别 2:API 和 ABI 在一个主发行版本中是稳定的
注意:以下一个常用软件包列表,仅用于方便参考。它并不是一个完整的列表。未包括在本文档中的兼容性级别列表中的任何组件都可以被认为是级别 2,它们在一个主版本的生命周期内(例如,在 Red Hat Enterprise Linux 8 生命周期中)具有兼容性。
源 RPM (仅供参考) | CL2 中的二进制 RPM |
---|---|
gcc | libgfortran (特别是共享库 libgfortran.so.5), libquadmath |
tbb | tbb, tbb-devel, tbb-doc, python3-tbb |
SDL | SDL |
libusb | libusb |
alsa-lib | alsa-lib |
libmodulemd | libmodulemd |
gtk2 | gtk2 |
gtk3 | gtk3 |
motif | motif |
libacl | libacl |
libattr | libattr |
libvirt | libvirt-client |
libX11 | libX11 |
libXaw | libXaw |
libXau | libXau |
libXrandr | libXrandr |
libXrender | libXrender |
libXext | libXext |
libXft | libXft |
libXi | libXi |
libXmu | libXmu |
libXpm | libXpm |
qt5-qt5base | qt5-qt5base |
bzip2 | bzip2-libs |
curl | libcurl |
xz | xz-libs |
systemd | systemd-libs |
dbus | dbus-libs |
openssl | openssl-libs |
gnutls | gnutls |
nss | nss |
libgcrypt | libgcrypt |
libssh | libssh |
兼容性级别 3:在组件的发布生命周期中,API 和 ABI 是稳定的
当前为级别 3 的组件包括在:Red Hat Enterprise Linux 8 Application Streams 生命周期
级别 3 的内容与级别 2 的内容具有相同的 ABI 和 API 兼容性,不同之处是维护的间隔不同,如应用程序流表中定义。
兼容性级别 4:红帽可自由裁量更改 API 或 ABI 的可靠性
源 RPM 或模块(仅供参考) | CL4 中的二进制 RPM 或 Module:Stream |
---|---|
gcc | libasan, libasan-static, libatomic-static, libgfortran-static, libitm, libitm-static, liblsan, liblsan-static, libstdc++-static, libtsan, libtsan, libubsan, libubsan-static |
glibc | glibc-static |
libxcrypt | libxcrypt-static |
libmodulemd | libmodulemd1 |
libnftnl | libnftnl, libnftnl-devel |
lttng-ust | lttng-ust, lttng-ust-devel |
libcgroup | libcgroup |
libdrm | libdrm |
libglvnd | libglvnd |
libvdpau | libvdpau |
libXfont2 | libXfont2 |
mesa | mesa-libGL, mesa-dri-drivers |
ocl-icd | ocl-icd |
python-evdev | python3-evdev |
vulkan-validation-layers | vulkan-validation-layers |
wayland-protocols | wayland-protocols-devel |
xorg-sgml-doctools | xorg-sgml-doctools |
xorg-x11-server | xorg-x11-server-Xorg, xorg-x11-server-Xwayland |
gnome-desktop | gnome-desktop |
pipewire | pipewire, pipewire-devel, pipewire-libs, pipewire-utils |
pulseaudio | pulseaudio-libs, pulseaudio-module-x11, pulseaudio-module-bluetooth, pulseaudio-module-gconf |
bcc | bcc, bcc-tools, python3-bcc |
kabi-dw | kabi-dw |
criu | criu, python3-criu |
nettle | nettle |
bind | bind-devel, bind-export-devel, bind-export-libs, bind-libs, bind-libs-lite, bind-lite-devel, bind-pkcs11-devel, bind-pkcs11-libs |
wireshark | wireshark-cli, wireshark-devel |
cracklib | cracklib |
samba | samba-libs |
openldap | openldap |
libfastjson | libfastjson |
libestr | libestr |
liblognorm | liblognorm |
librdkafka | librdkafka |
librelp | librelp |
http-parser | http-parser |
openvswitch-selinux-extra-policy | openvswitch-selinux-extra-policy |
virtio-win | virtio-win |
driverctl | driverctl |
ipset | ipset-libs |
libteam | libteam, libteam-devel, network-scripts-team, python3-libteam, teamd, teamd-devel, libteam-doc |
WALinuxAgent | WALinuxAgent |
cloud-init | cloud-init |
open-vm-tools | open-vm-tools |
lldpad | lldpad |
dpdk | dpdk, dpdk-devel, dpdk-doc, dpdk-tools |
webkit2gtk3 | webkit2gtk3, webkit2gtk3-devel, webkit2gtk3-jsc, webkit2gtk3-jsc-devel, webkit2gtk3-plugin-process |
container-tools | container-tools:rhel8 |
HdrHistogram_c | HdrHistogram_c |
xdp-tools | xdp-tools, libxdp |
rhc | rhc |
rhc-worker-playbook | rhc-worker-playbook |
coreos-installer | coreos-installer |
eth-tools | eth-tools-basic, eth-tools-fastfabric |
sevctl | sevctl |
xorg-x11-server-Xwayland | xorg-x11-server-Xwayland |
libbpf | libbpf |
micropipenv | micropipenv |
bind9.16 | bind9.16 bind9.16-chroot bind9.16-libs bind9.16-license bind9.16-utils bind9.16-devel bind9.16-dnssec-utils bind9.16-doc python3-bind9.16 |
fido-device-onboard | fdo-admin-cli fdo-client fdo-init fdo-manufacturing-server fdo-owner-cli fdo-owner-onboarding-server fdo-rendezvous-server |
libzdnn | libzdnn libzdnn-devel |
python-resolvelib | python38-resolvelib |
qatlib | qatlib qatlib-devel qatlib-tests |
qatzip | qatzip qatzip-libs qatzip-devel |
rig | rig |
sshpass | sshpass |
xxhash | xxhash, xxhash-devel, xxhash-doc, xxhash-libs |
yara | yara |
ecj | ecj |
inkscape1 | inkscape1,inkscape1-docs,inkscape1-view |
libwpe | libwpe,libwpe-devel |
libzpc | libzpc,libzpc-devel |
rtla | rtla |
synce4l | synce4l |
tomcat | tomcat,tomcat-admin-webapps,tomcat-docs-webapp,tomcat-el-3.0-api,tomcat-jsp-2.3-api,tomcat-lib,tomcat-servlet-4.0-api,tomcat-webapps |
wpebackend-fdo | wpebackend-fdo,wpebackend-fdo-devel |
Comments