第 6 章 Packaging software


In the following sections, learn the basics of the packaging process with the RPM package manager.

6.1. About spec files

A spec file is a file with instructions that the rpmbuild utility uses to build an RPM package. This file provides necessary information to the build system by defining instructions in a series of sections. These sections are defined in the Preamble and the Body part of the spec file:

  • The Preamble section contains a series of metadata items that are used in the Body section.
  • The Body section represents the main part of the instructions.

6.1.1. Preamble items of a spec file

The following are some of the directives that you can use in the Preamble section of the RPM spec file.

Expand
表 6.1. The Preamble section directives
DirectiveDefinition

Name

A base name of the package that must match the spec file name.

Version

An upstream version number of the software.

Release

The number of times the version of the package was released.

Set the initial value to 1%{?dist} and increase it with each new release of the package. Reset to 1 when a new Version of the software is built.

Summary

A brief one-line summary of the package.

License

A license of the software being packaged.

The exact format for how to label the License in your spec file varies depending on which RPM-based Linux distribution guidelines you are following, for example, GPLv3+.

URL

A full URL for more information about the software, for example, an upstream project website for the software being packaged.

Source

A path or URL to the compressed archive of the unpatched upstream source code. This link must point to an accessible and reliable storage of the archive, for example, the upstream page, not the packager’s local storage.

You can apply the Source directive either with or without numbers at the end of the directive name. If there is no number given, the number is assigned to the entry internally. You can also give the numbers explicitly, for example, Source0, Source1, Source2, Source3, and so on.

Patch

A name of the first patch to apply to the source code, if necessary.

You can apply the Patch directive either with or without numbers at the end of the directive name. If there is no number given, the number is assigned to the entry internally. You can also give the numbers explicitly, for example, Patch0, Patch1, Patch2, Patch3, and so on.

You can apply the patches individually by using the %patch0, %patch1, %patch2 macro, and so on. Macros are applied within the %prep directive in the Body section of the RPM spec file. Alternatively, you can use the %autopatch macro that automatically applies all patches in the order they are given in the spec file.

BuildArch

An architecture that the software will be built for.

If the software is not architecture-dependent, for example, if you wrote the software entirely in an interpreted programming language, set the value to BuildArch: noarch. If you do not set this value, the software automatically inherits the architecture of the machine on which it is built, for example, x86_64.

BuildRequires

A comma- or whitespace-separated list of packages required to build the program written in a compiled language. There can be multiple entries of BuildRequires, each on its own line in the SPEC file.

Requires

A comma- or whitespace-separated list of packages required by the software to run once installed. There can be multiple entries of Requires, each on its own line in the spec file.

ExcludeArch

If a piece of software cannot operate on a specific processor architecture, you can exclude this architecture in the ExcludeArch directive.

Conflicts

A comma- or whitespace-separated list of packages that must not be installed on the system in order for your software to function properly when installed. There can be multiple entries of Conflicts, each on its own line in the spec file.

Obsoletes

The Obsoletes directive changes the way updates work depending on the following factors:

  • If you use the rpm command directly on a command line, it removes all packages that match obsoletes of packages being installed, or the update is performed by an update or dependency solver.
  • If you use the updates or dependency resolver (DNF), packages containing matching Obsoletes: are added as updates and replace the matching packages.

Provides

If you add the Provides directive to the package, this package can be referred to by dependencies other than its name.

6.1.2. Body items of a spec file

The following are the items used in the Body section of the RPM spec file.

Expand
表 6.2. The Body section items
DirectiveDefinition

%description

A full description of the software packaged in the RPM. This description can span multiple lines and can be broken into paragraphs.

%prep

A command or series of commands to prepare the software for building, for example, for unpacking the archive in the Source directive. The %prep directive can contain a shell script.

%conf

A command or series of commands to configure the software for building.

%build

A command or series of commands for building the software into machine code (for compiled languages) or bytecode (for some interpreted languages).

%install

A command or series of commands that the rpmbuild utility will use to install the software into the BUILDROOT directory once the software has been built. These commands copy the desired build artifacts from the %_builddir directory, where the build happens, to the %buildroot directory that contains the directory structure with the files to be packaged. This includes copying files from ~/rpmbuild/BUILD to ~/rpmbuild/BUILDROOT and creating the necessary directories in ~/rpmbuild/BUILDROOT.

The %buildroot directory is an empty base directory, which resembles the end user’s system directory layout. In %buildroot, you can create any directories that will contain the installed files. To create such directories, you can use RPM macros without having to hardcode the paths.

Note that %install is only run when you create a package, not when you install it. For more information, see Working with spec files.

%check

A command or series of commands for testing the software, for example, unit tests.

%files

A list of files, provided by the RPM package, to be installed in the user’s system and their full path location on the system.

During the build, if there are files in the %buildroot directory that are not listed in %files, you will receive a warning about possible unpackaged files.

Within the %files section, you can indicate the role of various files by using built-in macros. This is useful for querying the package file manifest metadata by using the rpm command. For example, to indicate that the LICENSE file is a software license file, use the %license macro.

%changelog

A record of changes that happened to the package between different Version or Release builds. These changes include a list of date-stamped entries for each Version-Release of the package. These entries log packaging changes, not software changes, for example, adding a patch or changing the build procedure in the %build section.

6.1.3. Advanced spec file items

A spec file can contain advanced items, such as Scriptlets, File triggers and Triggers. These directives influence not only the spec file, but also the target operating system on which the resulting RPM is installed by updating the system with information from the RPM. Scriptlets, File Triggers and Triggers take effect at different points during the installation process on the target system, not the build process:

  • Scriptlets are unconditionally executed before or after the package is installed or deleted.
  • Triggers are conditionally executed when their specified trigger condition matches other packages on the installed system or in a transaction.
  • File triggers are conditionally executed when their specified path prefix matches other files on the installed system or in a transaction.

6.1.3.1. Scriptlets directives

Scriptlets are arbitrary programs that execute at pre-determined slots related to a package’s lifetime, for example, before or after the package is installed or deleted. By default, scriptlets are short shell scripts declared by the various %pre or %post directives in a spec file. Use scriptlets only for tasks that cannot be done at build time or in a startup script.

Common scriptlet directives are similar to the spec file section headers, such as %build or %install. They are defined by multi-line segments of code, which are often written as a standard POSIX shell script. However, they can also be written in other programming languages that RPM accepts for the target machine’s distribution.

6.1.3.2. Scriptlets directives execution order

Scriptlets directives have different order of execution:

  • %pre and %post are executed before and after you installed a package.
  • %preun and %postun are executed before and after you uninstalled the package.
  • %pretrans and %posttrans are executed at start and end of the transaction that installs the package, respectively.

During the package upgrade, the scriptlets are executed in the following order:

Expand
表 6.3. Scriptlets directives
DirectiveDescription

%pretrans

The %pretrans scriptlet is executed before installing or removing a package.

%pre

The %pre scriptlet is executed before installing a package on the target system.

%post

The %post scriptlet is executed after a package was installed on the target system.

%preun

The %preun scriptlet is executed before uninstalling a package from the target system.

%postun

The %postun scriptlet is executed after a package was uninstalled from the target system.

%posttrans

The %posttrans scriptlet is executed at the end of a transaction.

6.1.3.3. Turning off scriptlets execution

You can turn off the execution of any scriptlet by using the --no option with the scriptlet name.

You can also use the --noscripts option, which is equivalent to turning off the execution of all the following scriptlets:

  • --nopre
  • --nopost
  • --nopreun
  • --nopostun
  • --nopretrans
  • --noposttrans
  • --nopreuntrans
  • --nopostuntrans

For more information, see the rpm man page on your system.

Procedure

  • Turn off the scriptlet execution:

    # rpm --no<scriptlet_name>

    For example, to turn off the execution of the %pretrans scriptlet, enter:

    # rpm --nopretrans

6.1.3.4. Example macros for scriptlets

The following are example macros that you can use for scriptlets in a spec file. These macros are real-world macros provided by the systemd-rpm-macros package. You can use these macros for packaging systemd-related things. You can also apply similar principles to other packages.

Packages that contain systemd unit files must use scriptlets to properly handle systemd services. systemd packages provide a set of macros to handle systemd scriptlet operations. For example:

%post
%systemd_post httpd.service

%preun
%systemd_preun httpd.service

These macros expand to the following in a package:

$ rpm --eval "%systemd_preun httpd.service"

if [ $1 -eq 0 ] && [ -x "/usr/lib/systemd/systemd-update-helper" ]; then
    # Package removal, not upgrade
    /usr/lib/systemd/systemd-update-helper remove-system-units httpd.service || :
fi
注意

The way macros behave is subject to change. For example, macros' behavior can change with a package’s development.

6.1.4. The Epoch directive

If setting the Version spec file directive is not enough for comparing package versions, you can use an Epoch directive. For example, you can use Epoch to resolve upgrade path issues that, for example, occurred because of the upstream change in a version numbering scheme in an incompatible manner.

Epoch is a numeric field. If you assign a value to Epoch, it adds a qualifier that RPM uses when comparing package versions. Not having the Epoch directive listed in a spec file means Epoch is not set. This is contrary to the common belief that not setting Epoch results in an Epoch of 0. However, for processing purposes, if you do not set Epoch, RPM treats it the same as if the Epoch was set to 0, and vice versa.

重要

Using Epoch in a spec file is usually omitted because, in the majority of cases, introducing an Epoch value distorts the expected RPM behavior when comparing versions of packages. Therefore, consider using Epoch as a last resort.

For example, you installed the foobar package with Epoch: 1 and Version: 1.0. Another packager packages foobar with Version: 2.0, but without the Epoch directive. As a result, the new version is never considered an update because the Epoch version is preferred over the traditional Name-Version-Release marker that signifies versioning for RPM packages.

6.1.5. Package versioning essentials

The essential part of the package description is the information defined in the Name, Version, and Release (NVR) spec file directives. RPM uses this information to compare package versions and track package dependencies.

When working with RPMs, you can also see mentions of EVR (epoch-version-release), NEVR (name-epoch-version-release), and NEVRA (name-epoch-version-release-architecture). EVR is the full version information of the package that RPM always uses for comparison. RPM compares one component at a time, starting from the first component. RPM stops the comparison when it finds a difference in components. For example, if Epoch differs, RPM does not compare the rest of the EVR components.

You can display the NVR information for a specific package by querying the RPM database, for example:

# rpm -q bash
bash-4.4.19-7.el8.x86_64

Here, bash is the package name, 4.4.19 is the version, and 7.el8 is the release. The x86_64 marker is the package architecture. Unlike NVR, the architecture marker is not under direct control of the RPM packager, but is defined by the rpmbuild build environment. The exception to this is the architecture-independent noarch package.

注意

The rpm -q command displays the package information in the NEVRA format by default.

Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2026 Red Hat
返回顶部