How to use multiple upstream tarballs in Debian source packages?

Since the introduction of the “3.0 (quilt)” source format, it is now possible to integrate multiple upstream tarballs in Debian source packages. This article will show you how to do the same with your own package shall you need it. It’s quite useful to easily integrate supplementary plugins, translations, or documentation that the upstream developers are providing in separate tarballs.

Step by step explanation

We’ll take the spamassassin source package as an example. The upstream version is 3.3.1. The main upstream tarball is named as usual (spamassassin_3.3.1.orig.tar.gz) and contains the top directory of our source package. We already have a debian directory because the package is not new.

Upstream provides spamassassin rules in a separate tarball named Mail-SpamAssassin-rules-3.3.1.r901671.tgz. We grab it, rename it to spamassassin_3.3.1.orig-pkgrules.tar.gz and put it next to the main tarball. The “pkgrules” part is the component name that we choose to identify the tarball, it’s also the name of the directory in which it will be extracted inside the source package. For now that directory doesn’t exist yet so we must create it.

$ mv Mail-SpamAssassin-rules-3.3.1.r901671.tgz spamassassin_3.3.1.orig-pkgrules.tar.gz
$ cd spamassassin-3.3.1
$ mkdir pkgrules
$ tar -C pkgrules -zxf ../spamassassin_3.3.1.orig-pkgrules.tar.gz

This is already enough, the next time that you will build the source package, the supplementary tarball will be automatically integrated in the generated source package.

$ dpkg-buildpackage -S
 dpkg-source -b spamassassin-3.3.1
dpkg-source: info: using source format `3.0 (quilt)'
dpkg-source: info: building spamassassin using existing ./spamassassin_3.3.1.orig-pkgrules.tar.gz ./spamassassin_3.3.1.orig.tar.gz
dpkg-source: info: building spamassassin in spamassassin_3.3.1-1.debian.tar.gz
dpkg-source: info: building spamassassin in spamassassin_3.3.1-1.dsc

The supplementary tarball is now part of the source package but we’re not making anything useful out of it. We have to modify debian/rules (or debian/spamassin.install) to install the new files in the binary package.

A special case: bundling related software

In very rare cases, you might want to create a bundle of several software (small perl modules for example) and you don’t have any main tarball, you only have several small tarballs. Rename all the tarballs following the same logic as above and when building the source package you can ask dpkg-source to create an empty (and fake) main archive for you with the option --create-empty-orig:

$ dpkg-buildpackage -S --source-option=--create-empty-orig

Use with care as the version number you give to the bundle is what users will see and it’s likely unrelated to the version number of each individual software.

Common mistakes

Forgetting to extract the supplementary tarball

If you forget to extract the content of the supplementary tarball in the pkgrules directory, dpkg-source will emit lots of warnings about those files being deleted. In fact, you did not delete them but you only forgot to create them in the first place.

dpkg-source: warning: ignoring deletion of directory pkgrules
dpkg-source: warning: ignoring deletion of file pkgrules/
dpkg-source: warning: ignoring deletion of file pkgrules/

Using a bad version number for the supplementary tarball

Sometimes the supplementary tarball has a version of its own that does not match the upstream version. You must still name the file in a way that matches the upstream version of the main tarball otherwise it will not be picked up by dpkg-source and it will generate a new patch in debian/patches/ containing the whole new directory.

It’s possible to encode the version number of the supplementary tarball in the component name (in our example above we could have picked “pkgrules-r901671” as component name) but this means that the name of the associated directory will regularly change and you must adapt your packaging rules to cope with this.

However this last trick has the benefit of being able to update the additional tarball without bumping the upstream version. A sourceful upload of a new revision of the package will be accepted by the archive: the main tarball is ignored since it’s unchanged but the supplementary tarball is taken since it’s a new file for the archive (it has a different filename).

Be sure to move away old versions of the additional tarball when you do that if you don’t want to upload several versions of the same tarball by mistake!

Misextracting the supplementary tarball

dpkg-source is very smart when it extracts the supplementary tarball and you should be as well when you manually extract it.

If the tarball contains only a single top-level directory, that directory is extracted, renamed to match the component name and moved in the source package directory.
If the tarball contains several top-level files or directories, then the target directory is first created and the content of the archive is directly extracted into that directory.

Here are commands to install the files in both cases (we’re already in the source package directory):

$ mkdir pkgrules
# Archive contains a single top-level directory
$ tar -C pkgrules --strip-components=1 -zxf ../spamassassin_3.3.1.orig-pkgrules.tar.gz
# Archive contains many top-level entries
$ tar -C pkgrules -zxf ../spamassassin_3.3.1.orig-pkgrules.tar.gz