PbuilderHowto

Differences between revisions 176 and 196 (spanning 20 versions)
Revision 176 as of 2011-09-03 17:50:59
Size: 34004
Editor: stefanor
Comment: eatmydata
Revision 196 as of 2020-01-28 13:36:36
Size: 33350
Editor: paelzer
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
||<tablestyle="float:right; font-size: 0.9em; width:40%; background:#F1F1ED; margin: 0 0 1em 1em;" style="padding:0.5em;"><<TableOfContents>>|| ||<tablestyle="float: right; font-size: 1em; width: 30%; background: #f1f1ed; margin: 0 0 1em 1em; padding: 0.5em;"><<TableOfContents>>||
Line 5: Line 5:
Line 12: Line 11:
The following assume you want to install ''lucid''. If you need a different release, then exchange ''lucid'' with the appropriate distribution. The following assume you want to install ''eoan''. If you need a different release, then exchange ''eoan'' with the appropriate distribution.
Line 15: Line 14:

First install the required packages.
First install the required packages (in a 'eoan' system).
Line 32: Line 30:
The buildd variant will install the build-essential packages in the chroot environment, which is probably what you want, since you will be compiling packages. 

If you want to build Debian packages on Ubuntu, you need to install Debian archive keys and add Debian distribution name, Debian mirror and key location to pbuilder command line like this: 
The buildd variant will install the build-essential packages in the chroot environment, which is probably what you want, since you will be compiling packages.

If you want to build Debian packages on Ubuntu, you need to install Debian archive keys and add Debian distribution name, Debian mirror and key location to pbuilder command line like this:
Line 37: Line 35:
sudo pbuilder create --distribution squeeze --mirror ftp://ftp.us.debian.org/debian/ --debootstrapopts "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg" sudo pbuilder create --distribution squeeze --mirror http://ftp.us.debian.org/debian/ --debootstrapopts "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg"
Line 41: Line 39:
Line 51: Line 48:
Replace ''<ubuntu_version>'' with the version of ubuntu you are using (i.e. jaunty, karmic, or lucid). If the line above is there, but is commented out, you must uncomment it. Make sure your package index files are synchronized so that apt-get knows where to find the sources. Replace ''<ubuntu_version>'' with the version of ubuntu you are using (i.e. xenial, bionic or eoan). If the line above is there, but is commented out, you must uncomment it. Make sure your package index files are synchronized so that apt-get knows where to find the sources.
Line 72: Line 69:
Line 80: Line 76:
Line 92: Line 87:
Line 147: Line 141:
Line 154: Line 147:
== Updating a chroot to another version of ubuntu ==

For new packages you need a chroot of the current distribution under development of Ubuntu (hardy, at this writing). To do so, create a pbuilder chroot as usual and then do:

{{{
    sudo pbuilder update --distribution DIST-NAME --override-config
}}}

It will update the chroot to the DIST-NAME version of ubuntu and will override the configuration files to make it effective.
Then you can start building packages for the next version of ubuntu.
Line 166: Line 148:

If you us
e feisty you can use a new build-dependency resolver based on gdebi that should be significantly faster. Change ~/.pbuilderrc to add this line:
There is a build-dependency resolver based on gdebi that should be significantly faster. Change ~/.pbuilderrc to add this line:
Line 174: Line 155:
Line 203: Line 183:
Line 207: Line 186:

To change the dpkg setting login into your pbuilder and run following 
To change the dpkg setting '''login into your pbuilder''' and run following
Line 215: Line 193:
Line 217: Line 194:

For eatmydata (<= around 26)
Line 223: Line 202:
For M-A aware eatmydata (>= around 82)
{{{
# Install eatmydata in new chroots
EXTRAPACKAGES=eatmydata
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}libeatmydata.so"
}}}
Line 224: Line 210:
Line 230: Line 215:
You also have to put  You also have to put
Line 237: Line 222:
Since 0.197, ccache is enabled by default.

Using ccache with pbuilder is easy, simply add the following to '''~/.pbuilderrc''' (/etc/pbuilder/pbuilderrc is an alternative):
Pbuilder has built-in support for ccache since v0.197.

Using ccache with pbuilder is easy, simply add the following to '''~/.pbuilderrc''' (or /etc/pbuilder/pbuilderrc):
Line 243: Line 228:
sudo mkdir -p /var/cache/pbuilder/ccache
sudo chmod a+w /var/cache/pbuilder/ccache
export CCACHE_DIR="/var/cache/pbuilder/ccache"
export PATH="/usr/lib/ccache:${PATH}"
EXTRAPACKAGES=ccache
BINDMOUNTS="${CCACHE_DIR}"
CCACHEDIR=/var/cache/pbuilder/ccache
Line 254: Line 234:
Line 270: Line 249:
== Building an i386 pbuilder on AMD64 ==

One of the things a pbuilder is useful for is building i386 packages on an AMD64 machine. You can create an i386 chroot with the command:

{{{
sudo pbuilder create --debootstrapopts --arch --debootstrapopts i386
}}}

If you're interested in using pbuilder to build on other architectures, you should read the next section on multiple pbuilders.

== Multiple pbuilders ==

When you work with packages, you often want to have multiple pbuilders on your machine, if for example you want to backport to Dapper while developing on the development version of Ubuntu (currently Intrepid). Or maybe you want to [[https://wiki.ubuntu.com/ContributingToDebian|build your packages for Debian]] and have them merged back to Ubuntu. The next sections will provide some information to get you started with using multiple pbuilders.

'''STOP:''' Before you go too far here, try out pbuilder-dist in package ''ubuntu-dev-tools'' for an alternative, easy way to use pbuilder with many different Ubuntu versions.


=== Update debootstrap ===

It is recommended to use an updated version of debootstrap from the backports repository of whatever version of Ubuntu you are using. You can either activate the backports repository in your sources.list configuration or download the source package using dget, build the packages, and install them. The updated version will have support for newer distributions, such as the development branch of Ubuntu.

=== Change base.tgz Location ===

The only thing required to use pbuilder with multiple distributions is an alternate location to store the gzipped tarball that contains the pbuilder environment. On the command line, this can be specified with the 'basetgz' option. However, it is tedious to specify the full path every time pbuilder is run, so it is convenient to place a snippet in '''~/.pbuilderrc''' to automate this:

{{{#!bash
# Codenames for Debian suites according to their alias. Update these when
# needed.
UNSTABLE_CODENAME="sid"
TESTING_CODENAME="wheezy"
STABLE_CODENAME="squeeze"
STABLE_BACKPORTS_SUITE="$STABLE_CODENAME-backports"

# List of Debian suites.
DEBIAN_SUITES=($UNSTABLE_CODENAME $TESTING_CODENAME $STABLE_CODENAME
    "unstable" "testing" "stable")

# List of Ubuntu suites. Update these when needed.
UBUNTU_SUITES=("natty" "maverick" "lucid" "karmic" "jaunty" "hardy")

# Mirrors to use. Update these to your preferred mirror.
DEBIAN_MIRROR="ftp.us.debian.org"
UBUNTU_MIRROR="ftp.ubuntu.com"

# Optionally use the changelog of a package to determine the suite to use if
# none set.
if [ -z "${DIST}" ] && [ -r "debian/changelog" ]; then
    DIST=$(dpkg-parsechangelog | awk '/^Distribution: / {print $2}')
    # Use the unstable suite for certain suite values.
    if $(echo "experimental UNRELEASED" | grep -q $DIST); then
        DIST="$UNSTABLE_CODENAME"
    fi
fi

# Optionally set a default distribution if none is used. Note that you can set
# your own default (i.e. ${DIST:="unstable"}).
: ${DIST:="$(lsb_release --short --codename)"}

# Optionally change Debian release states in $DIST to their names.
case "$DIST" in
    unstable)
        DIST="$UNSTABLE_CODENAME"
        ;;
    testing)
        DIST="$TESTING_CODENAME"
        ;;
    stable)
        DIST="$STABLE_CODENAME"
        ;;
esac

# Optionally set the architecture to the host architecture if none set. Note
# that you can set your own default (i.e. ${ARCH:="i386"}).
: ${ARCH:="$(dpkg --print-architecture)"}

NAME="$DIST"
if [ -n "${ARCH}" ]; then
    NAME="$NAME-$ARCH"
    DEBOOTSTRAPOPTS=("--arch" "$ARCH" "${DEBOOTSTRAPOPTS[@]}")
fi
BASETGZ="/var/cache/pbuilder/$NAME-base.tgz"
# Optionally, set BASEPATH (and not BASETGZ) if using cowbuilder
# BASEPATH="/var/cache/pbuilder/$NAME/base.cow/"
DISTRIBUTION="$DIST"
BUILDRESULT="/var/cache/pbuilder/$NAME/result/"
APTCACHE="/var/cache/pbuilder/$NAME/aptcache/"
BUILDPLACE="/var/cache/pbuilder/build/"

if $(echo ${DEBIAN_SUITES[@]} | grep -q $DIST); then
    # Debian configuration
    MIRRORSITE="http://$DEBIAN_MIRROR/debian/"
    COMPONENTS="main contrib non-free"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg")

elif $(echo ${UBUNTU_SUITES[@]} | grep -q $DIST); then
    # Ubuntu configuration
    MIRRORSITE="http://$UBUNTU_MIRROR/ubuntu/"
    COMPONENTS="main restricted universe multiverse"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg")
else
    echo "Unknown distribution: $DIST"
    exit 1
fi
}}}

'''NOTE:''' There are some optional lines in this snippet that appear after comments that start with "Optionally". Either comment these lines out or change the lines to suit your needs.

'''NOTE:''' If you are using ubuntu, and wish to create a debian chroot, you need to install the debian-archive-keyring package.
{{{
sudo apt-get install debian-archive-keyring
}}}

Now, if the user sets DIST to another distribution such as hardy when running pbuilder, the tarball location will be changed. The line that sets the DISTRIBUTION only takes effect during the creation of a new base tarball, or if the --override-config option is given, where it specifies the distribution to use for the new base tarball. Setting BUILDRESULT or APTCACHE is optional, but possibly helpful.

If ARCH is set to a different architecture when running pbuilder, pbuilder will be set to create an environment to build packages for the architecture specified in ARCH.

We can now create and use alternate tarballs, as in the following examples:

{{{
# Create a base environment for Ubuntu hardy
sudo DIST=hardy pbuilder create

# Create a base environment for Debian sid
sudo DIST=sid pbuilder create

# Create a base environment for Ubuntu hardy under
# the i386 architecture
sudo DIST=hardy ARCH=i386 pbuilder create

# Update a base environment for Ubuntu hardy
sudo DIST=hardy pbuilder update

# Build a package using Ubuntu hardy as the base
# environment
DIST=hardy pdebuild

# Build a package using Ubuntu hardy as the base
# environment under the i386 architecture
DIST=hardy ARCH=i386 pdebuild
}}}

=== Using backport repositories in pbuilder ===

==== Debian ====

By default, no packages from backports.org is automatically installed. You will need to set your /etc/apt/preferences in your chroot to enable packages to be automatically installed from the backports suite. This can be achieved using pbuilder hooks.

First, you must create and then specify the location of the hooks directory via the HOOKDIR variable in your ~/.pbuilderrc script. For example, if you created a hooks directory under {{{/var/cache/pbuilder/hook.d}}}, then you should place the following in your ~/.pbuilderrc script.
{{{
HOOKDIR="/var/cache/pbuilder/hook.d/"
}}}

Then write a script under {{{/var/cache/pbuilder/hook.d}}} that will write the preferences file in your chroot. The script name must be of the form 'E<digit><digit><whatever else you want>'.

For example, a script can be saved to {{{/var/cache/pbuilder/hook.d/E01apt-preferences}}} and written like so.
{{{
#!/bin/sh
#!/bin/sh
set -e

STABLE_VERSION_REGEX='^5\.0\.[0-9]\+$'

if $(cat "/etc/debian_version" | grep -q -e "$STABLE_VERSION_REGEX"); then
cat > "/etc/apt/preferences" << EOF
Package: debhelper
Pin: release a=squeeze-backports
Pin-Priority: 999

Package: lintian
Pin: release a=squeeze-backports
Pin-Priority: 999
EOF
fi
}}}

Note that the only packages specified here are debhelper and lintian. More can be specified, although these are two common ones to backport. You should keep packages that are backported for your pbuilder environment at a minimum.

## Someone feel free to write an Ubuntu section for backports

=== Using the 'othermirror' option ===

It is possible to specify more mirrors than the one specified for MIRRORSITE. There's two ways to do this, specifiying the option '--othermirror "<sources.list deb line>"' when running pbuilder, or using the variable 'OTHERMIRROR="<sources.list deb line>"' in the pbuilderrc configuration file. Just replace "<sources.list deb line>" with a deb line in the same format as would be found under {{{/etc/apt/sources.list}}}.

Note: Don't forget to use '''--override-config''' and then pbuilder update to take the new repository into account.

=== Troubleshooting "pbuilder create" ===

Make sure that you have debootstrap later than X installed. The version from hardy will not suffice. Install from backports or backport yourself if necessary.

If you are running pbuilder < 0.196, then you will encounter this error when you try to create a base tarball for sid:
{{{
chroot: cannot run command `/usr/bin/apt-get': No such file or directory
}}}
This was fixed in pbuilder 0.196. To workaround this on older versions of pbuilder, you will need to add this line to your ~/.pbuilderrc
{{{
DEBOOTSTRAPOPTS=("--include=apt" "${DEBOOTSTRAPOPTS[@]}")
}}}

There will be sometimes where running {{{sudo pbuilder create}}} will fail to create a base tarball. This normally occurs only when creating base tarballs for development versions of Ubuntu or Debian (for example, Debian sid). These are development versions and it is best to wait and try at a later date to create a base tarball. It can be days however (sometimes weeks) until creating a base tarball will be successful for these development versions. In the meantime you could create a base tarball for an older version of Ubuntu or Debian and update the tarball to the development version instead.

For example, to create an etch base tarball and update to sid, start with:
{{{
sudo DIST=etch pbuilder create
}}}

Then to update, run:
{{{
sudo DIST=etch pbuilder update --override-config \
--othermirror "deb http://http.us.debian.org/debian sid main"
}}}

What will happen is that the base packages for Etch will be downloaded, installed, and configured first. Then apt-get update will be performed for "etch main" and "sid main". When the update is run, all packages in need of upgrading will be upgraded and thus, the base packages for Sid will be installed. After pbuilder is done, a base tarball will have been created but named for Etch ({{{etch-base.tgz}}}). All the base packages will be copied into the aptcache directory in {{{/var/cache/pbuilder/etch}}}. From here you can copy the aptcache directory over to the sid directory and make a copy of etch-base.tgz and call it sid-base.tgz.

{{{
sudo mkdir /var/cache/pbuilder/sid
sudo cp /var/cache/pbuilder/etch/aptcache /var/cache/pbuilder/sid/aptcache
sudo cp /var/cache/pbuilder/etch-base.tgz /var/cache/pbuilder/sid-base.tgz
}}}

It is better of course to create a base tarball directly. Check often to see if a base tarball can be created directly.
Line 492: Line 250:
Line 496: Line 253:
Line 517: Line 273:
[etch]

[hardy]

}}}

This conffile was modified from the documentation for mini-dinstall ({{{/usr/share/doc/mini-dinstall}}}). Under {{{architectures}}}, you can choose to only specify the architecture of your machine. The listing of {{{[sid]}}}, {{{[hardy]}}}, etc. is so that you will be able to upload packages using dput for Debian sid or any Ubuntu version. If you are only building packages for one version, just list only that version.
[eoan]

}}}

This conffile was modified from the documentation for mini-dinstall ({{{/usr/share/doc/mini-dinstall}}}). Under {{{architectures}}}, you can choose to only specify the architecture of your machine. The listing of {{{[sid]}}}, {{{[eoan]}}}, etc. is so that you will be able to upload packages using dput for Debian sid or any Ubuntu version. If you are only building packages for one version, just list only that version.
Line 544: Line 298:
Line 557: Line 310:
<distro-version> is either sid, hardy, etc. depending on what distro version you built the package for. In this directory, there should be a {{{Packages}}} and {{{Source}}} file along with the packages you uploaded. <distro-version> is either sid, xenial, bionic, eoan, etc. depending on what distro version you built the package for. In this directory, there should be a {{{Packages}}} and {{{Source}}} file along with the packages you uploaded.
Line 560: Line 313:
Line 566: Line 318:
TESTING_CODENAME="wheezy"
STABLE_CODENAME="squeeze"
TESTING_CODENAME="bullseye"
STABLE_CODENAME="buster"
Line 575: Line 327:
UBUNTU_SUITES=("natty" "maverick" "lucid" "karmic" "jaunty" "intrepid" "hardy") UBUNTU_SUITES=("eoan" "bionic" "xenial")
Line 591: Line 343:
        DIST="$STABLE"         DIST="$STABLE_CODENAME"
Line 651: Line 403:
sudo DIST=hardy pbuilder update \ sudo DIST=bionic pbuilder update \
Line 658: Line 410:
== Installing Pbuilder on Warty, Hoary or Breezy ==

Install pbuilder package and debootstrap.

Add this to ~/.pbuilderrc:
{{{
    MIRRORSITE=http://archive.ubuntu.com/ubuntu
    DISTRIBUTION=lucid
}}}

Since pbuilder will complain about unauthenticated packages, you have to allow unauthenticated packages. You can make it like so:

Add this to ~/.pbuilderrc:

{{{
    APTCONFDIR="/etc/pbuilder/apt.config/"
}}}
Now you'll copy needed files of /etc/apt to it and

{{{
    sudo -s
    mkdir /etc/pbuilder/apt.config/
    cp -ar /etc/apt/* /etc/pbuilder/apt.config/
    echo "APT::Get::AllowUnauthenticated 1;" >> /etc/pbuilder/apt.config/apt.conf.d/allow-unauthenticated
    exit
}}}

NOTE: Make sure to remove 99update-notifier from /etc/pbuilder/apt.config/apt.conf.d/ if you have copied it in the last step. It can potentially
break future updates to your pbuilder chroot, as update-notifier won't normally be installed.

Save the file and run the command below to build your lucid chroot:

{{{
    sudo pbuilder create --distribution lucid
}}}
Line 695: Line 411:
Line 721: Line 436:
To get the mighty Kubuntu pbuilder-hooks (written by mighty Harald Sitter aka apachelogger) run
{{{
    bzr branch lp:~kubuntu-members/pbuilder/pbuilder-hooks
}}}

Then you have to move them to an location (eg .pbuilder-hooks).

To enable them you have to put
{{{
 HOOKDIR="$HOME/.pbuilder-hooks"
}}}
into your .pbuilderrc. For further information read the README

== Building 32-bit packages on 64-bit or for older Ubuntu versions ==
To build for other distributions or architectures, you can use '''pbuilder-dist'''.
To get the mighty Kubuntu pbuilder-hooks (written by mighty Harald Sitter aka apachelogger), run:
{{{
    bzr branch lp:~kubuntu-packagers/pbuilder/pbuilder-hooks
    mkdir ~/.pbuilder-hooks
    echo 'HOOKDIR="$HOME/.pbuilder-hooks"' >> ~/.pbuilderrc
}}}

Then symlink the hooks you want to enable in `~/.pbuilder-hooks`.

All hooks are documented in the [[http://bazaar.launchpad.net/~kubuntu-packagers/pbuilder/pbuilder-hooks/view/head:/README|README]].

== Using pbuilder-dist to manage different architectures and distro releases ==
To build for other distributions or architectures, you can use '''pbuilder-dist'''. See the later section [[#Multiple pbuilders]] for important information.
Line 745: Line 458:
    pbuilder-dist lucid i386 create
    # build for lucid
i386
    pbuilder-dist lucid i386 build PACKAGE.dsc
    # build for hardy i386

    pbuilder-dist hardy i386 build PACKAGE.dsc
}}}

The resulting packages will be put into "~/pbuilder/DIST-ARCH_result" by default and not in "/var/cache/pbuilder/result" as is the case with pbuilder.
    # build for bionic i386
    pbuilder-dist bionic
i386 build PACKAGE.dsc
    # build for eoan amd64

    pbuilder-dist eoan amd64 build PACKAGE.dsc
    # build for xenial
i386
    pbuilder-dist xenial i386 build PACKAGE.dsc
}}}

The resulting packages will be put into "~/pbuilder/DIST-ARCH_result" by default and not in "/var/cache/pbuilder/result" as is the case with pbuilder. You can make the two act the same by setting PBUILDFOLDER=/var/cache/pbuilder in your .bashrc.
Line 758: Line 472:
sudo pbuilder-dist karmic i386 update --override-config --othermirror "deb http://ppa.launchpad.net/cae-team/ppa/ubuntu karmic main" sudo pbuilder-dist eoan i386 update --override-config --othermirror "deb http://ppa.launchpad.net/cae-team/ppa/ubuntu eoan main"
Line 763: Line 477:
OTHERMIRROR="deb http://ppa.launchpad.net/cae-team/ppa/ubuntu karmic main"
}}}
OTHERMIRROR="deb http://ppa.launchpad.net/cae-team/ppa/ubuntu eoan main"
}}}

== Manually doing what pbuilder-dist can do ==
'''STOP:''' Before you go too far here, try out pbuilder-dist in package ''ubuntu-dev-tools'' for an alternative, easy way to use pbuilder with many different Ubuntu versions. It can support multiple pbuilders for different architectures and releases of both Ubuntu and Debian.

=== Updating a chroot to another version of ubuntu ===
For new packages you need a chroot of the current distribution under development of Ubuntu. To do so, create a pbuilder chroot as usual and then do:

{{{
    sudo pbuilder update --distribution DIST-NAME --override-config
}}}

It will update the chroot to the DIST-NAME version of ubuntu and will override the configuration files to make it effective.
Then you can start building packages for the next version of ubuntu.

=== Building an i386 pbuilder on amd64 ===
One of the things a pbuilder is useful for is building i386 packages on an amd64 machine. You can create an i386 chroot with the command:

{{{
sudo pbuilder create --debootstrapopts --arch --debootstrapopts i386
}}}

If you're interested in using pbuilder to build on other architectures, you should read the next section on multiple pbuilders.

=== Multiple pbuilders ===
When you work with packages, you often want to have multiple pbuilders on your machine, if for example you want to backport to Bionic or Xenial while developing on the development version of Ubuntu (currently Eoan). Or maybe you want to [[https://wiki.ubuntu.com/ContributingToDebian|build your packages for Debian]] and have them merged back to Ubuntu. The next sections will provide some information to get you started with using multiple pbuilders. [[https://wiki.debian.org/PbuilderTricks]] gives some details not covered on this page.

==== Update debootstrap ====
It is recommended to use an updated version of debootstrap from the backports repository of whatever version of Ubuntu you are using. You can either activate the backports repository in your sources.list configuration or download the source package using dget, build the packages, and install them. The updated version will have support for newer distributions, such as the development branch of Ubuntu.

==== Change base.tgz Location ====
The only thing required to use pbuilder with multiple distributions is an alternate location to store the gzipped tarball that contains the pbuilder environment. On the command line, this can be specified with the 'basetgz' option. However, it is tedious to specify the full path every time pbuilder is run, so it is convenient to place a snippet in '''~/.pbuilderrc''' to automate this:

{{{#!bash
# Codenames for Debian suites according to their alias. Update these when
# needed.
UNSTABLE_CODENAME="sid"
TESTING_CODENAME="bullseye"
STABLE_CODENAME="buster"
STABLE_BACKPORTS_SUITE="$STABLE_CODENAME-backports"

# List of Debian suites.
DEBIAN_SUITES=($UNSTABLE_CODENAME $TESTING_CODENAME $STABLE_CODENAME
    "unstable" "testing" "stable")

# List of Ubuntu suites. Update these when needed.
UBUNTU_SUITES=("eoan" "bionic" "xenial")

# Mirrors to use. Update these to your preferred mirror.
DEBIAN_MIRROR="ftp.us.debian.org"
UBUNTU_MIRROR="ftp.ubuntu.com"

# Optionally use the changelog of a package to determine the suite to use if
# none set.
if [ -z "${DIST}" ] && [ -r "debian/changelog" ]; then
    DIST=$(dpkg-parsechangelog | awk '/^Distribution: / {print $2}')
    DIST="${DIST%%-*}"
    # Use the unstable suite for certain suite values.
    if $(echo "experimental UNRELEASED" | grep -q $DIST); then
        DIST="$UNSTABLE_CODENAME"
    fi
fi

# Optionally set a default distribution if none is used. Note that you can set
# your own default (i.e. ${DIST:="unstable"}).
: ${DIST:="$(lsb_release --short --codename)"}

# Optionally change Debian release states in $DIST to their names.
case "$DIST" in
    unstable)
        DIST="$UNSTABLE_CODENAME"
        ;;
    testing)
        DIST="$TESTING_CODENAME"
        ;;
    stable)
        DIST="$STABLE_CODENAME"
        ;;
esac

# Optionally set the architecture to the host architecture if none set. Note
# that you can set your own default (i.e. ${ARCH:="i386"}).
: ${ARCH:="$(dpkg --print-architecture)"}

NAME="$DIST"
if [ -n "${ARCH}" ]; then
    NAME="$NAME-$ARCH"
    DEBOOTSTRAPOPTS=("--arch" "$ARCH" "${DEBOOTSTRAPOPTS[@]}")
fi
BASETGZ="/var/cache/pbuilder/$NAME-base.tgz"
# Optionally, set BASEPATH (and not BASETGZ) if using cowbuilder
# BASEPATH="/var/cache/pbuilder/$NAME/base.cow/"
DISTRIBUTION="$DIST"
BUILDRESULT="/var/cache/pbuilder/$NAME/result/"
APTCACHE="/var/cache/pbuilder/$NAME/aptcache/"
BUILDPLACE="/var/cache/pbuilder/build/"

if $(echo ${DEBIAN_SUITES[@]} | grep -q $DIST); then
    # Debian configuration
    MIRRORSITE="http://$DEBIAN_MIRROR/debian/"
    COMPONENTS="main contrib non-free"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg")

elif $(echo ${UBUNTU_SUITES[@]} | grep -q $DIST); then
    # Ubuntu configuration
    MIRRORSITE="http://$UBUNTU_MIRROR/ubuntu/"
    COMPONENTS="main restricted universe multiverse"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg")
else
    echo "Unknown distribution: $DIST"
    exit 1
fi
}}}

'''NOTE:''' There are some optional lines in this snippet that appear after comments that start with "Optionally". Either comment these lines out or change the lines to suit your needs.

'''NOTE:''' If you are using ubuntu, and wish to create a debian chroot, you need to install the debian-archive-keyring package.
{{{
sudo apt-get install debian-archive-keyring
}}}

Now, if the user sets DIST to another distribution such as bionic when running pbuilder, the tarball location will be changed. The line that sets the DISTRIBUTION only takes effect during the creation of a new base tarball, or if the --override-config option is given, where it specifies the distribution to use for the new base tarball. Setting BUILDRESULT or APTCACHE is optional, but possibly helpful.

If ARCH is set to a different architecture when running pbuilder, pbuilder will be set to create an environment to build packages for the architecture specified in ARCH.

We can now create and use alternate tarballs, as in the following examples:

{{{
# Create a base environment for Debian sid
sudo DIST=sid pbuilder create

# Create a base environment for Ubuntu eoan under
# the i386 architecture
sudo DIST=eoan ARCH=i386 pbuilder create

# Create a base environment for Ubuntu eoan
sudo DIST=eoan pbuilder create

# Update a base environment for Ubuntu eoan
sudo DIST=eoan pbuilder update

# Build a package using Ubuntu eoan as the base
# environment
DIST=eoan pdebuild

# Build a package using Ubuntu eoan as the base
# environment under the i386 architecture
DIST=eoan ARCH=i386 pdebuild
}}}

=== Using backport repositories in pbuilder ===
==== Debian ====
By default, no packages from backports.org is automatically installed. You will need to set your /etc/apt/preferences in your chroot to enable packages to be automatically installed from the backports suite. This can be achieved using pbuilder hooks.

First, you must create and then specify the location of the hooks directory via the HOOKDIR variable in your ~/.pbuilderrc script. For example, if you created a hooks directory under {{{/var/cache/pbuilder/hook.d}}}, then you should place the following in your ~/.pbuilderrc script.
{{{
HOOKDIR="/var/cache/pbuilder/hook.d/"
}}}

Then write a script under {{{/var/cache/pbuilder/hook.d}}} that will write the preferences file in your chroot. The script name must be of the form 'E<digit><digit><whatever else you want>'.

For example, a script can be saved to {{{/var/cache/pbuilder/hook.d/E01apt-preferences}}} and written like so.
{{{
#!/bin/sh
#!/bin/sh
set -e

STABLE_VERSION_REGEX='^5\.0\.[0-9]\+$'

if $(cat "/etc/debian_version" | grep -q -e "$STABLE_VERSION_REGEX"); then
cat > "/etc/apt/preferences" << EOF
Package: debhelper
Pin: release a=squeeze-backports
Pin-Priority: 999

Package: lintian
Pin: release a=squeeze-backports
Pin-Priority: 999
EOF
fi
}}}

Note that the only packages specified here are debhelper and lintian. More can be specified, although these are two common ones to backport. You should keep packages that are backported for your pbuilder environment at a minimum.

## Someone feel free to write an Ubuntu section for backports

==== Using the 'othermirror' option ====
It is possible to specify more mirrors than the one specified for MIRRORSITE. There's two ways to do this, specifiying the option '--othermirror "<sources.list deb line>"' when running pbuilder, or using the variable 'OTHERMIRROR="<sources.list deb line>"' in the pbuilderrc configuration file. Just replace "<sources.list deb line>" with a deb line in the same format as would be found under {{{/etc/apt/sources.list}}}.

Note: Don't forget to use '''--override-config''' and then pbuilder update to take the new repository into account.

==== Troubleshooting "pbuilder create" ====
Make sure that you have debootstrap later than X installed. The version from hardy will not suffice. Install from backports or backport yourself if necessary.

If you are running pbuilder < 0.196, then you will encounter this error when you try to create a base tarball for sid:
{{{
chroot: cannot run command `/usr/bin/apt-get': No such file or directory
}}}
This was fixed in pbuilder 0.196. To workaround this on older versions of pbuilder, you will need to add this line to your ~/.pbuilderrc
{{{
DEBOOTSTRAPOPTS=("--include=apt" "${DEBOOTSTRAPOPTS[@]}")
}}}

There will be sometimes where running {{{sudo pbuilder create}}} will fail to create a base tarball. This normally occurs only when creating base tarballs for development versions of Ubuntu or Debian (for example, Debian sid). These are development versions and it is best to wait and try at a later date to create a base tarball. It can be days however (sometimes weeks) until creating a base tarball will be successful for these development versions. In the meantime you could create a base tarball for an older version of Ubuntu or Debian and update the tarball to the development version instead.

For example, to create an etch base tarball and update to sid, start with:
{{{
sudo DIST=etch pbuilder create
}}}

Then to update, run:
{{{
sudo DIST=etch pbuilder update --override-config \
--othermirror "deb http://http.us.debian.org/debian sid main"
}}}

What will happen is that the base packages for Etch will be downloaded, installed, and configured first. Then apt-get update will be performed for "etch main" and "sid main". When the update is run, all packages in need of upgrading will be upgraded and thus, the base packages for Sid will be installed. After pbuilder is done, a base tarball will have been created but named for Etch ({{{etch-base.tgz}}}). All the base packages will be copied into the aptcache directory in {{{/var/cache/pbuilder/etch}}}. From here you can copy the aptcache directory over to the sid directory and make a copy of etch-base.tgz and call it sid-base.tgz.

{{{
sudo mkdir /var/cache/pbuilder/sid
sudo cp /var/cache/pbuilder/etch/aptcache /var/cache/pbuilder/sid/aptcache
sudo cp /var/cache/pbuilder/etch-base.tgz /var/cache/pbuilder/sid-base.tgz
}}}

It is better of course to create a base tarball directly. Check often to see if a base tarball can be created directly.
Line 767: Line 705:

pbuilder User's Manual: http://www.netfort.gr.jp/~dancer/software/pbuilder-doc/pbuilder-doc.html
[[https://pbuilder-team.pages.debian.net/pbuilder/|pbuilder User's Manual]]

Introduction

pbuilder allows users to setup a chroot environment for building Ubuntu packages. A clean chroot environment makes it possible to check what dependencies are really required or missing. It's one of the "best practices" for many maintainers of Ubuntu or Debian packages, and also for anyone interested in building packages using Ubuntu (yes, you can build Debian packages using Ubuntu). This document describes how to use pbuilder to do this.

You can build packages without pbuilder but you must already have all the build dependencies of the package that you are building installed on your running system.

If you use LVM and want to take advantage of using LVM snapshots to speed up the chroot creation/destruction, please see SbuildLVMHowto for an alternate approach.

The following assume you want to install eoan. If you need a different release, then exchange eoan with the appropriate distribution.

The First Steps

First install the required packages (in a 'eoan' system).

sudo apt-get install pbuilder debootstrap devscripts

NOTE: devscripts is not necessary to install along with pbuilder, however if you are serious about using pbuilder and creating and maintaining packages for Ubuntu or Debian, you will want to install devscripts.

Create a base tarball that will contain your chroot environment to build packages with.

sudo pbuilder create

To more closely mimic the environment of the official build machines, you can use the '--variant=buildd' option when creating the base tarball.

sudo pbuilder create --debootstrapopts --variant=buildd

The buildd variant will install the build-essential packages in the chroot environment, which is probably what you want, since you will be compiling packages.

If you want to build Debian packages on Ubuntu, you need to install Debian archive keys and add Debian distribution name, Debian mirror and key location to pbuilder command line like this:

sudo apt-get install debian-archive-keyring
sudo pbuilder create --distribution squeeze --mirror http://ftp.us.debian.org/debian/ --debootstrapopts "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg"

Rebuilding a package

If everything went well, you should now have a tarball called base.tgz in your system under /var/cache/pbuilder.

To check if you can download source packages, you will need an uncommented deb-src line in /etc/apt/sources.list. It should look like:

    deb-src http://archive.ubuntu.com/ubuntu <ubuntu_version> main restricted universe multiverse

Replace <ubuntu_version> with the version of ubuntu you are using (i.e. xenial, bionic or eoan). If the line above is there, but is commented out, you must uncomment it. Make sure your package index files are synchronized so that apt-get knows where to find the sources.

After you ensured the deb-src line is correct and uncommented, run:

    sudo apt-get update

We will build bc, a simple calculator, from source, let's download the debian source package (which also gets the .dsc file) from ubuntu repository:

    apt-get source bc

Now build the package using your chroot cleanroom you created with the command:

    sudo pbuilder build *.dsc

Once the packages are successfully built, the binary and source packages will be stored in /var/cache/pbuilder/result/

pdebuild

pdebuild is the pbuilder way of doing debuild. It comes along with the pbuilder package. pdebuild runs essentially in the same way as debuild. Go into the source tree containing the debian directory and type:

    pdebuild

Downloading Source Packages Using dget

There will be times when a package you want or need to build is not in the repositories of the current version of Ubuntu you are running. Rather than entering deb-src lines in your sources.list configuration for other versions of Ubuntu you are not running, you can use dget instead to download a package. dget is included in the devscripts package, hence why you should have installed it.

To use dget, first locate the .dsc file of the package you are going to build. Good places to look are http://packages.ubuntu.com/ or http://packages.debian.org/ . Once you located the .dsc file. Copy the link address to it and then in a command prompt run:

    dget <link_address_to_foo.dsc>

Signing Source Files

If you intend to upload your packages to REVU, http://mentors.debian.net/, or any other location, it is highly recommended you sign your source files (.dsc and .changes files). Both REVU and http://mentors.debian.net/ enforce signed sources. The easiest way to do this after using pbuilder is by using debsign. Assuming your packages and source files were placed in /var/cache/pbuilder/result/, run;

(i) You may want to run sudo chown $USER /var/cache/pbuilder/result so that you can sign the packages.

debsign /var/cache/pbuilder/result/*.changes

NOTE: The debsign tool is part of the devscripts package mentioned previously.

If you attempted to run the debsign command as a continuation of the previous instructions for building the bc package (see "Rebuilding a package" section above), you may encounter the following error:

$ debsign bc_1.06.94-3ubuntu1_i386.changes
 signfile bc_1.06.94-3ubuntu1.dsc Matthias Klose <doko@ubuntu.com>
gpg: skipped "Matthias Klose <doko@ubuntu.com>": secret key not available
gpg: [stdin]: clearsign failed: secret key not available
debsign: gpg error occurred!  Aborting....

First, keep in mind that debsign requires a PGP Key in order to create a signature for a document. If you have not already done so, you should read the GNU Privacy Guard wiki page. Even if you have created a PGP key, the command above may not work because debsign does not know what key to use. If no key is specified, the program searches through the target file ("bc_1.06.94-3ubuntu1_i386.changes" in the bc example) for the "Changed-By" field and tries to sign it using that exact UID ("Matthias Klose <doko@ubuntu.com>" in this case). Unless you are Matthias Klose, you will not be able to sign this document using that UID because you will not have the necessary private key. Instead, you must sign it using your own key by using the -k<your_own_key> command option. In the example below, the key used is "5D1AFE8F".

$ debsign -k5D1AFE8F bc_1.06.94-3ubuntu1_i386.changes
 signfile bc_1.06.94-3ubuntu1_i386.changes 5D1AFE8F

You need a passphrase to unlock the secret key for
user: "Darmeister (The DAR) <user_kp@yahoo.com>"
1024-bit DSA key, ID 5D1AFE8F, created 2009-02-03

Successfully signed dsc and changes files

If you want to save yourself the hassle of specifying the command arguments every time you run debsign, modify the configuration file(s) based on the instructions listed at the bottom of the debsign manpage (see below). Set DEBSIGN_PROGRAM=gpg, DEBSIGN_SIGNLIKE=gpg and DEBSIGN_KEYID=5D1AFE8F in one of the configurations files. This will provide the necessary parameters for debsign to execute properly.

CONFIGURATION VARIABLES
       The  two configuration files /etc/devscripts.conf and ~/.devscripts are
       sourced in that order to set  configuration  variables.   Command  line
       options  can be used to override configuration file settings.  Environ‐
       ment variable settings are ignored for  this  purpose.   The  currently
       recognised variables are:

       DEBSIGN_PROGRAM
              Setting this is equivalent to giving a -p option.

       DEBSIGN_SIGNLIKE
              This  must be gpg or pgp and is equivalent to using either -sgpg
              or -spgp respectively.

       DEBSIGN_MAINT
              This is the -m option.

       DEBSIGN_KEYID
              And this is the -k option.

Updating a chroot

It is recommended you update your chroot daily before each build, to do this task use the command below:

    sudo pbuilder update

Speeding up build-dependency calculation

There is a build-dependency resolver based on gdebi that should be significantly faster. Change ~/.pbuilderrc to add this line:

    PBUILDERSATISFYDEPENDSCMD="/usr/lib/pbuilder/pbuilder-satisfydepends-gdebi"

Problems with pbuilder-satisfydepends-gdebi and local repositories

If you are using a local overlay repository (a very advanced use of pbuilder usually used for backport archives), you will likely want to use a modified version of 'pbuilder-satisfydepends-gdebi'. First, copy the dependency resolver over, and mark it as executable.

   cp /usr/lib/pbuilder/pbuilder-satisfydepends-gdebi ~/.pbuilder-satisfydepends-gdebi
   chmod +x ~/.pbuilder-satisfydepends-gdebi

Change line 80 of '$HOME/.pbuilder-satisfydepends-gdebi' to ignore warnings from local packages that aren't in the Ubuntu keyring.

Change:

   $CHROOTEXEC /usr/bin/apt-get install -y $INSTALL

To this:

   $CHROOTEXEC /usr/bin/apt-get install -y --force-yes $INSTALL

Then change ~/.pbuilderrc to use your local modified dependency resolver script instead of the one which comes with pbuilder by default:

   PBUILDERSATISFYDEPENDSCMD="~/.pbuilder-satisfydepends-gdebi"

Speeding up the package installation

To speed up the package installation you have to options tmpfs and an dpkg setting.

dpkg setting

To change the dpkg setting login into your pbuilder and run following

    echo "force-unsafe-io" > /etc/dpkg/dpkg.cfg.d/02apt-speedup

this forces dpkg not to call sync() after package extraction and leads to 1-2 packages installed per second.

eatmydata

Install eatmydata inside and outside the chroot.

For eatmydata (<= around 26)

# Install eatmydata in new chroots (will cause chroot creation failure for pre-maverick chroots)
EXTRAPACKAGES=eatmydata
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}/usr/lib/libeatmydata/libeatmydata.so"

For M-A aware eatmydata (>= around 82)

# Install eatmydata in new chroots
EXTRAPACKAGES=eatmydata
export LD_PRELOAD="${LD_PRELOAD:+$LD_PRELOAD:}libeatmydata.so"

tmpfs

Tmpfs is an option to create an filesystem in your RAM. To use tmpfs put following into your fstab (you need at least 3G of RAM, 4 or more is better)

  tmpfs           /var/cache/pbuilder/build               tmpfs        defaults,size=2400M        0       0

You also have to put

   APTCACHEHARDLINK=no

into your .pbuilderrc

Integration with ccache

Pbuilder has built-in support for ccache since v0.197.

Using ccache with pbuilder is easy, simply add the following to ~/.pbuilderrc (or /etc/pbuilder/pbuilderrc):

# ccache
CCACHEDIR=/var/cache/pbuilder/ccache

Now pbuilder will automatically cache compiler output between multiple builds of the same software.

Universe support

If you want to rebuild a package from universe or build a new one that needs a package out of main you will need to add this to ~/.pbuilderrc:

COMPONENTS="main restricted universe multiverse"

if [ "$DIST" == "squeeze" ]; then
    echo "Using a Debian pbuilder environment because DIST is $DIST"
    COMPONENTS="main contrib non-free"
fi

After adding the new sources you need to update the chroot, so that it picks up the new apt lines:

sudo pbuilder update --override-config

Building With Local Packages

Sometimes a package you intend to build will depend on a recent version of a package that isn't found in the Ubuntu or Debian archives. Or your package depends on another package that isn't in the Ubuntu or Debian archives at all. For these type of cases, you could create the packages and upload them to your local filesystem as you wait for a package to be uploaded to the archives. The next sections will cover setting up a miniature repository on your system for use with pbuilder.

Setting up

First, install the required packages.

sudo apt-get install dput mini-dinstall

Create a file call .mini-dinstall.conf under your home directory with the following contents:

[DEFAULT]
architectures = all, i386, amd64, powerpc
archivedir = /var/cache/archive/
use_dnotify = 0
verify_sigs = 0
extra_keyrings = ~/.gnupg/pubring.gpg
mail_on_success = 0
archive_style = flat
poll_time = 10
mail_log_level = NONE

[sid]

[eoan]

This conffile was modified from the documentation for mini-dinstall (/usr/share/doc/mini-dinstall). Under architectures, you can choose to only specify the architecture of your machine. The listing of [sid], [eoan], etc. is so that you will be able to upload packages using dput for Debian sid or any Ubuntu version. If you are only building packages for one version, just list only that version.

Edit the [local] stanza under ~/.dput.cf (/etc/dput.cf is an alternative) to look like:

[local]
method = local
incoming = /var/cache/archive/mini-dinstall/incoming
allow_non-us_software = 1
run_dinstall = 0
post_upload_command = mini-dinstall --batch

Now create the "incoming" directory for your local repository and set yourself as the owner.

sudo mkdir -p /var/cache/archive/mini-dinstall/incoming
sudo chown -R $USER /var/cache/archive/

Uploading to Local Filesystem

Once you build a package, you can upload it to your local filesystem. Run:

dput local foo*.changes

With the configuration above, it should end up in

/var/cache/archive/<distro-version>

<distro-version> is either sid, xenial, bionic, eoan, etc. depending on what distro version you built the package for. In this directory, there should be a Packages and Source file along with the packages you uploaded.

Updating Using the Local Repository

Rewrite your pbuilderrc configuration file to place a snippet to look like this.

# Codenames for Debian suites according to their alias. Update these when
# needed.
UNSTABLE_CODENAME="sid"
TESTING_CODENAME="bullseye"
STABLE_CODENAME="buster"
STABLE_BACKPORTS_SUITE="$STABLE_CODENAME-backports"

# List of Debian suites.
DEBIAN_SUITES=($UNSTABLE_CODENAME $TESTING_CODENAME $STABLE_CODENAME
    "unstable" "testing" "stable")

# List of Ubuntu suites. Update these when needed.
UBUNTU_SUITES=("eoan" "bionic" "xenial")

# Mirrors to use. Update these to your preferred mirror.
DEBIAN_MIRROR="ftp.us.debian.org"
UBUNTU_MIRROR="mirrors.kernel.org"

# Optionally use the changelog of a package to determine the suite to use if
# none set.
if [ -z "${DIST}" ] && [ -r "debian/changelog" ]; then
    DIST=$(dpkg-parsechangelog | awk '/^Distribution: / {print $2}')
    # Use the unstable suite for certain suite values.
    if $(echo "experimental UNRELEASED" | grep -q $DIST); then
        DIST="$UNSTABLE_CODENAME"
    fi
    # Use the stable suite for stable-backports.
    if $(echo "$STABLE_BACKPORTS_SUITE" | grep -q $DIST); then
        DIST="$STABLE_CODENAME"
    fi
fi

# Optionally set a default distribution if none is used. Note that you can set
# your own default (i.e. ${DIST:="unstable"}).
: ${DIST:="$(lsb_release --short --codename)"}

# Optionally change Debian release states in $DIST to their names.
case "$DIST" in
    unstable)
        DIST="$UNSTABLE_CODENAME"
        ;;
    testing)
        DIST="$TESTING_CODENAME"
        ;;
    stable)
        DIST="$STABLE_CODENAME"
        ;;
esac

# Optionally set the architecture to the host architecture if none set. Note
# that you can set your own default (i.e. ${ARCH:="i386"}).
: ${ARCH:="$(dpkg --print-architecture)"}

NAME="$DIST"
if [ -n "${ARCH}" ]; then
    NAME="$NAME-$ARCH"
    DEBOOTSTRAPOPTS=("--arch" "$ARCH" "${DEBOOTSTRAPOPTS[@]}")
fi
BASETGZ="/var/cache/pbuilder/$NAME-base.tgz"
# Optionally, set BASEPATH (and not BASETGZ) if using cowbuilder
# BASEPATH="/var/cache/pbuilder/$NAME/base.cow/"
DISTRIBUTION="$DIST"
BUILDRESULT="/var/cache/pbuilder/$NAME/result/"
APTCACHE="/var/cache/pbuilder/$NAME/aptcache/"
BUILDPLACE="/var/cache/pbuilder/build/"
BINDMOUNTS="/var/cache/archive"

if $(echo ${DEBIAN_SUITES[@]} | grep -q $DIST); then
    # Debian configuration
    MIRRORSITE="http://$DEBIAN_MIRROR/debian/"
    COMPONENTS="main contrib non-free"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg")
    OTHERMIRROR="deb file:///var/cache/archive $DIST/"

elif $(echo ${UBUNTU_SUITES[@]} | grep -q $DIST); then
    # Ubuntu configuration
    MIRRORSITE="http://$UBUNTU_MIRROR/ubuntu/"
    COMPONENTS="main restricted universe multiverse"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg")
    OTHERMIRROR="deb file:///var/cache/archive $DIST/"
else
    echo "Unknown distribution: $DIST"
    exit 1
fi

Now do an update of pbuilder. You will need to run pbuilder with the 'override-config' first before your base environments will use the new "deb" location. Use the 'override-config' and the 'configfile' option to use the new entries in your config file.

sudo DIST=bionic pbuilder update \
--override-config \
--configfile ~/.pbuilderrc

After updating each base environment to use your local repository, you can use the pbuilder/pdebuild commands as before.

Running a Shell When Build Fails (Intro to Hook Scripts)

This is done using a hook script. First we need to create a directory to home your pbuilder hooks. This can be anywhere but we'll use a directory in /var/cache/pbuilder for this example:

    sudo mkdir /var/cache/pbuilder/hook.d

Now we need to tell pbuilder to use this directory as its hook directory. Edit ~/.pbuilderrc and add the following line:

    HOOKDIR="/var/cache/pbuilder/hook.d"

Then we need to add a hook script to be called by pbuilder when the build fails. The script needs to be placed in the HOOKDIR and made executable. The name of the hook script is also important. See the pbuilder man page for details. As you can see, for this example, we need to name the script C<digit><digit><whatever-else-you-want> so let's call it C10shell. Edit the new file /var/cache/pbuilder/hook.d/C10shell and add the following:

#!/bin/sh
# invoke shell if build fails.

apt-get install -y --force-yes vim less bash
cd /tmp/buildd/*/debian/..
/bin/bash < /dev/tty > /dev/tty 2> /dev/tty

This script must be made world executable for pbuilder to execute it, so now we run:

    sudo chmod a+x /var/cache/pbuilder/hook.d/C10shell

And you're all set.

Using the Kubuntu pbuilder hooks

To get the mighty Kubuntu pbuilder-hooks (written by mighty Harald Sitter aka apachelogger), run:

    bzr branch lp:~kubuntu-packagers/pbuilder/pbuilder-hooks
    mkdir ~/.pbuilder-hooks
    echo 'HOOKDIR="$HOME/.pbuilder-hooks"' >> ~/.pbuilderrc

Then symlink the hooks you want to enable in ~/.pbuilder-hooks.

All hooks are documented in the README.

Using pbuilder-dist to manage different architectures and distro releases

To build for other distributions or architectures, you can use pbuilder-dist. See the later section #Multiple pbuilders for important information.

Syntax:

    pbuilder-dist distribution [architecture] [mainonly] operation [...]

Examples:

    # You must first call create, just as with the normal pbuilder
    # build for bionic i386
    pbuilder-dist bionic i386 build PACKAGE.dsc
    # build for eoan amd64
    pbuilder-dist eoan amd64 build PACKAGE.dsc
    # build for xenial i386
    pbuilder-dist xenial i386 build PACKAGE.dsc

The resulting packages will be put into "~/pbuilder/DIST-ARCH_result" by default and not in "/var/cache/pbuilder/result" as is the case with pbuilder. You can make the two act the same by setting PBUILDFOLDER=/var/cache/pbuilder in your .bashrc.

Differences with pbuilder

pbuilder-dist does apparently not yet support all kinds of operations. The following doesn't work correctly for example:

sudo pbuilder-dist eoan i386 update --override-config --othermirror "deb http://ppa.launchpad.net/cae-team/ppa/ubuntu eoan main"

So if you want to add a repository, you will have to use "OTHERMIRROR" in ~/.pbuilderrc as follows:

OTHERMIRROR="deb http://ppa.launchpad.net/cae-team/ppa/ubuntu eoan main"

Manually doing what pbuilder-dist can do

STOP: Before you go too far here, try out pbuilder-dist in package ubuntu-dev-tools for an alternative, easy way to use pbuilder with many different Ubuntu versions. It can support multiple pbuilders for different architectures and releases of both Ubuntu and Debian.

Updating a chroot to another version of ubuntu

For new packages you need a chroot of the current distribution under development of Ubuntu. To do so, create a pbuilder chroot as usual and then do:

    sudo pbuilder update --distribution DIST-NAME --override-config

It will update the chroot to the DIST-NAME version of ubuntu and will override the configuration files to make it effective. Then you can start building packages for the next version of ubuntu.

Building an i386 pbuilder on amd64

One of the things a pbuilder is useful for is building i386 packages on an amd64 machine. You can create an i386 chroot with the command:

sudo pbuilder create --debootstrapopts --arch --debootstrapopts i386

If you're interested in using pbuilder to build on other architectures, you should read the next section on multiple pbuilders.

Multiple pbuilders

When you work with packages, you often want to have multiple pbuilders on your machine, if for example you want to backport to Bionic or Xenial while developing on the development version of Ubuntu (currently Eoan). Or maybe you want to build your packages for Debian and have them merged back to Ubuntu. The next sections will provide some information to get you started with using multiple pbuilders. https://wiki.debian.org/PbuilderTricks gives some details not covered on this page.

Update debootstrap

It is recommended to use an updated version of debootstrap from the backports repository of whatever version of Ubuntu you are using. You can either activate the backports repository in your sources.list configuration or download the source package using dget, build the packages, and install them. The updated version will have support for newer distributions, such as the development branch of Ubuntu.

Change base.tgz Location

The only thing required to use pbuilder with multiple distributions is an alternate location to store the gzipped tarball that contains the pbuilder environment. On the command line, this can be specified with the 'basetgz' option. However, it is tedious to specify the full path every time pbuilder is run, so it is convenient to place a snippet in ~/.pbuilderrc to automate this:

# Codenames for Debian suites according to their alias. Update these when
# needed.
UNSTABLE_CODENAME="sid"
TESTING_CODENAME="bullseye"
STABLE_CODENAME="buster"
STABLE_BACKPORTS_SUITE="$STABLE_CODENAME-backports"

# List of Debian suites.
DEBIAN_SUITES=($UNSTABLE_CODENAME $TESTING_CODENAME $STABLE_CODENAME
    "unstable" "testing" "stable")

# List of Ubuntu suites. Update these when needed.
UBUNTU_SUITES=("eoan" "bionic" "xenial")

# Mirrors to use. Update these to your preferred mirror.
DEBIAN_MIRROR="ftp.us.debian.org"
UBUNTU_MIRROR="ftp.ubuntu.com"

# Optionally use the changelog of a package to determine the suite to use if
# none set.
if [ -z "${DIST}" ] && [ -r "debian/changelog" ]; then
    DIST=$(dpkg-parsechangelog | awk '/^Distribution: / {print $2}')
    DIST="${DIST%%-*}"
    # Use the unstable suite for certain suite values.
    if $(echo "experimental UNRELEASED" | grep -q $DIST); then
        DIST="$UNSTABLE_CODENAME"
    fi
fi

# Optionally set a default distribution if none is used. Note that you can set
# your own default (i.e. ${DIST:="unstable"}).
: ${DIST:="$(lsb_release --short --codename)"}

# Optionally change Debian release states in $DIST to their names.
case "$DIST" in
    unstable)
        DIST="$UNSTABLE_CODENAME"
        ;;
    testing)
        DIST="$TESTING_CODENAME"
        ;;
    stable)
        DIST="$STABLE_CODENAME"
        ;;
esac

# Optionally set the architecture to the host architecture if none set. Note
# that you can set your own default (i.e. ${ARCH:="i386"}).
: ${ARCH:="$(dpkg --print-architecture)"}

NAME="$DIST"
if [ -n "${ARCH}" ]; then
    NAME="$NAME-$ARCH"
    DEBOOTSTRAPOPTS=("--arch" "$ARCH" "${DEBOOTSTRAPOPTS[@]}")
fi
BASETGZ="/var/cache/pbuilder/$NAME-base.tgz"
# Optionally, set BASEPATH (and not BASETGZ) if using cowbuilder
# BASEPATH="/var/cache/pbuilder/$NAME/base.cow/"
DISTRIBUTION="$DIST"
BUILDRESULT="/var/cache/pbuilder/$NAME/result/"
APTCACHE="/var/cache/pbuilder/$NAME/aptcache/"
BUILDPLACE="/var/cache/pbuilder/build/"

if $(echo ${DEBIAN_SUITES[@]} | grep -q $DIST); then
    # Debian configuration
    MIRRORSITE="http://$DEBIAN_MIRROR/debian/"
    COMPONENTS="main contrib non-free"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/debian-archive-keyring.gpg")

elif $(echo ${UBUNTU_SUITES[@]} | grep -q $DIST); then
    # Ubuntu configuration
    MIRRORSITE="http://$UBUNTU_MIRROR/ubuntu/"
    COMPONENTS="main restricted universe multiverse"
    DEBOOTSTRAPOPTS=("${DEBOOTSTRAPOPTS[@]}" "--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg")
else
    echo "Unknown distribution: $DIST"
    exit 1
fi

NOTE: There are some optional lines in this snippet that appear after comments that start with "Optionally". Either comment these lines out or change the lines to suit your needs.

NOTE: If you are using ubuntu, and wish to create a debian chroot, you need to install the debian-archive-keyring package.

sudo apt-get install debian-archive-keyring

Now, if the user sets DIST to another distribution such as bionic when running pbuilder, the tarball location will be changed. The line that sets the DISTRIBUTION only takes effect during the creation of a new base tarball, or if the --override-config option is given, where it specifies the distribution to use for the new base tarball. Setting BUILDRESULT or APTCACHE is optional, but possibly helpful.

If ARCH is set to a different architecture when running pbuilder, pbuilder will be set to create an environment to build packages for the architecture specified in ARCH.

We can now create and use alternate tarballs, as in the following examples:

# Create a base environment for Debian sid
sudo DIST=sid pbuilder create

# Create a base environment for Ubuntu eoan under
# the i386 architecture
sudo DIST=eoan ARCH=i386 pbuilder create

# Create a base environment for Ubuntu eoan
sudo DIST=eoan pbuilder create

# Update a base environment for Ubuntu eoan
sudo DIST=eoan pbuilder update

# Build a package using Ubuntu eoan as the base
# environment
DIST=eoan pdebuild

# Build a package using Ubuntu eoan as the base
# environment under the i386 architecture
DIST=eoan ARCH=i386 pdebuild

Using backport repositories in pbuilder

Debian

By default, no packages from backports.org is automatically installed. You will need to set your /etc/apt/preferences in your chroot to enable packages to be automatically installed from the backports suite. This can be achieved using pbuilder hooks.

First, you must create and then specify the location of the hooks directory via the HOOKDIR variable in your ~/.pbuilderrc script. For example, if you created a hooks directory under /var/cache/pbuilder/hook.d, then you should place the following in your ~/.pbuilderrc script.

HOOKDIR="/var/cache/pbuilder/hook.d/"

Then write a script under /var/cache/pbuilder/hook.d that will write the preferences file in your chroot. The script name must be of the form 'E<digit><digit><whatever else you want>'.

For example, a script can be saved to /var/cache/pbuilder/hook.d/E01apt-preferences and written like so.

#!/bin/sh
set -e

STABLE_VERSION_REGEX='^5\.0\.[0-9]\+$'

if $(cat "/etc/debian_version" | grep -q -e "$STABLE_VERSION_REGEX"); then
cat > "/etc/apt/preferences" << EOF
Package: debhelper
Pin: release a=squeeze-backports
Pin-Priority: 999

Package: lintian
Pin: release a=squeeze-backports
Pin-Priority: 999
EOF
fi

Note that the only packages specified here are debhelper and lintian. More can be specified, although these are two common ones to backport. You should keep packages that are backported for your pbuilder environment at a minimum.

Using the 'othermirror' option

It is possible to specify more mirrors than the one specified for MIRRORSITE. There's two ways to do this, specifiying the option '--othermirror "<sources.list deb line>"' when running pbuilder, or using the variable 'OTHERMIRROR="<sources.list deb line>"' in the pbuilderrc configuration file. Just replace "<sources.list deb line>" with a deb line in the same format as would be found under /etc/apt/sources.list.

Note: Don't forget to use --override-config and then pbuilder update to take the new repository into account.

Troubleshooting "pbuilder create"

Make sure that you have debootstrap later than X installed. The version from hardy will not suffice. Install from backports or backport yourself if necessary.

If you are running pbuilder < 0.196, then you will encounter this error when you try to create a base tarball for sid:

chroot: cannot run command `/usr/bin/apt-get': No such file or directory

This was fixed in pbuilder 0.196. To workaround this on older versions of pbuilder, you will need to add this line to your ~/.pbuilderrc

DEBOOTSTRAPOPTS=("--include=apt" "${DEBOOTSTRAPOPTS[@]}")

There will be sometimes where running sudo pbuilder create will fail to create a base tarball. This normally occurs only when creating base tarballs for development versions of Ubuntu or Debian (for example, Debian sid). These are development versions and it is best to wait and try at a later date to create a base tarball. It can be days however (sometimes weeks) until creating a base tarball will be successful for these development versions. In the meantime you could create a base tarball for an older version of Ubuntu or Debian and update the tarball to the development version instead.

For example, to create an etch base tarball and update to sid, start with:

sudo DIST=etch pbuilder create

Then to update, run:

sudo DIST=etch pbuilder update --override-config \
--othermirror "deb http://http.us.debian.org/debian sid main"

What will happen is that the base packages for Etch will be downloaded, installed, and configured first. Then apt-get update will be performed for "etch main" and "sid main". When the update is run, all packages in need of upgrading will be upgraded and thus, the base packages for Sid will be installed. After pbuilder is done, a base tarball will have been created but named for Etch (etch-base.tgz). All the base packages will be copied into the aptcache directory in /var/cache/pbuilder/etch. From here you can copy the aptcache directory over to the sid directory and make a copy of etch-base.tgz and call it sid-base.tgz.

sudo mkdir /var/cache/pbuilder/sid
sudo cp /var/cache/pbuilder/etch/aptcache /var/cache/pbuilder/sid/aptcache
sudo cp /var/cache/pbuilder/etch-base.tgz /var/cache/pbuilder/sid-base.tgz

It is better of course to create a base tarball directly. Check often to see if a base tarball can be created directly.

See also

pbuilder User's Manual

See the script pbuilder-dist in package ubuntu-dev-tools for an alternative way to use pbuilder with many different Ubuntu versions.


CategoryMOTU

PbuilderHowto (last edited 2020-01-28 13:36:36 by paelzer)