Building RPMs using Mock
Mock is a major re-write of mach - SethVidal (author of yum) ripped out quite a bit of code from mach to get it working better for the purposes of rebuilding SRPMs (and it now uses yum rather than apt). Mock is used by the Fedora Extras build system as a way to verify SRPMs and to build them in a safe chroot where malicious code can't hurt the build system.
Basically, mock creates a chroot and does a minimal install of your target OS using yum. Then, it enters into the chroot to rebuild your SRPM for you. It will auto-install Buildrequires listed in your spec file.
One of the nice things about using mock is that it allows you to build for different target archs and operating systems without having to jump around to multiple systems. This means that on a x86_64 machine running FC4 it is possible to build both i386 and x86_64 packages for Redhat (Linux and Enterprise Linux), Fedora Core, CentOS, etc.
To use mock, you'll need to install it first - since it's part of Fedora Extras , you can most likely do a 'yum install mock' and you'll be set. You'll then need to add your user account to the 'mock' group since mock can only be used by members of that group. You may need to log in again before your additional group takes effect. Next, you'll want to edit the config files in /etc/mock. There is one file for each target OS/Arch. Pointing these to a local mirrors is a good idea!
See http://fedoraproject.org/projects/mock/releases/configs/ for some additional configuration examples.
Remember that /etc/mock/default.cfg is a symlink to whichever config file you want to be the default.
For older Fedora and Redhat releases that did not use the new metadata (ie. there is a 'headers/' directory in the repository instead of 'repodata/'), you'll need to run createrepo to generate the new metadata for that repository. Note that this can safely co-exist with the old yum-arch information. Here is an example file for Redhat 9 i386 builds. You may want change the URLs to point to local mirror repositories.
import os config_opts['root'] = 'redhat-9-i386' config_opts['target_arch'] = 'i386' config_opts['runuser'] = '/bin/su' config_opts['yum.conf'] = """ [main] cachedir=/var/cache/yum debuglevel=1 logfile=/var/log/yum.log reposdir=/dev/null retries=20 obsoletes=1 gpgcheck=0 assumeyes=1 [core] name=core baseurl=http://download.fedoralegacy.org/redhat/9/os/i386/ [updates-released] name=updates baseurl=http://download.fedoralegacy.org/redhat/9/updates/i386/ [groups] name=groups baseurl=http://fedoraproject.org/buildgroups/rh9/i386/ """
Once you have the config files setup, it's easy to rebuild a SRPM using mock. Simply run 'mock /path/to/srpm'. If you don't specify a target with '-r', it will use the default. After the build, mock will output the build logs and RPMs to /var/lib/mock/[root_name] /results.
Currently mock looks to /var/lib/mock for all of its build roots. If you have a larger partition you would like to store this stuff on, you can do so by using a bind mount. For example, to use the '/local' partition you could use the following line in /etc/fstab:
/local/mock /var/lib/mock ext3 bind 0 0
Notes for Specific Distributions
The chroot environment set up by mock contains only a minimal set of packages as listed in the Buildrequires Exceptions section of the wiki:Self:Packaging/Guidelines, plus whatever packages (and their dependencies) are listed as build requirements for the particular SRPM you're building.
The minimal set of packages is defined by the
buildsys-build package, which is found in the
Different distributions require some different packages in the minimal root due to the way that packages and their dependencies have changed over time:
- For all Fedora Core distributions before Fedora Core 5, and Red Hat Linux 9, an additional package,
elfutils, is needed in the default buildroot. It's needed because
redhat-rpm-configturns on the creation of debuginfo packages, and
elfutilspackage is needed for this. In Fedora Core 5,
elfutilsis a dependency of
rpm-build, so it gets pulled in automatically, but this doesn't happen for earlier distributions. There is disagreement about where the dependency should really be (see Bug #111363 , Bug #132633 , and Bug #155129 ) so in the meantime (and certainly for end-of-lifed distributions), it needs to be a dependency of
- Building for any Red Hat Linux target older than Red Hat Linux 9 requires
findutilsin the buildroot rather than
coreutils(these are needed for the post-build scripts).
- Red Hat Linux 7 does not include the
redhat-rpm-configpackage, so it must not be included in the buildroot.
A request to have the default
buildsys-build package take these requirements into account was made in Bug #196930 .
If you would like to roll your own
buildsys-build package, a useful place to start is the
spec file in mock CVS .
- For all Fedora Core and Red Hat Linux distributions before Fedora Core 3,
runuserisn't available and so the
mockconfiguration file needs:
config_opts['runuser'] = '/bin/su'
- Building packages for a Fedora Core 2 target with SELinux enabled (even in permissive mode) on the host system requires a modified version of
libselinuxto be installed in the chroot in place of the
libselinuxdistributed in Fedora Core 2. This can be done by creating a local repository containing the modified
libselinuxpackage and adding that repository to the
mockconfiguration file for the Fedora Core 2 target. The modification is to have the
is_selinux_enabled()function always return 0 so that programs running in the chroot believe that SELinux is disabled. Without this modification, the
mockbuild process hangs at the point of running the first command in the chroot (i.e. the
mockbuildaccount), where the system tries to prompt the user to select an SELinux context to use. This problem does not affect any other Fedora or Red Hat release, nor does it affect building on hosts with SELinux disabled. Modified
libselinuxpackages can be found here .
- To build for a target of Fedora Core 1 on an i386 host, you need to set in the host's
kernel.vdso = 0
This is due to a
glibc bug (Bug #121351 ). This tweak is not necessary when building on an x86_64 host prior to Fedora 9. From Fedora 9 onwards, set in the host's
abi.vsyscall32 = 0
It's also a good idea to add
exclude=glibc.i386 in the
yum.conf for a Fedora 1 target as the i386 version of
glibc on Fedora 1 doesn't support NTPL threads properly, which causes build failures for packages like
perl-BerkeleyDB that require them. The exclusion results in a
glibc package built for a later processor such as i686 or athlon being installed, which has proper NTPL thread support.
- Building for any Red Hat Linux target requires rebuilding of many of the original packages, which have broken dependencies due to the use of Epoch: tags and the omission of the epoch in exact version dependencies, such as between foo and foo-devel. Whilst these comparisons worked back in 2003, they don't now.