Red Hat Enterprise Linux 8:
Application Compatibility Guide
Note: this article discusses Application Compatibility for Red Hat Enterprise Linux 8. For Red hat Enterprise Linux 7 please see the Red Hat Enterprise Linux 7: Application Compatibility GUIDE.
Table of Contents
- Executive Summary
- Scope of Compatibility
- Compatibility exceptions
- Guidelines for Preserving Binary Compatibility
- Appendix A: Compatibility Levels for Specific Packages and Libraries
This guide is intended to provide software developers with Red Hat's guidelines regarding support of third-party applications across multiple releases of the Red Hat® Enterprise Linux® platform. ISV and customer applications can reduce or avoid migration issues between major and minor Red Hat® Enterprise Linux® versions by following these guidelines during application development.
This document describes the recommended uses of the system application programming (API) and binary interfaces (ABI) that are intended to provide compatibility across Red Hat® Enterprise Linux® releases. It outlines the tiered framework under which applications are considered compatible or not compatible.
The purpose of this document is to provide guidance regarding the stability of applications and libraries written for RHEL and run under newer releases of RHEL. The document focuses primarily on issues of software backwards-compatibility. Although backwards compatibility is the goal, development of new capabilities or security concerns sometimes makes that impractical. Hence, the guidelines and published policy may sometimes be overridden by the objective of providing our customers with the most competitive, secure, and capable systems possible; situational testing is always recommended.
If additional clarification of these compatibility guidelines is required, please contact your Red Hat representative.
The following are basic terms used in this document:
Application programming interface (API)
An API is a public interface implemented by a software program that enables it to interact with other software, including operating system components. The API is enforced at compile time and determines source compatibility, that is, whether application source code will compile similarly across different versions of the operating environment. It covers details such as:
- C and C++ headers for developer use
- Language syntax, but only where it applies to a published standard
- Public interface definitions
- Command line interfaces, but only where it applies to documented public interfaces
Application binary interface (ABI)
An ABI is a set of runtime conventions that interact with a compiled binary representation of a program. The ABI is enforced at runtime and it describes the low-level interface between an application and the operating environment. It covers details such as:
- Data type, size, and alignment
- Layout of aggregate types, C++ run-time type information, virtual tables
- The calling standard, which defines how function arguments are passed and return values retrieved
- The binary format of object files and program libraries
- Presence and format of (asynchronous) unwinding information
- Function and / or data symbol names and their versions, and symbol sizes (for data symbols)
- Bytecode or any intermediate representation and the public interfaces to the virtual machine
Tools such as compilers, linkers, runtime libraries, and the operating system itself needs to work with the ABI. The output of CLI tools is not considered a stable ABI.
A compiler conforms to an ABI if it generates code that follows all of the specifications enumerated by that ABI. A library conforms to an ABI if it is implemented according to that ABI. An application conforms to an ABI if it is built using tools that conform to that ABI and does not contain source code that changes behavior specified by the ABI or that otherwise bypasses the ABI.
Binary compatibility means application binaries that are compiled for a specific ABI, generally for a combination of RHEL and a particular hardware architecture, will load and run similarly across different versions of RHEL. Application binaries consist of executable files, Dynamic Shared Objects (DSO), source, bytecode for interpreted just-in-time compiled languages, and their required data files.
Core persistent system infrastructure
The core persistent system infrastructure refers to interfaces and externally available data structures that represent system state or provide a means of communicating with the system (for instance, system calls and header files).
Compatibility in a virtualized environment
Virtual environments emulate bare-metal environments such that unprivileged applications that run on bare-metal environments will run, unmodified, in corresponding virtual environments. Virtual environments present simplified abstracted views of physical resources, so some differences may exist.
Compatibility in a Containerized environment
Container environments provide isolation from the host OS, and at a minimum allows the application to run in an isolated manner from the host OS libraries and binaries, but still share the same OS kernel as all other containers on the host.
Major and minor releases
A Red Hat major release represents a significant step in the development of a product (wholesale changes are usually reserved for major releases). Minor releases appear more frequently within the scope of a major release and generally represent smaller, incremental developmental steps.
An installable language, application, database, or other functional set of packages that run on RHEL. Components may be packaged as modules, Software Collections, or traditional RPMs. Components may be made available in container images.
Application Streams make multiple versions of components available for installation on RHEL systems. Each different version is called a stream. PHP 7.2 is a stream, as is PHP 7.3. Application Streams may be packaged as SCLs, Modules, or traditional RPMs. Many Application Streams have a specified lifecycle, i.e. 3 years, and therefore are compatibility level 3 as described below.
Software Collection (SCL)
A well-integrated, well-tested set of packages released together as a distinct unit. Software Collections deliver newer stable versions of components for use with Red Hat Enterprise Linux.
A module is a collection of RPMs with associated metadata, and are installed as a group or removed as a group. Modules are the mechanism by which some larger components, like databases, can deliver multiple versions. Modules are available in one or multiple streams. A module stream usually represents a major version of a piece of software, giving the user the option to choose what versions of the software packages they want to consume. Modules may be used for an Application Stream or may be dependent modules for other Modules. RPMs not listed in the module’s API are considered implementation details and are not subject to compatibility guarantees provided by the module.
SystemTap Static Probes
SystemTap static probes are part of the SystemTap profiling and tracing framework. The probes are integrated into key system libraries to support profiling and debugging of applications and libraries.
File Hierarchy Standard (FHS)
A file system structure which defines the names, locations, and permissions for various file types and directories. FHS-compliant file systems are compatible with each other and have the ability to mount a /usr/ partition as read only. The latter is important because the partition contains common executables and should not be changed by users.
CodeReady Linux Builder Repository
The CodeReady Linux Builder repository contains components that a developer would use during the development of their RHEL application, but which would not be deployed in production. The components in the CodeReady Linux Builder repository are unsupported.
All components and packages in Red Hat Enterprise Linux are classified under one of the following four compatibility levels:
Compatibility level 1
- APIs and ABIs are stable within the lifetime of a major release and ABIs are also stable across the next two major releases; the release that introduces a new or revised ABI, and the two following major releases (n, n+1, n+2). In the case of this document, release n starts with Red Hat Enterprise Linux 8. If a change to a library causes an incompatibility with existing binaries, a separate version of the library will be provided with the older ABI to run the application without modification.
Compatibility level 2
- APIs and ABIs are stable within the lifetime of a single major release. Compatibility level 2 application interfaces will not change from minor release to minor release and can be relied upon by the application to be stable for the duration of the major release. Compatibility level 2 is the default for packages in Red Hat Enterprise Linux 8. Packages not identified as having another compatibility level may be considered compatibility level 2.
Compatibility level 3
- This level applies to languages, tools, and applications included with Red Hat Enterprise Linux. Each component will specify a lifetime during which the API and ABI will be supported. Newer versions (i.e. PHP7.2 and PHP7.3) will attempt to be as API and ABI compatible from version to version as possible. Version to version compatibility is not guaranteed, however.
- Components and developer tools that receive continuous updates, referred to as toolsets, should be considered compatibility level 3. Developers should use caution and understand how these components change with each release.
Compatibility level 4
- No compatibility is provided. ABI and API can change at any point. These components should not be used by applications needing long term support.
Notes on Compatibility levels
Compatibility levels for bare-metal configurations also apply to virtualized and containerized configurations except for any features that directly interact with hardware. Those features directly related to hardware have no API or ABI compatibility level. For example, applications that rely on Graphics Processing Unit (GPU) features cannot expect binary compatibility.
Red Hat requests that application developers validate that any behavior they depend on is explicitly defined in formal API documentation to prevent introducing dependencies on unspecified implementation-specific behavior or dependencies on bugs in a particular implementation of an API. For example, new releases of the GNU C library (glibc) may not be compatible with older releases if an application uses an undocumented API or relies on undefined behavior.
Your support representative will be happy to guide you through any specific questions you may have.
The following are exceptions to compatibility in RHEL.
SystemTap Static Probes
- No assurances are made at this time that integrated SystemTap static probes will continue to have the same probe name, probe location, or interpretation or number of arguments. Since the probes are primarily designed for deep analysis and debugging the probes must be able to change as the underlying implementation changes.
Static Linking with the C/C++ Runtime
- Static linking with the C/C++ runtime is not supported. This includes linking with any files that are part of the glibc-static or libstdc++-static packages. You may choose to link statically, but the resulting application binaries may fail to operate if any package in the installation is changed.
C/C++ application sanitizers
- C/C++ applications built with the compiler option “-fsanitize=[option]” cannot participate in the API or ABI guarantees provided in this document. The sanitizer libraries which implement the sanitizer runtimes are part of Compatibility Level 4 and have no compatibility guarantees.
CodeReady Linux Builder Repository
- All packages in the CodeReady Linux Builder repository are unsupported. Packages in this repository are maintained for use by developers, often for specific use cases. Developers are welcome to use these packages understanding that no compatibility levels apply.
- If a binary rpm in the distribution contains features accessible only through a CodeReady Builder development package e.g. headers or shared object symlink, then those features should be considered as if they were available only in CodeReady Linux Builder.
Guidelines for Preserving Binary Compatibility
Red Hat recommends that application developers adopt the following principles in order to improve binary compatibility:
Use only libraries and applications listed in the compatibility level that suits your application needs.
Build applications using the published interfaces of a library. Non-published (internal) interfaces are subject to change at any time, which can cause instability in the dependent application if relied upon.
- If the library provides a development package you must install and use that development package, including any provided headers, for your own development. If the library does not provide a development package or does not provide a set of headers and shared object for linking, then the API and the ABI of that library is not covered by any compatibility guarantees.
- You must link with all libraries that are required by your application. Failing to link against all required libraries is called “underlinking.” An underlinked application cannot take advantage of ABI compatibility.
- If the application dynamically calls an ELF versioned symbol it must use the glibc dlvsym API in order to request that specific symbol at that specific version. If you use the dlsym API (no version specifier) you always get the latest version of the symbol, and thus the latest API behavior, which may not be suitable for your application.
An application is only guaranteed to run correctly if it executes in an environment that is as new as the environment it was built in or newer. For example compiling your application on Red Hat Enterprise Linux 8.0 means your application is only guaranteed to run correctly on Red Hat Enterprise Linux 8.0 or later depending on the compatibility level of the components you depend upon.
Application developers should validate that any behavior they depend on is described in the published API documentation to prevent introducing dependencies on unspecified implementation-specific semantics or introducing dependencies on bugs in a particular implementation of an API.
For example, new releases of the GNU C library are not guaranteed to be compatible with older releases if the old behavior was not consistent with a published specification.
Avoid static linking of libraries (C/C++). Static linking causes the executables to have their own version of the library. This increases the chance of an application not running predictably on a later version of the operating system as these library dependencies might have changed along the way. Linking applications dynamically is strongly recommended in order to avoid this problem.
Package applications using the RPM mechanism. RPM provides a software-packaging mechanism that includes a detailed specification of application dependencies. When creating RPMs, the following should be kept in mind:
*Explicitly state all required runtime and build dependencies using the appropriate RPM syntax. It is recommended you rely on automatic dependency tracking where possible and avoid disabling via AutoReqProv, AutoReq, and AutoProv tags.
- Do not modify, replace, or recompile files managed by Red Hat-provided packages. Doing so may lead to unpredictable behavior.
- When considering dependencies, do not assume that all possible packages will be installed on every Red Hat Enterprise Linux system. The default installed packages may change between major releases, between product variants of the same version, and on a customer’s system. Always depend on all the packages your application needs to work and do not expect that transitive dependencies will remain unchanged.
Follow the Filesystem Hierarchy Standard (FHS) version 2.3 or higher when installing programs. Third-party software should be installed to the '/opt' subdirectory. More information on the FHS is available at http://www.pathname.com/fhs/.
- Do not design applications that rely on configuration files provided by system packages or other components. These files can change between versions unless the upstream community is explicitly committed to preserving them.
- Do not install packages, modules or other global identifiers with the same names as system components shipped by Red Hat. This includes RPM package names (including Provides), shared object names (sonames, e.g. libpthread.so.0), and symbol names (e.g., log), but also Python package names, and D-Bus endpoints used by the systems.
- If you require functionality from a component that is currently not listed in any of the application compatibility levels, or if you would like a component to be moved to a different compatibility level, please contact your support representative for review.
- Do not depend on components with a shorter compatibility guarantees than your application. Please see the appendix for a list of packages and their compatibility level.
- Do not depend on a specific Linux kernel version. Avoid reading from proc, sys, and debug filesystems, or any other pseudo-filesystem. Avoid using ioctls to directly interact with hardware.
Note: During the life cycle of a major release, Red Hat makes commercially reasonable efforts to maintain the binary compatibility of the runtime environment across all minor releases and errata advisories. If necessary, Red Hat may make exceptions to this compatibility goal for critical impact security or other significant issues. Furthermore, as described above and in Appendix A, major releases of Red Hat Enterprise Linux contain a limited set of backward-compatible libraries included in previous major releases to allow for the easy migration of applications. Typically, Red Hat applies changes in such a way as to minimize the amount of change and to maintain binary compatibility.
Appendix A: Compatibility Levels for Specific Packages and Libraries
For each compatibility level we define the binary packages which provide APIs and ABIs that are part of the compatibility level. As a convenience we list the source RPM from which those binary RPM(s) were built, but that source RPM is not considered to be a part of the compatibility level.
Compatibility level 1 (CL1): APIs and ABIs are stable across three major releases (starting with RHEL 8)
|Source RPM(s) (for reference)||Binary RPM(s) in level 1|
|glibc||glibc (does not include package glibc-static)|
|gcc||libstdc++, libgcc, libgomp, libatomic|
|elfutils||elfutils-libelf (does not include package elfutils-libelf-static-devel)|
|libglvnd||libglvnd-glx, libglvnd-egl, libglvnd-gles, libglvnd-opengl|
Compatibility level 2: APIs and ABIs are stable within one major release
Note: This list below is a list of commonly used packages and is included for easy reference. It is not a complete list. Any component not included in a compatibility level listing in this document can be assumed to be level 2 and can be relied upon for compatibility within a major release, i.e. during the life of Red Hat Enterprise Linux 8.
|Source RPM(s) (for reference)||Binary RPM(s) in CL2|
|gcc||libgfortran (specifically shared library libgfortran.so.5), libquadmath|
|tbb||tbb, tbb-devel, tbb-doc, python3-tbb|
Compatibility level 3: APIs and ABIs are stable for the published life of the component
The current set of level 3 content can be viewed here: Red Hat Enterprise Linux 8 Application Streams Life Cycle
Level 3 content has the same ABI and API compatibility as level 2 content, only the maintenance interval is different, as defined in the Application Stream table.
Compatibility level 4: Stability of APIs or ABIs subject to change at Red Hat's discretion
|Source RPM(s) or Modules (for reference)||Binary RPM(s) or Module:Stream in CL4|
|gcc||libasan, libasan-static, libatomic-static, libgfortran-static, libitm, libitm-static, liblsan, liblsan-static, libstdc++-static, libtsan, libtsan-static, libubsan,, libubsan-static|
|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|
|bind||bind-devel, bind-export-devel, bind-export-libs, bind-libs, bind-libs-lite, bind-lite-devel, bind-pkcs11-devel, bind-pkcs11-libs|
|libteam||libteam, libteam-devel, network-scripts-team, python3-libteam, teamd, teamd-devel, libteam-doc|
|dpdk||dpdk, dpdk-devel, dpdk-doc, dpdk-tools|
|webkit2gtk3||webkit2gtk3, webkit2gtk3-devel, webkit2gtk3-jsc, webkit2gtk3-jsc-devel, webkit2gtk3-plugin-process|
|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|
|qatlib||qatlib qatlib-devel qatlib-tests|
|qatzip||qatzip qatzip-libs qatzip-devel|
|xxhash||xxhash, xxhash-devel, xxhash-doc, xxhash-libs|