Notes: Rebuiling RPM packages with mock
Wed 22 May 2019 #technical #rpm #mock #centos #notesDISCLAIMER: this is not meant to be coherent post. Sorry. Just notes for future reference.
Given a source RPM package in order to rebuild it I use following tools. For detailed description about what and why I suggest looking at the RPM Packaging Guide first (really nice resource for first-time packagers!).
Installing needed tools on Centos 7 (and other RHEL derivatives, btw RHEL8 shouldn't change this) would look like this:
sudo yum install -y epel-release
sudo yum install -y rpm-build rpmdevtools mock yum-utils
Now for standard rebuiling we need to setup the correct directory structure:
$ rpmdev-setuptreeo
$ tree -L 1 ~/rpmbuild
/home/vagrant/rpmbuild/
|-- BUILD
|-- RPMS
|-- SOURCES
|-- SPECS
`-- SRPMS
5 directories, 0 files
Now when we have a source package we need to unpack it in correct
subdirectiories, if the package is called llvm3.9-3.9.1-7.el7.src.rpm
then
command looks like this:
rpm --install llvm3.9-3.9.1-7.el7.src.rpm
This will put all files in correct places for you. Note: no need for superuser privilages (unless you're building as root, but that is discouraged).
Next step is to take care of the dependencies for the package we are building:
sudo yum-builddep ~/rpmbuild/SPECS/llvm3.9.spec
Now for a rebuild:
rpmbuild -ba ~/rpmbuild/SPECS/llvm3.9.spec
If it doesn't work try installing @buildsys-build
. This will install all
needed compilers and standard (in terms of C/C++) build tools.
Building with mock
Now, we want to be able to build the package without worrying that we have not
specified some build dependency in the specfile. mock
comes to the rescue!
In order to build something with mock
we need to have the SRPM. With the
above rpmbuild
command we get the file as well, but if you want to just
create the SRPM from scratch run:
rpmbuild -bs ~/rpmbuild/SPECS/llvm3.9.spec
The .src.rpm
will be in the ~/rpmbuild/SRPMS/
directory.
For building with mock the user that will be running the command needs to be in
the mock
group. To add current user we simply can:
sudo usermod -a -G mock $USER
Now, we need a session where the user is in fact recognized as part of the group. Supposedly, this is the solution in some environments (I couldn't make it work with graphical session)
newgrp -
Ok. Here we can start actually building. mock
needs to know what evironment
it is supposed to 'emulate' or rather - recreate. Under /etc/mock/
you can
find a plethora of different configurations (mostly, Fedora and EPEL for
different versions). You can work out the syntax from different sources.
Building now is as simple as running:
mock -r $CONFIG --rebuild package.src.rpm
where you specify the CONFIG
for the package to be built with.
Setting builder hostname
Supposedly, setting a macro we can change the hostname of the building machine
# here CONFIG points to something in /etc/mock e.g. epel-7-x86_64
CONFIG=epel-7-x86_64
mock -r $CONFIG -D "_buildhost NAME" package-1.0-1.el7.x86_64.src.rpm
More useful info in site-defaults.cfg from the mock repo.
Other way is to have a custom mock.cfg (note, Python-like syntax):
config_opts['hostname'] = 'my.own.hostname'
There are some packages that will misbehave though. See mysql-community. But I guess that's the exception from the rule.
Other useful resources
- Marcin Juszkiewicz, Workflow for building sets of RPM packages
- Marcin Juszkiewicz, How to speed up mock
- PackageCloud, Building with Mock
- Giovanni Torres, How to Setup an RPM Build Environment on CentOS 6
- Giovanni Torres, How to Setup an RPM Signing Key
- Giovanni Torres, How to Build RPMs - Collectd Example
- Giovanni Torres, Signing RPMs