Current experiments are done in Debian unstable. We maintain a set of modified packages needed to make other packages reproducible. These packages allow to conduct experiments and test modifications locally or in our continuous integration platform. The goal is to get our changes accepted by the respective maintainers after proving them bug-free and fruitful.

APT repository

Our modified packages can be found in the following APT archive, which is signed by 49B6 5747 36D0 B637 CC37 01EA 5DB7 CA67 EA59 A31F:

deb http://reproducible.alioth.debian.org/debian/ ./
deb-src http://reproducible.alioth.debian.org/debian/ ./

Git repositories

Several Git repositories have been created on Alioth. Commit notifications are sent to a dedicated mailing list.

Straightforward patches — or packages not using Git as their version control system — have often been sent directly through the BTS.

Modified packages

The following packages have been modified to enable reproducible builds of other packages:

debhelper

The pu/reproducible_builds debhelper branch in the reproducible project contains several fixes and calls dh_strip_nondeterminism (see below) will be called before dh_compress in dh. See the changelog for details.

dpkg

The pu/reproducible_builds dpkg branch in the reproducible repository makes:

  1. file order deterministic in control and data part of the .deb,
  2. uses a single timestamp for .deb ar members
  3. preset the aforementioned timestamp to the latest changelog entry
  4. add -Wdate-time as part of CPPFLAGS in dpkg-buildflags

  5. add support for .buildinfo files

strip-nondeterminism

strip-nondeterminism is a post-processing tool that will normalize various file types. dh_strip_nondeterminism will be run by debhelper at the end of the build process.

cdbs

The pu/reproducible_builds cdbs branch in the reproducible project contains a fix for 764478 which makes cdbs call the newly introduced dh_strip_nondeterminism commands.

javatools

The pu/reproducible_builds javatools branch in the reproducible repository changes javahelper to call jh_installlibs after dh_install. See 764988.

discount

discount needs a patch to produce stable output of email addresses. See 762622 and the pu/reproducible_builds branch.

ghc

The pu/reproducible_builds ghc branch in the reproducible repository changes ghc to not include timestamps in interface hashes. See 769893

python-setuptools

python-setuptools needs a patch to write names top_level.txt in a stable order. See 773969

r-base

r-base needs a patch to use the latest entry in debian/changelog as build time. See 774031

fontforge

fontforge needs a patch to propagate creation and modification times from source file. See 774148 and the pu/reproducible_builds branch.

python-qt4

python-qt4 needs a patch to remove timestamps from generated files. See 774509

pyqt5

pyqt5 needs a patch to remove timestamps from generated files. See 774510

libxslt

libxslt needs a patch to make generate-id() return identifiers in a deterministic way. See the pu/reproducible_builds branch.

libmodule-build-perl

libmodule-build-perl needs a patch to output data in a stable order. See pu/reproducible_builds branch and 774869.

libextutils-depends-perl

libextutils-depends-perl needs a patch to output data in a stable order. See 775678.

python-support

python-support needs a patch to sort file lists in /usr/share/python-support/*.private. See 775786

Usage example

If you have a pbuilder already setup, it's fairly easy to setup an environment with the custom toolchain:

## for pbuilder
sudo cp /var/cache/pbuilder/base.tgz /var/cache/pbuilder/base-reproducible.tgz
sudo pbuilder --login --save-after-exec --basetgz /var/cache/pbuilder/base-reproducible.tgz
## for cowbuilder
sudo cowbuilder --create --distribution sid --basepath /var/cache/pbuilder/base-reproducible.cow
sudo cowbuilder --login --save-after-exec --basepath /var/cache/pbuilder/base-reproducible.cow
## then, for both:
echo 'deb http://reproducible.alioth.debian.org/debian/ ./' > /etc/apt/sources.list.d/reproducible.list
apt-get install busybox
busybox wget -O- http://reproducible.alioth.debian.org/reproducible.gpg | apt-key add -
apt-get purge busybox
apt-key fingerprint | grep '49B6 5747 36D0 B637 CC37  01EA 5DB7 CA67 EA59 A31F' || { echo 'Something is wrong' && exit 1; }
apt-get update
apt-get upgrade
exit 0 # exit the pbuilder/cowbuilder login shell

Once that's done, two options:

  1. Use the prebuilder script from the misc.git repository.

  2. Manually, through the following process:

apt-get source --download-only acl
mkdir b1 b2
sudo DEB_BUILD_OPTIONS=nocheck pbuilder --build --debbuildopts '-b' --basetgz /var/cache/pbuilder/base-reproducible.tgz acl_*.dsc
dcmd cp /var/cache/pbuilder/result/acl_*.changes b1
sudo dcmd rm /var/cache/pbuilder/result/acl_*.changes
sudo DEB_BUILD_OPTIONS=nocheck pbuilder --build --debbuildopts '-b' --basetgz /var/cache/pbuilder/base-reproducible.tgz acl_*.dsc
dcmd cp /var/cache/pbuilder/result/acl_*.changes b2
sudo dcmd rm /var/cache/pbuilder/result/acl_*.changes

(for cowbuilder, change pbuilder to cowbuilder, --basetgz to --basepath and $path.tgz to $path.cow.

debbindiff is useful to check the result:

debbindiff --html $output_file b1/*.changes b2/*.changes

Adding a package to the APT archive

On alioth.debian.org:

  1. Import the private signing key to your keyring, if you haven't already: gpg --import /home/groups/reproducible/private/reproducible-private.gpg

  2. Place the package files in /home/groups/reproducible/htdocs/debian/

  3. Run make from that directory.