Sunday, February 9, 2020

Building an rpm in the current directory without any build environment

Say you have a proper .spec file, e.g. from a Fedora rpm repo. The repo contains the latest patches for the package but you won't get them via dnf this week b/c of the ~slow testing process. Or you just want to apply a small fix to a package.

How to do this quickly w/o spending hours on a correct "build environment", "infrastructure", w/o re-reading Maximum RPM book & the wearisome packaging guidelines?

Say we want to amend the flite Fedora package. At the time of writing, its .spec file describes not only a prehistoric version of the program but a configuration w/ the most robotic voices possible. Let's at least fix the latter.

Clone https://src.fedoraproject.org/rpms/flite.git and apply the following patch to it:

diff --git a/flite.spec b/flite.spec
index dc6dd28..ccf8251 100644
--- a/flite.spec
+++ b/flite.spec
@@ -3,2 +3,3 @@ Version: 1.3
Release: 35%{?dist}
+Epoch: 1000
Summary: Small, fast speech synthesis engine (text-to-speech)
@@ -52,3 +53,3 @@ cp -p %{SOURCE1} .
autoreconf -vif
-%configure --enable-shared --with-audio=alsa
+%configure --enable-shared --with-audio=alsa --with-vox=cmu_us_kal16
# This package fails parallel make (thus cannot be built using "_smp_flags")

To build an rpm, cd to the repo directory & run:

$ rpmbuild --load ~/lib/macros.spec -bb flite.spec
...
$ find -name \*rpm
./_out/RPMS/x86_64/flite-devel-1.3-35.fc31.x86_64.rpm
./_out/RPMS/x86_64/flite-1.3-35.fc31.x86_64.rpm

That's it. It even automatically fetches a source tarball.

The only missing part is a mysterious ~/lib/macros.spec:

%_topdir                %(pwd)/_out
%_sourcedir %(pwd)
%debug_package %nil
%_disable_source_fetch %nil

That file is your whole "rpm build environment".