The goal of this post is to help myself reproduce this pbuilder setup in the future. If you find it useful too, then that’s great.
Building ARM packages on older ARM devices like the Raspberry Pi 1 is slow, so I want to use a single amd64 machine to build Debian packages for all my target platforms:
- armel/ARMv4+ (e.g. Debian on Raspberry Pi 1),
- armhf/ARMv6+ (Raspbian), and
- armhf/ARMv7+ (e.g. Debian/Ubuntu on Raspberry Pi 2, Odroid C1, etc.).
Preferably, I want to build the packages for the current Debian stable, which at the time of writing is wheezy, so that they’ll work for as many users as possible.
Instead of managing a bunch of virtual machines by hand, we can use pbuilder. pbuilder creates chroots with debootstrap, keeps them updated with changes to the base system, and keeps the chroots clean of dependencies installed when you build packages within them.
There is an introduction to pbuilder and lots of information on various ways of using it in the Ubuntu wiki.
I’m doing the following on an amd64 system running Ubuntu 14.10.
I start out with a
~/.pbuilderrc to help simplify the later commands:
.pbuilderrc file cares about three environment variables:
DIST: For example
ARCH: For example
Based on these three variables, the
.pbuilderrc script selects the proper APT
mirror, distribution components, and keyring to verify the downloaded packages.
If the architecture is
armhf, and we’re not currently on that
architecture, it uses
qemu-debootstrap to bootstrap the chroot and copies a
static qemu emulator for ARM into the chroot.
For more details on the qemu part, see the Ports page in the Ubuntu wiki.
Before running pbuilder, we have to install pbuilder and qemu-debootstrap:
And we also need the keyrings. Ubuntu includes packages with the Ubuntu and Debian keyrings:
While we have to download the Raspbian keyring package and install it by hand:
You should now have all keyrings referenced from the
Then we can bootstrap the five chroots. This takes a bit of time as it downloads all packages needed to bootstrap a fully functional OS. Five times.
This will create tarballs with the pristine chroots:
Now we’re ready to build packages. Basically, you just get the source of a Debian package, change into its directory, and run:
pdebuild command completes successfully, you’ll find the resulting
Debian source and binary packages for armhf in e.g.
/var/cache/pbuilder/raspbian-wheezy-armhf/result. All without using the
rather slow Raspberry Pi 1 I used to build packages with.
Appendix: Depending on packages from an unofficial APT repo
Since I build packages for Mopidy, to be hosted at apt.mopidy.com, they often
depend on other packages hosted there, and not just packages from the official
repos. Thus I need to add an extra APT repository to the chroots. As I already
have five chroots, I don’t want to change each chroot manually with
The solution is to add a hook script to be executed every time the chroot is
being set up, before the Debian packaging begins, which adds apt.mopidy.com as
an APT repo and runs
Create the directory
/var/cache/pbuilder/hook.d and make a file
Remember to make the hook script executable, or else it will have no effect:
And that should be it. The hook script will now be executed before any package
build and all packages from the APT repo will be available to