This page describes how to compile a backport in the "proper" way, one which tries to respect the rules for the backports.
This assumes you will build a backport that will be uploaded to the official backports repository. For simpler recipes, look for SimpleBackportCreation for your own informal backports or AutomateBackports for your own personal backporting archive.
Contents
Retrieve the Package Source
Backports for a release, for almost all cases, must be prepared from the subsequent release. There are multiple ways to retrieve a package source. A simple way is to use dget (from the devscripts package)` on the URL for the desired package's dsc file:
If you find your package listing by searching on https://packages.debian.org for the appropriate source distribution (Testing, in the case of Stable backports), you will see a link to its dsc file. The following command will retrieve the source package and extract it for you:
dget -x <url-of-dsc-file>
More efficient workflows for ongoing maintenance of the backport will make use of the maintainer's packaging VCS and/or dgit instead.
Modify the package as needed
To make a proper backport, you need to modify the package according to the rules. A simpler version:
Use stretch-backports, jessie-backports, wheezy-backports-sloppy or wheezy-backports as distribution and append ~bpo${debian_release}+${build_int} to the version number (consider using dch --bpo), e.g. 1.2.3-4 now becomes 1.2.3-4~bpo8+1 for jessie, 1.2.3-4~bpo7+1 for wheezy-backports-sloppy or 1.2.3-4~bpo70+1 for wheezy.
This is just a summary of the technical aspects of the rules. It is really important that you read up on the rules and follow them.
Build in a minimal environment
Using sbuild
Preparation for first use
The sbuild page provides guidance for setting up sbuild. Some backports-specific notes are mentioned here.
The Examples section of sbuild-createchroot(8) specifically shows how to create a chroot for the Stable release that also allows access to Stable-backports (which may be needed to fulfill dependencies in the backport you intend to prepare).
Building your backported package
From the top-level directory of the backported source package, you should be able to build as follows:
sbuild --build-dep-resolver=aptitude --debbuildopts="-v<last-main-version>"
Where <last-main-version> is the version of the most recent backport or Stable released version (as recommended in the Backports rules)
The aptitude build dependency resolver is needed in order to be able to pull packages from Stable-backports as needed (which will only happen if the build-dependencies cannot be met from Stable).
Building multi-dependency packages
If your package requires others to be backported first, you can build them as described above and then use them from your local file system without having to manually set up a temporary APT repository. Simply pass --extra-package <path-to-deb-file> in your call to sbuild.
Correct distribution name
The distribution field in the .changes file must be correct for the backports upload to process into the correct queue. For example, for bookworm this field must be bookworm-backports. Sbuild automatically populates this field with the name of the chroot, so it is important that the chroot have the correct name and not simply be something like bookworm or stable.
Using pbuilder
This section needs a major update, in its current state it has a lot of mistakes and thus currently isn't about official backports anymore.
Your first step is to configure pbuilder and, optionally, cowbuilder. The remaining of this howto will assume you will use cowbuilder, as this is what is in use here and is more efficient. We also like to use git-buildpackage to avoid building a .dsc file first, so to build straight from the source.
A full pbuilder or cowbuilder is beyond the scope of this manual, but there are specific issues you should not miss here. See git-pbuilder for details of use of cowbuilder/pbuilder with git-buildpackage.
Installing the toolchain
apt-get install cowbuilder pbuilder
Building for different distributions
Then enable pbuilder to build for different distributions easily, by following those instructions.
At this point you should be able to build a package using:
DIST=jessie ARCH=amd64 pbuilder build --debbuildopts "-sa -v1.0" foo.dsc
With git-buildpackage this becomes:
cd package DIST=buster ARCH=amd64 git-buildpackage --git-builder=git-pbuilder -sa -v1.0 # or DIST=buster ARCH=amd64 gbp buildpackage --git-builder=git-pbuilder -sa -v1.0
Note that this option can be written to your ~/.gbp.conf file as such: builder = /usr/bin/git-pbuilder.
Another example, with cowbuilder:
DIST=wheezy ARCH=i386 pdebuild --pbuilder cowbuilder --debbuildopts "-sa -v1.0"
Advanced: Building multi-dependency packages
At this point you are able to build and upload backports of existing packages easily. The tricky part comes up when you have multiple dependencies to upload at once. pbuilder chroots do not use packages from backports by default, so that's the first thing we need to fix. Add this to your pbuilderrc:
OTHERMIRROR="deb http://deb.debian.org/debian/ $DIST-backports main"
Then update the chroot with the new sources.list line:
sudo DIST=jessie ARCH=amd64 cowbuilder --update --override-config
Then you could build the packages one at a time: backport one, upload it, wait for it to show up in the backports archive, build the second one, etc. But this is really time consuming and could take a long time for big package suites. It could also mean a lot of dependent packages be uploaded to backports while the package that needs it is not there, which is bad practice.
What you need is to be able to use the packages you're building locally in the chroot. This is again described in the PbuilderTricks page, but we'll show our own way here.
Add this to your pbuilderrc:
OTHERMIRROR="deb http://deb.debian.org/debian/ $DIST-backports main|deb [trusted=yes] file:///home/anarcat/dist/build-area/ ./" HOOKDIR=/usr/lib/pbuilder/hooks BINDMOUNTS="/home"
The above assumes you are building your packages in /home/anarcat/dist/package and the build results end up in /home/anarcat/dist/build-area/. This can be freely changed, but it will only work if it is under the BINDMOUNTS.
Then you need to add a hook that will run apt-get update before the package is built, in /usr/lib/pbuilder/hooks/D90update:
/usr/bin/apt-get update
The HOOKDIR variable can be changed if you want to put your hook file somewhere else, but the file name is important.
Then the only bit missing is making sure the /home/anarcat/dist/build-area/ directory is a valid archive. Other howtos make that part of the hook, but since we are not running as root (see below), this is not practical for us. We simply use the following command on a as-needed basis:
dpkg-scanpackages . /dev/null | bzip2 -c > Packages.bz2
It is in the following makefile to make things easier:
all: Packages.bz2 Sources.bz2 Packages.bz2:: dpkg-scanpackages . /dev/null | bzip2 -c > Packages.bz2 Sources.bz2:: dpkg-scansources . /dev/null | bzip2 -c > Sources.bz2
Note that the above will fail because it's missing the SecureApt key. See AutomateBackports for another example which may resolve this.
Other tricks
We have found the following options to be useful in pbuilderrc:
PDEBUILD_PBUILDER="cowbuilder" BUILDUSERID="500" BUILDUSERNAME="anarcat-pbuilder" AUTO_DEBSIGN=yes
This is the ~/.gbp.conf (git-buildpackage config):
[DEFAULT] # tell git-buildpackage howto clean the source tree cleaner = fakeroot debian/rules clean postbuild = lintian $GBP_CHANGES_FILE # this is how we invoke pbuilder, arguments passed to git-buildpackage will be # passed to dpkg-buildpackge in the chroot builder = /usr/bin/git-pbuilder [git-buildpackage] export-dir = ../build-area/ [git-import-orig] dch = False
Self-contained example for Fossil 2
STABLE=stretch TESTING=buster # Prepare local repo mkdir -p /usr/src/backports/$STABLE/ touch /usr/src/backports/$STABLE/Packages cat <<EOF > /usr/src/backports/$STABLE/Release NotAutomatic: yes ButAutomaticUpgrades: yes Date: $(date -R -u) EOF cat <<EOF > /usr/src/backports/$STABLE/D70update #!/bin/bash # Take previous builds into account apt-get update EOF chmod 755 /usr/src/backports/$STABLE/D70update cat <<EOF > /usr/src/backports/$STABLE/I70scanpackages #!/bin/bash # Update repo after successful build cd /usr/src/backports/$STABLE/ dpkg-scanpackages . /dev/null > Packages EOF chmod 755 /usr/src/backports/$STABLE/I70scanpackages # Create initial environment sudo pbuilder --create --basetgz /var/cache/pbuilder/base-$STABLE-bpo.tgz \ --distribution $STABLE \ --othermirror "deb http://security.debian.org/ $STABLE/updates main|deb http://http.debian.net/debian $STABLE-backports main|deb [trusted=yes] file:///usr/src/backports/$STABLE ./" \ --bindmounts /usr/src/backports/$STABLE/ # Update regularly: # sudo pbuilder --update --basetgz /var/cache/pbuilder/base-$STABLE-bpo.tgz --bindmounts /usr/src/backports/$STABLE/ # Add source for 'apt source' echo "deb-src http://ftp.fr.debian.org/debian/ $TESTING main" \ | sudo tee /etc/apt/sources.list.d/$TESTING-src.list sudo apt update # Setup identity export DEBEMAIL="you@debian.org" export DEBFULLNAME="Your Name" # Configure build #export DEB_BUILD_OPTIONS="parallel=$(nproc) nocheck" export DEB_BUILD_OPTIONS="parallel=$(nproc)" # Create a working directory for sources mkdir /usr/src/backports/sources/ cd /usr/src/backports/sources/ # Dependencies to add in our local repo apt source sqlite3/$TESTING ( cd sqlite3-3.25.2/ dch --bpo "No changes." pdebuild --debbuildopts '-v3.16.2-5+deb9u1' \ --buildresult /usr/src/backports/$STABLE/ \ --pbuildersatisfydepends /usr/lib/pbuilder/pbuilder-satisfydepends-experimental \ -- --basetgz /var/cache/pbuilder/base-$STABLE-bpo.tgz \ --bindmounts /usr/src/backports/$STABLE/ \ --hookdir /usr/src/backports/$STABLE/ lintian -i ) # Fossil 2 itself apt source fossil/$TESTING ( cd fossil-2.8/ dch --bpo "Note: depends on backported sqlite3." pdebuild --debbuildopts '-v1:1.37-1' \ --buildresult /usr/src/backports/$STABLE/ \ --pbuildersatisfydepends /usr/lib/pbuilder/pbuilder-satisfydepends-experimental \ -- --basetgz /var/cache/pbuilder/base-$STABLE-bpo.tgz \ --bindmounts /usr/src/backports/$STABLE/ \ --hookdir /usr/src/backports/$STABLE/ lintian -i lintian -i /usr/src/backports/$STABLE/fossil_2.8-1~bpo9+1_amd64.changes ) # Test sudo --preserve-env=DEB_BUILD_OPTIONS pbuilder --login --basetgz /var/cache/pbuilder/base-$STABLE-bpo.tgz --bindmounts /usr/src/backports/$STABLE/ apt install fossil ... # Publish to official archive cd /usr/src/backports/$STABLE/ debsign xxx.changes -k YOUR_KEYID dput xxx.changes
If something goes wrong and you need to test manually:
sudo pbuilder --login --basetgz /var/cache/pbuilder/base-$STABLE-bpo.tgz --bindmounts /usr/src/backports apt update cd /usr/src/backports/sources/fossil-2.8/ apt install pbuilder devscripts fakeroot /usr/lib/pbuilder/pbuilder-satisfydepends-experimental debuild ...
Remember to subscribe to the packages in the Debian Package Tracker, so you get notified of new versions, especially security fixes!
Notes:
Not using cowbuilder, since it complexifies the commands, and since a few packages fail to build in hard-links corner-case situations 1
bookworm-backports
Two transitions in trixie/sid have a significant effect on backports and require special attention.
time64
In trixie and later, dpkg and gcc inject compiler flags causing the use of 64bit time types. Refer to ReleaseGoals/64bit-time for details. These flags are not injected in bookworm (nor bookworm-backports) or earlier. Therefore, a backport may unexpectedly break ABI.
If you backport a package that carries a t64 suffix. The package rename needs to be reverted for the backport. The *t64 packages in trixie/sid carry Breaks and Replaces that are compatible with such backports (as they use (<< ${source:Version})). However, renaming a package back to its previous form may interact with the /usr-move transition (see below).
If you backport a package that does not carry a t64 suffix, it may have lost a t64 suffix in an soname bump. If the library in question actually is affected by the time64 transition, the ABI of a backport may differ from the ABI in trixie on 32bit architectures. There are two ways to handle this situation. One option is to restrict the backport to 64bit architectures by adding a build dependency on architecture-is-64bit. The other is performing a different rename in your backport adding a t32 suffix. If you add such a suffix, the version in trixie and sid must declare Breaks and Replaces regarding these new t32 packages before uploading to bookworm-backports. As in the other case, package renames may interact with the /usr-move transition (see below).
/usr-move
In trixie, all files from aliased locations such as /bin, /lib and /sbin shall be moved to their corresponding location below /usr (UsrMerge). In bookworm (and bookworm-backports) such moves are not performed and forbidden by the file move moratorium issued by the CTTE. Therefore any file moves performed in trixie must be reverted when doing a backport. If the package in question does not ship any files below /bin, /lib and /sbin in both bookworm and trixie, this section can be ignored. Additionally, any mitigations for problems caused by /usr-move must be reverted. Some mechanisms have been implemented in a way that is safe for backports use:
dh-sequence-movetousr / dh_movetousr: This sequence addon and helper has been ported to bookworm-backports such that it will not actually perform any move in bookworm-backports. It can be kept and will automatically turn itself into a noop.
dh_installsystemd / dh_installudev: The installation location for systemd units and udev rules has been changed for trixie. When backporting a package, such units will automatically move back to the aliased locations. Note that this does not apply to files installed using dh_install or an upstream build system.
pkg-config files systemd and udev: The pkg-config files for systemd and udev identify the location for units and rules respectively via variables systemdsystemunitdir and udevdir. A number of upstream build systems rely on these variables to determine the installation location. When performing a backport, relying on these will work, but files may additionally be listed in debian/*.install and may need to be updated there.
A number of /usr-move mitigations rely on Breaks or Conflicts declarations. As such it may be necessary to update the version constraint in unstable when performing a backport. Since backports incur new upgrade paths, these may also come with /usr-move problems that did not exist at all earlier. Therefore, some packages such as glibc, base-files, cryptsetup, isc-dhcp, or molly-guard should not be backported to bookworm-backports at all. If in doubt, please request assistance from DEP17 transition drivers e.g. via irc.oftc.net channel #debian-usrmerge or by contacting them via email.
Uploading the backport
Use dput (≥ 0.9.6.3+nmu2), dput-ng or dupload to upload the resulting package (just like a regular package upload).
See also
PackagingWithGit - git-buildpackage and friends
Backports - the backports user documentation
SimpleBackportCreation - your own unofficial backports
Backports guide by gitlab maintainers - covers best practices when the package is maintained in git and its complementary video tutorial/demo
AutomateBackports - more elaborate: your own unofficial backport archive
The original trick of how to automatically adding dependencies to the pbuilder chroot