The preamble section is the "default" section of an RPM spec file. All spec files begin with a preamble
section that stretches from the top until a new section (e.g. %description) is reached.
In Fedora, a preamble is also referred to as a "tag" or a "field".1
Here is a non-exclusive (but nearly exclusive) list of preambles available:
## these fields MUST be present in a spec fileName: pkgnameVersion: 1.2.3Release: 1%?distSummary: Package summary (usually do not add period at the end)# As opposed to the guidelines given by RPM, we (and also Fedora!) strongly# recommend using SPDX identifiers.License: MITURL: https://terra.fyralabs.com/## terra also enforces the following preamble:Packager: username <email@example.com>## these fields are optional and have default valuesEpoch: 0# automatic `Requires:` and `Provides:` generationAutoReqProv: 1# automatic `Requires:` generationAutoReq: 1# automatic `Provides:` generationAutoProv: 1## these fields are optionalSourceLicense:BugURL:ModularityLabel:DistTag:VCS:Distribution:Copyright:Vendor:ExcludeArch:ExclusiveArch:ExcludeOS:ExclusiveOS:BuildArch:BuildArchitectures:BuildRequires:Group:Provides:Obsoletes:Conflicts:Suggests:Recommends:Enhances:Supplements:OrderWithRequires:BuildConflicts:Prefix:Prefixes:Docdir:RemovePathPostFixes:BuildSystem:BuildOption:
If you want to add comments, use %{dnl:…} or start a new line.
Adding # … at the end of a line does not work.
If you are a usual package maintainer, you would instantly notice one very important preamble is
missing: Requires:. Requires: is quite special because it can be further divided into:
Requires: or BuildRequires: must be followed by a space-separated
(comma-separated is accepted but not recommended) list of "query". A "query" (term used here specifically!)
is in the format of x = y (other comparators including >= are accepted) or simply x. RPM will resolve
a "query" by finding a best package that provides the requirement of the query. For example, given the package
gtk4-devel with the following provides:
Step Executing(%generate_buildrequires). Optional. Since rpm >= 4.15.
The stdout is intercepted during this step. The output should be a newline (\n)-separated list of
RPM build dependencies that should be installed.
Once this stage finishes, rpmbuild will attempt to install the list of dependencies. This implies
that you may generate a dynamic dependency list that will be available by the time %build
executes, usually by calling the package manager (e.g. dnf) with Internet access.
This optional script can be used to determine BuildRequires dynamically. If present it is executed after %prep and can though access the unpacked and patched sources. The script must print the found build dependencies to stdout in the same syntax as used after BuildRequires: one dependency per line.
rpmbuild will then check if the dependencies are met before continuing the build. If some dependencies are missing a package with the .buildreqs.nosrc.rpm postfix is created, that - as the name suggests - contains the found build requires but no sources. It can be used to install the build requires and restart the build.
On success the found build dependencies are also added to the source package. As always they depend on the exact circumstance of the build and may be different when bulding based on other packages or even another architecture.
Step Executing(%conf). Optional. Since rpm >= 4.18.
In %conf, the unpacked sources are configured for building.
Different build- and language ecosystems come with their own helper macros, but rpm has helpers for autotools based builds such as itself which typically look like this:
%conf%configure
When in doubt, you can always put %configure and other commands at the start of
%build instead.
In %build, the unpacked (and configured) sources are compiled to binaries.
Different build- and language ecosystems come with their own helper macros, but rpm has helpers for autotools based builds such as itself which typically look like this:
In %install, the software installation layout is prepared by creating the necessary directory structure into an initially empty “build root” directory and copying the just-built software in there to appropriate places. For many simple packages this is just:
%install%make_install
%install [is] required for creating packages that contain any files.
In this step, files should be installed to the %{buildroot} folder, e.g.:
Packages should place all their temporaries inside their designated %builddir, which rpm will automatically clean up. Needing a package specific %clean section generally suggests flaws in the spec.
Not a step. Required (practically). %files [-f file] [[-n] subpkg].
This specify all files that the package (or the subpackage) contains.
-f can be used in combination with %find_lang. Or rather, it just needs to be a
file with a list of line-separated paths that should be included into the final RPM package.
RPM generates debug packages (%{name}-debuginfo and %{name}-debugsource) automatically. When you did not
compile your software with debug symbols, you might see the following error:
Files can be specified with optionally an attribute3 (aka. a file directive4).
The following is an exhaustive list of file attributes available:
%artifact …# ╰─ mado: personally never seen this used%config(…) …# ╰─ exhaustive list:# - config(missingok)# - config(noreplace)%dir …# ╰─ specify a directory the package owns%doc …# ╰─ store the file into %{_docdir}%docdir# ╰─ mado: personally never seen this used%ghost …# ╰─ mark a file as owned by the package, but don't actually install the file%license …# ╰─ store the file into %{_defaultlicensedir}%verify(…) …# ╰─ exhaustive list:# - verify(user owner) ← user and owner are same# - verify(group)# - verify(mode)# - verify(filedigest md5) ← same# - verify(size)# - verify(maj)# - verify(min)# - verify(link symlink) ← same# - verify(rdev)# - verify(mtime)# - verify(not ...)# special:%attr(…) …%defattr(…)