RPM packager's cheat sheet
Published on
These are some random notes on creating RPM packages that I wrote some time ago for my own use.
I don’t have the time or motivation to organize them in a proper article, but I thought I’d publish them anyway in case they are useful to someone.
The RPM build tree
On Fedora, the default rpm build tree is ~/rpmbuild
.
ls ~/rpmbuild
BUILD/
BUILDROOT/
RPMS/
SOURCES/
SPECS/
SRPMS/
You can create this directory structure with
rpmdev-setuptree
from the rpmdevtools
package.
The purpose of each directory is:
SPECS
: spec files live here. They contain package metainformation and build instructions. This is what you’ll be writing when creating packages.SOURCES
: download the source tarballs into this directory.SRPMS
:.src.rpm
bundle together a spec file and the sources for that spec. You can create one withrpmbuild -bs
, or download withdnf download --source
, and then build a binary package from it withrpmbuild -rb
.BUILD
: sources are unpacked into this directory and get compiled here.BUILDROOT
: during the install phase, files are copied here.RPMS
: the final rpms are created here.
To change the location of the build tree, put this into
~/.rpmmacros
:
%_topdir %{getenv:HOME}/myrpmbuild
SRPMs
To customize a package that already exists in Fedora (for instance, to update to a newer upstream version), it is convenient to download and install an srpm (also known as src.rpm).
First, download an srpm from dl.fedoraproject.org
(substitute your release number) to ~/rpmbuild/SRPMS
.
Alternatively, use the program yumdownloader
from the
dnf-utils
package:
yumdownloader --destdir ~/rpmbuild/SRPMS --source packagename
Next, install it into your build tree:
rpm -i ~/rpmbuild/SRPMS/packagename.src.rpm
Now the spec file should appear under ~/rpmbuild/SPECS
and sources under ~/rpmbuild/SOURCES
.
RPM macros
Evaluate an RPM macro expression:
rpm -E '%_topdir'
Show all macro definitions:
rpm --showrc
It will also show where the definitions are located: look for
something like
Macro path: /usr/lib/rpm/macros:/usr/lib/rpm/macros.d/macros.*:/usr/lib/rpm/platform/%{_target}/macros:/usr/lib/rpm/fileattrs/*.attr:/usr/lib/rpm/redhat/macros:/etc/rpm/macros.*:/etc/rpm/macros:/etc/rpm/%{_target}/macros:~/.rpmmacros
.
Unfortunately, it doesn’t seem to show where each particular macro comes from.
Defining your own
It’s often useful to define variables in the SPEC file.
This can be done with either %define
or
%global
, and %global
is preferred:
%define commit a0a746442daf8dfca01859f1efcc8663b47b3705
%global commit a0a746442daf8dfca01859f1efcc8663b47b3705
Minimal RPM spec file
I usually start with the minimal spec file:
Name: minimal
Version: 1
Release: 1%{?dist}
Summary: Minimal package
License: MIT
%description
...
%prep
%build
%install
%files
/*
RPM has many defaults and convenient macros suited for traditional
./configure && make && make install
tarballs, but nowadays those are actually rare.
Sources
If you have any source files, they should be declared (usually above
%description
) like this:
URL: ftp://ftp.ncbi.nlm.nih.gov/entrez/entrezdirect/edirect.zip
Source0: edirect.zip
You can then download the sources automatically using
spectool
:
spectool -C ~/rpmbuild/SOURCES -g package.spec
Sometimes I don’t declare any sources and instead use a tool (such as
pypi
or gem
) to download and install the
software. This is not reproducible, and therefore unacceptable when
creating public packages, but is usually fine for personal use.
github sources
Here’s an example of using a specific commit from a github repo.
See also the pages on SourceURL for git and versioning snapshots.
%global commit a0a746442daf8dfca01859f1efcc8663b47b3705
%global shortcommit %(c=%{commit}; echo ${c:0:7})
Release: 1.%{shortcommit}
Source0: https://github.com/lwindolf/%{name}/archive/%{commit}/%{name}-%{commit}.tar.gz
%prep
%setup -n %{name}-%{commit}
Build stages
%prep
At this stage, you unpack the source tarballs and apply patches. If
you have any sources to unpack, try to find a %setup
invocation that does the trick. The flags to %setup
are
described elsewhere.
Auto-provides
http://stackoverflow.com/a/39819960/110081
Disable debuginfo
Put this in the spec file:
%global debug_package %{nil}
Extract dependencies from a spec file and install them
dnf builddep package.spec