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:

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
true

%build
true

%install
true

%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