If you are working on or developing software for a RHEL based operating system, building RPMs is a great way to distribute packages within a group or enterprise. Sometimes, the package you want is not in any of the usual RPM repositories, like EPEL for example.
At this point, you can compile the package from source and distribute it to each machine or place it on a shared filesystem. Alternatively, you could use a configuration management tool like Puppet or Ansible to take the tarball and run the build/compile/install commands for you.
In this guide, we will walk through the steps required to setup an environment to build RPMs.
Before continuing with this guide, start with a new virtual machine with the EPEL yum repository configured.
Building RPMs requires several development packages such as the GCC compiler and the autotools suite.
To install the required packages, run the following:
sudo yum groupinstall 'Development Tools' sudo yum install rpmdevtools yum-utils
Create a Dedicated User
Do not build RPMs as the root user! You have been warned. Things can go really wrong if the spec file is not written properly. In fact, the rpmbuild command will build the RPM in its own BUILD_ROOT, therefore root access is simply not needed. It is better to build RPMs as your own user or just create a dedicated user for this process. This way, if the RPM build environment is setup on a shared virtual machine, other users can switch to the dedicated user and use the same environment.
Create a dedicated user:
sudo useradd makerpm
Set Up The rpmbuild Tree
This process is trivial when using the rpmdevtools package. This package contains several scripts that help with building RPM packages.
As the makerpm user, run the rpmdev-setuptree command:
sudo su - makerpm rpmdev-setuptree
The rpmdev-setuptree will create the ~/rpmbuild directory and also create a .rpmmacros file in the home directory. The needed subdirectories are created under the rpmbuild directory:
[makerpm@localhost ~]$ tree rpmbuild/ rpmbuild/ ├── BUILD ├── RPMS ├── SOURCES ├── SPECS └── SRPMS 5 directories, 0 files
The .rpmmacros File
The rpmdev-setuptree command also installs a .rpmmacros file in the user's home directory. This file contains three lines by default:
%_topdir %(echo $HOME)/rpmbuild %_smp_mflags -j3 %__arch_install_post /usr/lib/rpm/check-rpaths /usr/lib/rpm/check-buildroot
The first macro, %_topdir, is set to the /home/makerpm/rpmbuild by default. It refers to the root directory of the RPM build environment.
The second macro, %_smp_mflags, is to set the level or parallelism for the make step in building the package. On a dedicated machine, you can set this to the number of available processors.
Use the nproc command to determine the number of available processors:
[makerpm@localhost ~]$ nproc 4
The third macro, %__arch_install_post, runs various checks at the end of building the RPM package. The default macro has a check to look for rpaths in the buildroot directories. This has to do with hardcoding library paths in the resulting binaries. The Linux dynamic linker, ld, can find the right libraries as long as the libraries are put in the standard locations, such as /lib, /lib64, etc. or an appropriate config file is placed /etc/ld.so.conf.d for libraries in non-standard locations.
For a more thorough explanation, see this Fedora Project link: https://fedoraproject.org/wiki/Packaging:Guidelines#Beware_of_Rpath.
You now have a working RPM build environment with a dedicated user for building RPMs. In the Part 2 of this guide, we will setup a signing key so that you can follow good practice and sign your RPM packages.