Packaging scripts
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

How to make a Debian binary package

Read all the instructions before you begin. This will cover building packages and maintaining the repository. It won't explain how Debian packages are/should be built (see the Debian Policy Manual), how the various tools work, how the Mercury build system works or how GPG keys should be managed; all that can be found elsewhere.

Setup the tools

You will need some Debian tools to make Debian packages.

apt install build-essential devscripts pbuilder fakeroot dput

And if you plan to maintain the repository, then also install

apt install reprepro rsync

Investigate each of the files in debian_conf and install them or their contents as necessary.


Copy the contents of bashrc into your ~/.bashrc file, modify it as necessary to set your name and e-mail address. The dquilt alias works with .dquiltrc-dpkg below.


Quilt is a tool for managing a series of patches. It's used to patch the source for a package before building it, to fix any bugs, apply backports etc.

Configuration file used with the dquilt alias for the quilt patch management tool. This simply configures quilt for use with debian packages, by providing some sensible defaults. The 'd' in 'dquilt' is for Debian.


pbuilder is a "Personal Builder" it is used to build debian packages in a chroot, ensuring that they can be built cleanly & don't have any extra dependencies.

This file can be coppied to ~/.pbuilderrc more-or-less verbatim, but read it anyway and get a sense for what it can do, particularly since it's a shell script! Set the username, any distribution codenames that may have changed since I wrote this, and your mirror sites.

You may need to create some directories in /var/cache/pbuilder. Particularly the hooks and result directories. If you get errors later come back to this step and add any required directories. TODO: update these docs to say exactly what is necessary.

Copy C10shell into /var/cache/pbuilder/hooks The C hooks are executed if a build fails, you can use them, for example this one, to determine why the build failed.


pbuilder (normally) needs sudo access, but it also needs access to some environment variables. Edit your sudoers file. Remeber to use the visudo command.

sudo visudo

Add to the Command alias section:

Cmnd_Alias  PBUILDER = /usr/sbin/pbuilder, /usr/bin/pdebuild, /usr/bin/debuild-$
Defaults!PBUILDER       env_keep+="DIST ARCH"

And add to the user privilege specification section:

# User privilege specification

Change "paul" to your username.

Don't make a mistake and get locked out of sudo access.

Setup chroots

Setup any chroots you need.

ARCH=amd64 DIST=jessie sudo pbuilder --create

Hopefully you have an amd64 system, which means you can build either amd64 or i386 packages and chroots.

Setup dput

Depending on whether you're maintaining the Mercury repository, or just building packages and sending them to someone else you'll want to use a different dput configuration. I've included my ~/ which assumes I'm maintaining the repository myself over a local NFS mount. Copy it and edit the path or else check the manual and write your own configuration.

Each stanza refers to a repository. Right now there is only one, mercury-stable, I plan to add mercury-snapshot in the future.

Build packages

Download a Mercury srcdist tarball, extract it and rename the root directory to give it a sensible name. Then tar it back up again with the new special name. Normally you can simply move a tarball to the correct name, but the Mercury tarballs include "srcdist" in the name, and we don't want that in the package name so we remove it.

tar -zxf mercury-srcdist-14.01.1.tar.gz
mv mercury-{srcdist-,}14.01.1
tar -zcf mercury_14.01.1.orig.tar.gz

Copy the debian directory from this repository into place.

cp -r packaging/debian mercury-14.01.1/debian

Build the source package

dpkg-source -b mercury-14.01.1

Use this to build a new source package and binary packages for amd64.

ARCH=amd64 DIST=jessie sudo pbuilder build mercury_14.01.1-1.dsc 

A new source package is used, because now the .changes file generated by this step will refer to its checksum. It can be uploaded in the same step.

Note: If you want to practice on some other software with a much shorter build time, try the "hello" package. You can get its source package with:

apt-get source hello

Sign and upload these packages

pushd /var/cache/pbuilder/result/
debsign mercury_14.01.1-1_amd64.changes
dput mercury-stable mercury_14.01.1-1_amd64.changes

mercury-stable is the name of the package repository to send the package to. Note that the command doesn't say which distribution within the repository to add it to. It figures this out from the changelog file within the source package that created these packages.

Use the newly generated source package, replacing the one generated in the first step. This is needed so that the .changes file for the i386 packages contains the right hash for the source package. The --binary-arch option tells it not to regenerate the source or architecture independent packages.

cp /var/cache/pbuilder/result/mercury_14.01.1-1.dsc \
    /var/cache/pbuilder/resxult/mercury_14.01.1-1.debian.tar.xz .
ARCH=i386 DIST=jessie sudo pbuilder build --binary-arch mercury_14.01.1-1.dsc 

Sign and upload these packages.

pushd /var/cache/pbuilder/result/
debsign mercury_14.01.1-1_i386.changes
dput mercury-stable mercury_14.01.1-1_i386.changes

Bumping the version number

If you've made changes to the debian packages, either by updating the upstream version or by adding patches via dquilt, then bump the version number. You'll need to change debian/changelog, but also debian/control and the version patch (in dquilt).

Generally the sid release should get the "root" version number and other releases, such as jessie, are backports of this version and hence have "jessieN" at the end.

Update the repository

To setup the repository the first time: The repository is setup by creating a base directory and copying the files The basedir is found by the REPREPRO_BASE_DIR variable in my .bashrc from debian_conf/reprepro/ into a conf/ subdirectory. Also create an incoming and temp directories. When you first use the repository (after the first processincoming) then you may also need to execute:

reprepro export
reprepro createsymlinks

dput will put package files into the incoming directory, mercury is the name of the repository to use (from ~/

dput mercury new_package.changes

The command

reprepro processincoming mercury

Will process these files adding them to the repository and rebuilding indexes. gpg will prompt you to resign the updated Release files. Because of the need for gpg signing this must be run locally, this is why we do not run it on deimos and instead it runs on my workstation. (Unless we had a shared key and such).

I rsync the local copy onto the webserver:

rsync -av --del --exclude db --exclude incoming --exclude temp \
    --exclude conf --exclude lists deb/ deimos:/srv/dl1/deb/

The excluded files simply don't need to be shared. Likewise if I were sharing this over HTTP (this is how dl2 is configured) I would need to exclude these files in my apache configuration.

How to make an RPM binary package

Download a Mercury srcdist tarball into ~/rpmbuild/SOURCES (or similar), then run:

make_rpm ~/rpmbuild/SOURCES/mercury-srcdist-VERSION.tar.gz

You can customise the grades in mercury-compiler.spec.