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.