Chapter 6. New features in RHEL 8 This section documents the most notable changes in RPM packaging between Red Hat Enterprise Linux 7 and 8. 6.1. Support for Weak dependencies Weak dependencies are variants of the Requires directive. These variants are matched against virtual Provides: and package names using Epoch-Version-Release range comparisons. Weak dependencies have two strengths ( weak and hint ) and two directions ( forward and backward ), as summarized in the following table. Note The forward direction is analogous to Requires: . The backward has no analog in the dependency system. Table 6.1. Possible combinations of Weak dependencies' strengths and directions Strength/Direction Forward Backward Weak Recommends: Supplements: Hint Suggests: Enhances: The main advantages of the Weak dependencies policy are: It allows smaller minimal installations while keeping the default installation feature rich. Packages can specify preferences for specific providers while maintaining the flexibility of virtual provides. 6.1.1. Introduction to Weak dependencies By default, Weak dependencies are treated similarly to regular Requires: . Matching packages are included in the YUM transaction. If adding the package leads to an error, YUM by default ignores the dependency. Hence, users can exclude packages that would be added by Weak dependencies or remove them later. Conditions of use You can use Weak dependencies only if the package still functions without the dependency. Note It is acceptable to create packages with very limited functionality without adding any of its weak requirements. Use cases Use Weak dependencies especially where it is possible to minimize the installation for reasonable use cases, such as building virtual machines or containers that have a single purpose and do not require the full feature set of the package. Typical use cases for Weak dependencies are: Documentation Documentation viewers if missing them is handled gracefully Examples Plug-ins or add-ons Support for file formats Support for protocols 6.1.2. The Hints strength Hints are by default ignored by YUM . They can be used by GUI tools to offer add-on packages that are not installed by default but can be useful in combination with the installed packages. Do not use Hints for the requirements of the main use cases of a package. Include such requirements in the strong or Weak dependencies instead. Package Preference YUM uses Weak dependencies and Hints to decide which package to use if there is a choice between multiple equally valid packages. Packages that are pointed at by dependencies from installed or to be installed packages are preferred. Note, the normal rules of dependency resolution are not influenced by this feature. For example, Weak dependencies cannot enforce an older version of a package to be chosen. If there are multiple providers for a dependency, the requiring package can add a Suggests: to provide a hint to the dependency resolver about which option is preferred. Enhances: is only used when the main package and other providers agree that adding the hint to the required package is for some reason the cleaner solution. Example 6.1. Using Hints to prefer one package over another If you want to prefer the mariadb package over the community-mysql package use: 6.1.3. Forward and Backward dependencies Forward dependencies are, similarly to Requires , evaluated for packages that are being installed. The best of the matching packages are also installed. In general, prefer Forward dependencies . Add the dependency to the package when getting the other package added to the system. For Backward dependencies , the packages containing the dependency are installed if a matching package is installed as well. Backward dependencies are mainly designed for third party vendors who can attach their plug-ins, add-ons, or extensions to distribution or other third party packages. 6.2. Support for Boolean dependencies Starting with version 4.13, RPM is able to process boolean expressions in the following dependencies: Requires Recommends Suggests Supplements Enhances Conflicts The following sections describe boolean dependencies syntax , provides a list of boolean operators , and explains boolean dependencies nesting as well as boolean dependencies semantics . 6.2.1. Boolean dependencies syntax Boolean expressions are always enclosed with parenthesis. They are build out of normal dependencies: Name only or name Comparison Version description 6.2.2. Boolean operators RPM 4.13 introduced the following boolean operators: Table 6.2. Boolean operators introduced with RPM 4.13 Boolean operator Description Example use and Requires all operands to be fulfilled for the term to be true. Conflicts: (pkgA and pkgB) or Requires one of the operands to be fulfilled for the term to be true. Requires: (pkgA >= 3.2 or pkgB) if Requires the first operand to be fulfilled if the second is. (reverse implication) Recommends: (myPkg-langCZ if langsupportCZ) if else Same as the if operator, plus requires the third operand to be fulfilled if the second is not. Requires: myPkg-backend-mariaDB if mariaDB else sqlite RPM 4.14 introduced the following additional boolean operators: Table 6.3. Boolean operators introduced with RPM 4.14 Boolean operator Description Example use with Requires all operands to be fulfilled by the same package for the term to be true. Requires: (pkgA-foo with pkgA-bar) without Requires a single package that satisfies the first operand but not the second. (set subtraction) Requires: (pkgA-foo without pkgA-bar) unless Requires the first operand to be fulfilled if the second is not. (reverse negative implication) Conflicts: (myPkg-driverA unless driverB) unless else Same as the unless operator, plus requires the third operand to be fulfilled if the second is. Conflicts: (myPkg-backend-SDL1 unless myPkg-backend-SDL2 else SDL2) Important The if operator cannot be used in the same context with the or operator, and the unless operator cannot be used in the same context with and . 6.2.3. Nesting Operands themselves can be used as boolean expressions, as shown in the below examples. Note that in such case, operands also need to be surrounded by parenthesis. You can chain the and and or operators together repeating the same operator with only one set of surrounding parenthesis. Example 6.2. Example use of operands applied as boolean expressions 6.2.4. Semantics Using Boolean dependencies does not change the semantic of regular dependencies. If Boolean dependencies are used, checking for one match all names are checked and the boolean value of there being a match is then aggregated over the Boolean operators. Important For all dependencies with the exception of Conflicts: , the result has to be True to not prevent an install. For Conflicts: , the result has to be False to not prevent an install. Warning Provides are not dependencies and cannot contain boolean expressions. 6.2.5. Understanding the output of the if operator The if operator is also returning a boolean value, which is usually close to what the intuitive understanding is. However, the below examples show that in some cases intuitive understanding of if can be misleading. Example 6.3. Misleading outputs of the if operator This statement is true if pkgB is not installed. However, if this statement is used where the default result is false, things become complicated: This statement is a conflict unless pkgB is installed and pkgA is not: So you might rather want to use: The same is true if the if operator is nested in or terms: This also makes the whole term true, because the if term is true if pkgB is not installed. If pkgA only helps if pkgB is installed, use and instead: 6.3. Support for File triggers File triggers are a kind of RPM scriptlets , which are defined in a spec file of a package. Similar to Triggers , they are declared in one package but executed when another package that contains the matching files is installed or removed. A common use of File triggers is to update registries or caches. In such use case, the package containing or managing the registry or cache should contain also one or more File triggers . Including File triggers saves time compared to the situation when the package controls updating itself. 6.3.1. File triggers syntax File triggers have the following syntax: Where: file_trigger_tag defines a type of file trigger. Allowed types are: filetriggerin filetriggerun filetriggerpostun transfiletriggerin transfiletriggerun transfiletriggerpostun FILE_TRIGGER_OPTIONS have the same purpose as RPM scriptlets options, except for the -P option. The priority of a trigger is defined by a number. The bigger number, the sooner the file trigger script is executed. Triggers with priority greater than 100000 are executed before standard scriptlets, and the other triggers are executed after standard scriptlets. The default priority is set to 1000000. Every file trigger of each type must contain one or more path prefixes and scripts. 6.3.2. Examples of File triggers syntax The following example shows the File triggers syntax: This file trigger executes /usr/bin/ldconfig directly after the installation of a package that contains a file having a path starting with /usr/lib or /lib . The file trigger is executed just once even if the package includes multiple files with the path starting with /usr/lib or /lib . However, all file names starting with /usr/lib or /lib are passed to standard input of trigger script so that you can filter inside of your script as shown below: This file trigger executes /usr/bin/ldconfig for each package containing files starting with /usr/lib and containing foo at the same time. Note that the prefix-matched files include all types of files including regular files, directories, symlinks and others. 6.3.3. File triggers types File triggers have two main types: File triggers executed once per package File triggers executed once per transaction File triggers are further divided based on the time of execution as follows: Before or after installation or erasure of a package Before or after a transaction 6.3.3.1. Executed once per package File triggers File triggers executed once per package are: %filetriggerin %filetriggerun %filetriggerpostun %filetriggerin This file trigger is executed after installation of a package if this package contains one or more files that match the prefix of this trigger. It is also executed after installation of a package that contains this file trigger and there is one or more files matching the prefix of this file trigger in the rpmdb database. %filetriggerun This file trigger is executed before uninstallation of a package if this package contains one or more files that match the prefix of this trigger. It is also executed before uninstallation of a package that contains this file trigger and there is one or more files matching the prefix of this file trigger in rpmdb . %filetriggerpostun This file trigger is executed after uninstallation of a package if this package contains one or more files that match the prefix of this trigger. 6.3.3.2. Executed once per transaction File triggers File triggers executed once per transaction are: %transfiletriggerin %transfiletriggerun %transfiletriggerpostun %transfiletriggerin This file trigger is executed once after a transaction for all installed packages that contain one or more files that match the prefix of this trigger. It is also executed after a transaction if there was a package containing this file trigger in that transaction and there is one or more files matching the prefix of this trigger in rpmdb . %transfiletriggerun This file trigger is executed once before a transaction for all packages that meet the following conditions: The package will be uninstalled in this transaction The package contains one or more files that match the prefix of this trigger It is also executed before a transaction if there is a package containing this file trigger in that transaction and there is one or more files matching the prefix of this trigger in rpmdb . %transfiletriggerpostun This file trigger is executed once after a transaction for all uninstalled packages that contain one or more file that matches the prefix of this trigger. Note The list of triggering files is not available in this trigger type. Therefore, if you install or uninstall multiple packages that contain libraries, the ldconfig cache is updated at the end of the whole transaction. This significantly improves the performance compared to RHEL 7 where the cache was updated for each package separately. Also the scriptlets which called ldconfig in %post and %postun in spec file of every package are no longer needed. 6.3.4. Example use of File triggers in glibc The following example shows a real-world usage of File triggers within the glibc package. In RHEL 8, File triggers are implemented in glibc to call the ldconfig command at the end of an installation or uninstallation transaction. This is ensured by including the following scriptlets in the glibc's SPEC file: Therefore, if you install or uninstall multiple packages, the ldconfig cache is updated for all installed libraries after the whole transaction is finished. Consequently, it is no longer necessary to include the scriptlets calling ldconfig in RPM spec files of individual packages. This improves the performance compared to RHEL 7, where the cache was updated for each package separately. 6.4. Stricter SPEC parser The SPEC parser has now some changes incorporated. Hence, it can identify new issues that were previously ignored. 6.5. Support for files above 4 GB On Red Hat Enterprise Linux 8, RPM can use 64-bit variables and tags, which enables operating on files and packages bigger than 4 GB. 6.5.1. 64-bit RPM tags Several RPM tags exist in both 64-bit versions and 32-bit versions. Note that the 64-bit versions have the LONG string in front of their name. Table 6.4. RPM tags available in both 32-bit and 64-bit versions 32-bit variant tag name 62-bit variant tag name Tag description RPMTAG_SIGSIZE RPMTAG_LONGSIGSIZE Header and compressed payload size. RPMTAG_ARCHIVESIZE RPMTAG_LONGARCHIVESIZE Uncompressed payload size. RPMTAG_FILESIZES RPMTAG_LONGFILESIZES Array of file sizes. RPMTAG_SIZE RPMTAG_LONGSIZE Sum of all file sizes. 6.5.2. Using 64-bit tags on command line The LONG extensions are always enabled on the command line. If you previously used scripts containing the rpm -q --qf command, you can add long to the name of such tags: 6.6. Other features Other new features related to RPM packaging in Red Hat Enterprise Linux 8 are: Simplified signature checking output in non-verbose mode Support for the enforced payload verification Support for the enforcing signature checking mode Additions and deprecations in macros Additional resources See the following references to various topics related to RPMs, RPM packaging, and RPM building. Some of these are advanced and extend the introductory material included in this documentation. Red Hat Software Collections Overview - The Red Hat Software Collections offering provides continuously updated development tools in latest stable versions. Red Hat Software Collections - The Packaging Guide provides an explanation of Software Collections and details how to build and package them. Developers and system administrators with basic understanding of software packaging with RPM can use this Guide to get started with Software Collections. Mock - Mock provides a community-supported package building solution for various architectures and different Fedora or RHEL versions than has the build host. RPM Documentation - The official RPM documentation. Fedora Packaging Guidelines - The official packaging guidelines for Fedora, useful for all RPM-based distributions.

Commands:
Package A: Requires: mysql Package mariadb: Provides: mysql Package community-mysql: Provides: mysql
Suggests: mariadb to Package A.
Requires: (pkgA or pkgB or pkgC)
Requires: (pkgA or (pkgB and pkgC))
Supplements: (foo and (lang-support-cz or lang-support-all))
Requires: (pkgA with capB) or (pkgB without capA)
Supplements: ((driverA and driverA-tools) unless driverB)
Recommends: myPkg-langCZ and (font1-langCZ or font2-langCZ) if langsupportCZ
Requires: (pkgA if pkgB)
Conflicts: (pkgA if pkgB)
Conflicts: (pkgA and pkgB)
Requires: ((pkgA if pkgB) or pkgC or pkg)
Requires: ((pkgA and pkgB) or pkgC or pkg)
%file_trigger_tag [FILE_TRIGGER_OPTIONS] - PATHPREFIX... body_of_script
%filetriggerin - /lib, /lib64, /usr/lib, /usr/lib64 /usr/sbin/ldconfig
%filetriggerin - /lib, /lib64, /usr/lib, /usr/lib64 grep "foo" && /usr/sbin/ldconfig
%transfiletriggerin common -P 2000000 - /lib /usr/lib /lib64 /usr/lib64 /sbin/ldconfig %end %transfiletriggerpostun common -P 2000000 - /lib /usr/lib /lib64 /usr/lib64 /sbin/ldconfig %end
-qp --qf="[%{filenames} %{longfilesizes}\n]"