From Fedora Project Wiki

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 [groups] repository.

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-config turns on the creation of debuginfo packages, and eu-strip from the elfutils package is needed for this. In Fedora Core 5, elfutils is 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 buildsys-build.
  • Building for any Red Hat Linux target older than Red Hat Linux 9 requires file, fileutils, and findutils in the buildroot rather than coreutils (these are needed for the post-build scripts).
  • Red Hat Linux 7 does not include the redhat-rpm-config package, 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, runuser isn't available and so the mock configuration 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 libselinux to be installed in the chroot in place of the libselinux distributed in Fedora Core 2. This can be done by creating a local repository containing the modified libselinux package and adding that repository to the mock configuration 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 mock build process hangs at the point of running the first command in the chroot (i.e. the useradd for the mockbuild account), 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 libselinux packages 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 /etc/sysctl.conf:
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 /etc/sysctl.conf:

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.