What are source RPMs?
A package is a collection of binaries, scripts, and associated data that is installed by your package manager.
Packages are typically generated from source code and a set of a metadata written by the package maintainer. Occasionally, the source may by patched by the package maintainer at build time.
A source RPM captures the source code and patches as they were at RPM build time.
On RPM-based systems (CentOS, Red Hat Enterprise Linux, Oracle Linux, and many more) source RPMs are RPM files that contain a tarball of source code, patches, auxiliary files that are used during the build process, and a .spec file for generating the RPM.
Why are source RPMs useful?
Source RPMs are extremely useful for:
- Regenerating binary packages
- Debugging issues with applications and libraries
- Modifying existing applications to add additional logging
- Confirming whether or not a particular security fix has been applied to the source
We strongly recommend that people and organizations running applications in production on RPM-based systems become familiar with RPM source packages so that when a bug appears, system operators and developers will have the tools to quickly and easily obtain the source and debug the issue.
Working with source RPMs
If you intend to rebuild or modify a source RPM, it is strongly recommended that you install the
rpm-build packages which contains many useful tools for working with
yum and RPMs:
$ sudo yum install yum-utils rpm-build
Getting Source RPMs
Getting the source for an RPM package is not as straight-forward as obtaining source packages for other systems.
Start by using
yumdownloader which is part of the
yum-utils package. This program will download the source RPM for the named package.
For example, to get the source RPM for
$ yumdownloader --source redis
This will download the
redis source RPM file in the current working directory.
Next, you must install the source RPM. When a source RPM is installed, the source tarballs, patches, and auxilliary files will be installed under a top level directory. This directory is called
topdir. You can get the current value of
topdir by checking the output of
rpm --showrc | grep topdir. On many systems, the default value is
rpmbuild in the current user’s home directory.
You can set your own
topdir by creating a file named
.rpmmacros in your home directory like this:
%_topdir %(echo $HOME)/my-rpm-build-dir
.rpmmacros file will cause source RPMs installed by you to be written to
my-rpm-build-dir in your home directory.
You can now install the source RPM:
$ rpm -ivh ./redis-2.8.19-1.el7.src.rpm
This will write the source tarballs, patches, and other files to the
SOURCES directory under your specified
topdir. The RPM spec file will be written to
Install Source RPM build dependencies
You should now install the source RPM’s build dependencies by using
$ sudo yum-builddep redis
Preparing the source
Now, that you’ve installed the source RPM and build dependencies, you can prepare the source so that all patches are applied. This brings the source into the state it was in when the RPM was built.
Begin by switching to the
SPECS directory under your
$ cd rpmbuild/SPECS
Next, prepare the source using the
rpmbuild program, passing the
-bp flag, and specifying the spec filename:
$ rpmbuild -bp redis.spec
Now, you can examine the source. It is found in the
BUILD directory under
$ ls ~/rpmbuild/BUILD redis-2.8.19
Now, you can look through the source code for Redis precisely as it was when Redis was compiled and put into the package that you have installed on your system.
Modifying the source and applying patches
Patches are applied to source code during the RPM build process by listing patches in the RPM spec file, and then applied during the build process.
For example, in
redis.spec, a patch is specified like this:
The actual application happens before the
Updating the RPM package version number
Updating the RPM package version number is done by modifying the
Release field found in the RPM spec file.
Version field is set to the version of the source itself whereas the
Release field is incremented for each RPM packaging related change.
Rebuilding the package
Now, you are ready to rebuild the RPM package!
You can do this by running the following command in the
$ rpmbuild -ba redis.spec
This will build and write a source RPM and a binary RPM in the
RPMS directories, respectively.
Upload Source RPMs to packagecloud.io
You can now upload your source RPMs to packagecloud.
You simply push the source RPM just as you would any other RPM with the
For example, to upload a source RPM to CentOS 7:
$ package_cloud push user/repo/el/7 redis-2.8.19-1.el7.src.rpm Looking for repository at user/repo... success! Pushing redis-2.8.19-1.el7.src.rpm... success!
The packagecloud command line client uses the package create API to upload the source RPM file.
The RPM package toolchain enables users to quickly and easily recreate the source tree for a package as it was at build time. This is incredibly useful for debugging strange application behavior and for adding additional logging output to applications that aren’t telling you what you need to know when they run.
Becoming familiar with the workflow of obtaining source code via the package manager is essential for debugging and administering infrastructure of any size.