RPM is the acronym for Red Hat Package Manager: we use it to reference both the software package format and the low-level package manager used by the Red Hat family of distributions. Since version 4.12 of the latter it is possible to declare packages “weak dependencies”, which are installed by default, but not strictly required.
In this tutorial we talk about rpm weak dependencies: we learn what they are used for, and how to skip their installation.
In this tutorial you will learn:
- What is a “weak” dependency, and what weak dependencies are used for
- How to list the weak dependencies of a package
- How to skip the installation of weak dependencies
|Category||Requirements, Conventions or Software Version Used|
|System||Red Hat family of distributions|
|Conventions||# – requires given linux-commands to be executed with root privileges either directly as a root user or by use of
$ – requires given linux-commands to be executed as a regular non-privileged user
Required vs weak dependencies
Since the release of Rpm 4.12, it is possible to declare weak dependencies for packages. What they are used for, and what is the difference between them and “core” dependencies?
Core dependencies of an rpm package are declared in its “SPEC” file at build time, using the “Requires” keyword: their installation is essential for the packaged software to work correctly. Here is an example. In a previous tutorial we talked about borg, an efficient deduplicating backup program. Since the program is written in Python, the “python” interpreter is listed among the required dependencies of the “borgbackup” package, which provides the application. This is easily verifiable by querying the dependencies of the latter with rpm itself:
$ rpm -qR borgbackup
In the example above I assumed the “borgbackup” package to be already installed (the full path of the rpm package should otherwise have been provided as argument to the
-p option). The command returns the following output:
((python3.11dist(msgpack) < 1.0.1 or python3.11dist(msgpack) > 1.0.1) with python3.11dist(msgpack) <= 1.0.5 with python3.11dist(msgpack) >= 0.5.6) /usr/bin/python3 fuse libacl.so.1()(64bit) libacl.so.1(ACL_1.0)(64bit) libc.so.6()(64bit) libc.so.6(GLIBC_2.14)(64bit) libc.so.6(GLIBC_2.2.5)(64bit) libc.so.6(GLIBC_2.3)(64bit) libc.so.6(GLIBC_2.3.4)(64bit) libc.so.6(GLIBC_2.4)(64bit) libcrypto.so.3()(64bit) libcrypto.so.3(OPENSSL_3.0.0)(64bit) liblz4.so.1()(64bit) libxxhash.so.0()(64bit) libzstd.so.1()(64bit) python(abi) = 3.11 python3-llfuse >= 1.3.8 python3.11dist(packaging) rpmlib(CompressedFileNames) <= 3.0.4-1 rpmlib(FileDigests) <= 4.6.0-1 rpmlib(PartialHardlinkSets) <= 4.0.4-1 rpmlib(PayloadFilesHavePrefix) <= 4.0-1 rpmlib(PayloadIsZstd) <= 5.4.18-1 rpmlib(RichDependencies) <= 4.12.0-1 rtld(GNU_HASH)
The ones reported above are not necessarily package names: the “Requires” directive can be used to point both to package names and “capabilities”, which, most of the times, are file paths. Multiple packages can provide the same capability, therefore a “Require” dependency has multiple ways to be satisfied.
When it comes to weak dependencies, we must distinguish between “recommendations” and “suggestions”. The former, which are the focus of this tutorial, are, by default, treated like “Requires” dependencies; unlike them, however, they are not strictly necessary for the packaged software to run. Recommended dependencies are used to specify packages which provides functionalities that most of the time users wants to be available. Hints, or “very weak dependencies”, instead, are ignored by default, and are mainly used to specify extra addons for GUI packages.
Listing the weak dependencies of a package
Here is an example of a “weak” dependency. Podman, as you may know, is a rootless alternative to Docker, developed by Red Hat. On recent versions of Fedora, the “podman” package requires the “containers-common-extra” package, which, in turn, has the “slirp4netns” package declared as a weak dependency. The latter provides the “user mode networking” functionality: this is not strictly required for podman to work in general, but is needed if we want to use podman as a non-root user. In order to list the weak dependencies of a package we can use the
rpm package manager in the following way:
$ rpm -q --recommends <package-name>
The same result can be achieved by using
$ dnf repoquery --recommends <package-name>
Checking the weak dependencies of the “containers-common-extra” package we mentioned above, returns the following output:
crun netavark >= 1.6.0-1 passt qemu-user-static slirp4netns
As you can see, “slirp4nets” is listed among the weak dependencies. Packages to be installed as weak dependencies are also specified in pre-installation reports when using
dnf. Here is the one displayed when attempting to install the “containers-common-extra” package on the latest version of Fedora (38 at the moment of writing):
=============================================================================================================== Package Architecture Version Repository Size =============================================================================================================== Installing: containers-common-extra noarch 4:1-89.fc38 updates 14 k Installing dependencies: containers-common noarch 4:1-89.fc38 updates 94 k criu x86_64 3.17.1-5.fc38 fedora 546 k crun x86_64 1.8.5-1.fc38 updates 209 k libbsd x86_64 0.11.7-4.fc38 fedora 112 k libmd x86_64 1.0.4-3.fc38 fedora 39 k libnet x86_64 1.2-7.fc38 fedora 57 k netavark x86_64 1.6.0-2.fc38 updates 3.0 M qemu-user-static-aarch64 x86_64 2:7.2.1-2.fc38 updates 4.2 M qemu-user-static-alpha x86_64 2:7.2.1-2.fc38 updates 1.4 M qemu-user-static-arm x86_64 2:7.2.1-2.fc38 updates 2.1 M qemu-user-static-cris x86_64 2:7.2.1-2.fc38 updates 1.4 M qemu-user-static-hexagon x86_64 2:7.2.1-2.fc38 updates 1.8 M qemu-user-static-hppa x86_64 2:7.2.1-2.fc38 updates 1.4 M qemu-user-static-loongarch64 x86_64 2:7.2.1-2.fc38 updates 1.4 M qemu-user-static-m68k x86_64 2:7.2.1-2.fc38 updates 1.5 M qemu-user-static-microblaze x86_64 2:7.2.1-2.fc38 updates 1.7 M qemu-user-static-mips x86_64 2:7.2.1-2.fc38 updates 3.8 M qemu-user-static-nios2 x86_64 2:7.2.1-2.fc38 updates 1.4 M qemu-user-static-or1k x86_64 2:7.2.1-2.fc38 updates 1.4 M qemu-user-static-ppc x86_64 2:7.2.1-2.fc38 updates 2.6 M qemu-user-static-riscv x86_64 2:7.2.1-2.fc38 updates 2.1 M qemu-user-static-s390x x86_64 2:7.2.1-2.fc38 updates 1.5 M qemu-user-static-sh4 x86_64 2:7.2.1-2.fc38 updates 1.7 M qemu-user-static-sparc x86_64 2:7.2.1-2.fc38 updates 2.2 M qemu-user-static-x86 x86_64 2:7.2.1-2.fc38 updates 2.1 M qemu-user-static-xtensa x86_64 2:7.2.1-2.fc38 updates 3.8 M Installing weak dependencies: aardvark-dns x86_64 1.6.0-1.fc38 updates 910 k container-selinux noarch 2:2.216.0-1.fc38 updates 55 k criu-libs x86_64 3.17.1-5.fc38 fedora 33 k fuse-overlayfs x86_64 1.12-1.fc38 updates 67 k qemu-user-static x86_64 2:7.2.1-2.fc38 updates 26 k slirp4netns
Skipping the installation of weak dependencies
In certain situations, most likely when building very minimal environments, we may want to avoid installing weak dependencies globally or only for certain packages. In order to skip the installation of weak dependencies for a specific package, we can use the dnf
--setopt option to temporarily set
install_weak_deps to false. For instance, to install the “containers-common-extra” package without its weak dependencies, we would run:
$ sudo dnf --setopt=install_weak_deps=false install containers-common-extra
To change the default dnf behavior, and always avoid the installation of weak dependencies, instead, we need to specify the same option in the dnf configuration file (
/etc/dnf/dnf.conf), under the “main” section:
[main] gpgcheck=True installonly_limit=3 clean_requirements_on_remove=True best=False skip_if_unavailable=True install_weak_deps=false
Skipping weak dependencies in Kickstart files
As we discussed in a previous tutorial, in order to easily perform (and replicate) unattended installations of distributions using the “Anaconda” installer, we can use Kickstart files. In such files, the list of the packages and package groups to be pulled in as part of the installation process, are specified inside the
%packages section, as in the example below:
%packages @core @standard podman %end
In order to avoid installing the weak dependencies of the packages specified in the
%packagessection, in recent versions of Kickstart (the feature has been introduced in Fedora 24, and is available in RHEL >= 8 and its clones), all we have to do is to use either the
--exclude-weakdepsoption in the following way:
%packages --exclude-weakdeps @core @standard podman %end
In this article we talked about rpm weak dependencies. Packages or capabilities defined as weak dependencies of a software are not strictly required for it to work correctly, but provide extra functionalities, which, most of the time, are desired. Weak dependencies are installed by default when using the dnf package manager; in this tutorial we learned how skip their installation in single cases, globally, and in Kickstart files.