Why use sbuild over pbuilder?

sbuild and pbuilder have developed over the years to have nearly identical functionality, and as features are added to either, they tend to be quickly adopted by the other.

As Debian packaging is a policy-driven format, it is a significant aid in determining whether a given build issue is a bug in the implementation of the builder or a problem with the package being built to have multiple implementations of a build system. In order to maintain this, the leading build systems must all have strong partisans supporting them, in a spirit of collaborative competition towards ensuring that we have the most correct available implementations of policy.

The internal mechanics of sbuild and pbuilder differ considerably, so precisely which packages are pulled to satisfy build-dependencies or how they are pulled, the precise mechanism by which the various targets in debian/rules are called, etc. may differ, causing some slight differences in behaviour in very specific cases for certain packages. Most of the time this represents a bug in one or the other implementation, and sometimes reflects a lack of clarity in packaging policy: in any case, behaviour changes ought be resolved.

Official buildds in both Debian and Ubuntu use sbuild (although often not the sbuild available from the archives), which is considered an advantage by some developers, as they have greater confidence that their configuration matches that to which their package will be exposed when built, although if everyone does this, we lose the ability to distinguish bugs in policy from bugs in sbuild.

Historically, my understanding is that pbuilder development initially focused on the needs of the developer as end-user and sbuild development initially focused on the needs of buildd and archive adminstrators. Recently, these focuses have switched, as people have built archive management systems based on pbuilder, and more helpful developer tools using sbuild.

Both tools (or their commonly available close derivatives) support storing chroots as tarballs, unpacked on the system, in separate volumes (with available hooks for special mounting: e.g. LVM snapshots), using overlay filesystems, using copy-on-write semantics, etc. Both tools offer trivial command-line tools to streamline the common case (test-build a package) and rich hook semantics to support complex cases (large archives). Both provide a means to create a test environment in a chroot. In short, both tools provide just about anything you might think you wanted in a package building tool (and both have active upstreams happy to accept bugs and patches).

In summary: if you're happy with pbuilder, keep using it. If you want to play with sbuild, feel free. The best tool is the one you are comfortable using for the sort of work you do.


It's always dangerous to disagree with Emmet, so let me start off by acknowledging that his answer is probably more correct. However, I personally find pbuilder more user-friendly and more performant out of the box.

If you are on Ubuntu 12.10 or later, be sure to install the excellent pbuilder-scripts, which are a set of extremely friendly wrappers around raw pbuilder.

If you are on Ubuntu 12.04 you may install the pbuilder-scripts from the backports repository.

Now, let's compare and contrast the user-friendliness of equivalent operations. In these examples, I'll walk through using an ARM chroot hosted on x86, but the concepts still apply to an x86 chroot hosted on x86 as well. Remember, I'm using the pbuilder-scripts wrappers.

One thing to note is that the pbuilder-scripts implement a bit of convention, similar to how Ruby on Rails makes some decisions for you so that you can get going quickly. I'll try and point these out as we go.

Create a chroot

mk-sbuild --arch=armhf quantal

vs

# in addition to the chroot, creates a new, empty directory named ~/Projects/quantal-armhf
pcreate -a armhf -d quantal quantal-armhf

verdict: tie, both command lines are pretty simple, and both can take extra options for fancier use cases if needed. However, do note the additional new directory created by pcreate.

Download a source package

# standard debian/ubuntu method, works in any directory
apt-get source casper

vs.

# 'quantal-armhf' is the name of the chroot created earlier
# results in downloading package to: ~/Projects/quantal-armhf/casper/
pget quantal-armhf casper

verdict: slight edge for sbuild, because you're using standard debian/ubuntu best practice. The convention used by pget might seem strange at first, but since I work on multiple packages across multiple releases of Ubuntu, I like the organization it imposes. Note also that apt-get source also extracts the source wherever you run the command, leaving you with the *.orig.tar.gz, *.debian.tar.gz, *.dsc and the expanded directory, which I personally find to be messy. The beauty of the organization is coming soon, I promise.

Enter the chroot, ephemeral version

schroot -c quantal-armhf

vs.

ptest quantal-armhf

verdict: slight edge for pbuild, fewer characters to type is fewer characters. Note that in this version of entering the chroot, any changes you make here will be lost once you exit the chroot. Also note that in schroot, you will remain a normal user whereas with ptest, you will be in the chroot as the root user.

Enter the chroot, save changes version

sudo schroot -c quantal-armhf-source -u root

vs.

ptest quantal-armhf --save

verdict: slight edge for pbuild, fewer characters and more intuitive command line arguments, in my opinion. In this version of entering the chroot, any changes you make therein will be saved for future invocations.

Build a package within the chroot

debuild -S -sa -I -i
sbuild -A --arch armhf -d quantal-armhf /path/to/casper-1.315.dsc

vs.

# must be invoked when pwd is ~/Projects/quantal-armhf/casper/casper-1.315
pbuild

verdict: pbuild, now we see the first significant win when using pbuild's conventions. This is a dead simple command with nothing else to remember, versus specifying the architecture, the name of chroot, and requiring a path to a *.dsc file that sbuild requires. Additionally, you must remember to generate a new *.dsc file with sbuild whereas pbuild will do it automatically for you.

Build same package in chroot, a second time

In the above example, both sbuild and pbuild will download and install the build-deps in their respective chroots. However, pbuild saves the downloaded .deb files in /var, so if you invoke pbuild a second time, you do not have to download all the build-deps again (although they must still be installed in the chroot). sbuild does not cache the .deb files (at least not by default), and therefore, you must download all the build-deps again in addition to waiting for them to be installed in the chroot.

verdict: pbuild by a long shot. Caching the build-deps is a great default setting, and pbuild is smart enough to detect if there is a newer version of a build-dep in the archive and will pull down the new version if required. For a complex package with many build-deps, this simple setting will save you minutes of your life.

Summary

Out of the box, I find pbuilder-scripts to be much friendlier and faster than the sbuild equivalents. Of course, there are ways to make pbuilder even faster (build in a tmpfs, disable some of the chroot hooks), and there are probably the same tricks for sbuild too, but I'm unaware of them.

Hope this helps.