How to modify an rpm package using rpmrebuild

Introduction

Rpm is one of the most advanced Gnu/Linux package manager. Created by Red Hat, it is used in many distributions, as for example Fedora and derivatives like Rhel and CentOS.

Packages to be installed with this package manager have the .rpm extension and are basically archives which contain the files provided by a library or an application plus information needed for the package to be installed and run correctly, such as its dependencies. In this tutorial we will learn how to use rpmrebuild, a very powerful tool which let us modify an existing rpm package without having to rebuild it from source code.

Fixing a missing dependency in the Atom package example

For the sake of this tutorial we will fix a real bug, affecting the official Atom editor rpm package. Atom depends on GConf2, however this package is omitted in the list of dependencies included the spec file.

You may not notice this if you install Atom on a default installation of Fedora Workstation, since the GConf2 package is already installed on the system (probably some other package requires it as a dependency).

However, when installing Atom in a minimal environment the problem will arise: the package will be installed without problems, but when trying to launch the editor, the following error will be displayed:

/usr/share/atom/atom: error while loading shared libraries: libgconf-2.so.4: cannot open shared object file: No such file or directory

The libgconf-2.so.4 shared object is provided by the GConf2 package, as we can easily verify issuing the following linux command:

$ dnf whatprovides libgconf-2.so.4
GConf2-3.2.6-20.fc28.i686 : A process-transparent configuration system
Repo        : fedora
Matched from:
Provide    : libgconf-2.so.4

Let’s fix this bug by adding the missing dependency in the spec file.



Step 1 – Rpmrebuild installation

The first thing we need to do, is to install the rpmrebuild package, which is available in the default Fedora repositories. The command may vary depending if the user is in the wheel group, and therefore can use the sudo command, or if we want to run the command switching to the root user, using su. I will assume the former case here:

$ sudo dnf install rpmrebuild

Let dnf do its job, and soon the package will be installed on our system. At this point, we need to retrieve the Atom package from the official project website. We will use it as a base to build our custom rpm.

Step 2 – Spec file modification

The spec file of a rpm package contains vital information about the package itself, such as its dependencies and the files it provides: it is this file we need to modify to fix this little bug. Assuming we are in the directory where we downloaded the Atom package, we can issue the following linux command:

$ rpmrebuild -enp atom.x86_64.rpm

We invoked the rpmrebuild command providing three options: -e, -n and -p. Let’s briefly see what they are for. The first option, -e is the short version of --edit-specfile and it’s needed to tell the program that we want to edit the specfile of the package; the second one, -n, short version of --notest-install modifies the behavior of the program so that the generated rpm will not be automatically installed at end of the building process.

Finally, by using the -p or --package option, we specify that we want to use an actual .rpm package file as the base of our rebuild, instead of using an already installed rpm.

Once we run the command above, the spec file will be opened into an instance of our default text editor. In our case, what we want to do, is to add a Requires clause, in order to include the missing dependency:

Requires:      lsb-core-noarch
Requires:      GConf2 # Here is our extra dependency
Requires:      libXss.so.1()(64bit)
Requires:      libsecret-1.so.0()(64bit)

Additionally, we can modify the package version, in order to distinguish our modified version from the official one. It is very simple: all we need to do is to modify the line:



Release:       0.1

Into something like:

Release:       0.1_custom

Once we are done, we save and close the file: a prompt will be displayed on our terminal, asking if we want to proceed and build the modified package:

Do you want to continue ? (y/N)

If we give an affirmative answer and press enter, the building will start (it could take a while to finish). It is important to notice that the specified rpm will not be modified in place, but a new one, based on it will be generated. At the end of the process, the new rpm will be located in the $HOME/rpmbuild/RPMS/x86_64/ directory:

$ ls $HOME/rpmbuild/RPMS/x86_64/
atom-1.27.0-0.1_custom.x86_64.rpm

To verify that the dependency has been correctly added, we can use rpm and query the new package dependencies:

$ rpm -qRp $HOME/rpmbuild/RPMS/x86_64/atom-1.27.0-0.1_custom.x86_64.rpm
GConf2
libXss.so.1()(64bit)
libsecret-1.so.0()(64bit)
lsb-core-noarch
rpmlib(CompressedFileNames) <= 3.0.4-1
rpmlib(FileDigests) <= 4.6.0-1
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(PayloadIsXz) <= 5.2-1

GConf2 is now included in the list of the package dependencies. This becomes evident when we try to install the package: as always, a summary of the operations to be performed will be displayed when installing the package with dnf:



[...]
================================================================================
 Package                    Arch   Version                   Repository    Size
================================================================================
Installing:
 atom                       x86_64 1.27.0-0.1_custom         @commandline  99 M
Installing dependencies:
 GConf2                     x86_64 3.2.6-20.fc28             fedora       1.0 M
 at                         x86_64 3.1.20-10.fc28            fedora        80 k
 cronie                     x86_64 1.5.1-9.fc28              fedora       105 k
 cronie-anacron             x86_64 1.5.1-9.fc28              fedora        40 k
 crontabs                   noarch 1.11-16.20150630git.fc28  fedora        24 k
 ed                         x86_64 1.14.2-2.fc28             fedora        80 k
 esmtp                      x86_64 1.2-10.fc28               fedora        57 k
 libXScrnSaver              x86_64 1.2.2-14.fc28             fedora        29 k
 libesmtp                   x86_64 1.0.6-14.fc28             fedora        67 k
 liblockfile                x86_64 1.14-1.fc28               fedora        30 k
 m4                         x86_64 1.4.18-6.fc28             fedora       221 k
 mailx                      x86_64 12.5-28.fc28              updates      256 k
 ncurses-compat-libs        x86_64 6.1-4.20180224.fc28       fedora       331 k
 redhat-lsb-core            x86_64 4.1-44.fc28               fedora        44 k
 redhat-lsb-submod-security x86_64 4.1-44.fc28               fedora        21 k
 spax                       x86_64 1.5.3-12.fc28             fedora       216 k
 time                       x86_64 1.9-1.fc28                fedora        53 k
 util-linux-user            x86_64 2.32-2.fc28               fedora        94 k

Transaction Summary
================================================================================
Install  19 Packages

[...]

The package will now run correctly, as all its runtime dependencies are correctly satisfied.

Final thoughts

In this tutorial we saw how to modify a spec file of a package without having to rebuild it from source code using the rpmrebuild tool. We fixed a little bug, which consists in a missing dependency in the Atom official rpm package.

We downloaded and used the official Atom package as the base of our rebuild, however with the same tool it’s possible to work and modify files which are part of an already installed rpm, in order to generate a new build of it which will include the modifications. Rpmrebuild is a very useful and powerful tool; the suggestion, as always, it’s to dive into its manpage to master it unlock its full potential.



Comments and Discussions
Linux Forum