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.rpmbundle 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