As a follow-up to the previous Debian packaging article, here is a second go at documenting for future me a couple more obscure concepts around building custom packages.
So today I learned how to create virtual
For those unaware, Debian has a way for packages to state that they satisfy
more than just a single package name. In the canonical example, there are
dozens of packages that can fill the generic dependency of
konquoror. When a package doesn’t
particularly care which specific browser is used, just that there is one, they
can specify a dependency on
www-browser and allow the user to pick the
browser of their choice. The actual browser package has a section in the config
file that lists the virtual packages that it provides, in this case
www-browser iceweasel gnome-www-browser. You can easily view what
virtual packages a package provides using
$ apt-cache showpkg firefox Package: firefox Versions: 52.0.2+build1-0ubuntu0.12.04.1 [...] Provides: 52.0.2+build1-0ubuntu0.12.04.1 - www-browser iceweasel gnome-www-browser
You can get a list of packages that provide a virtual package, shown in the
Reverse Provides section, in the same way:
$ apt-cache showpkg www-browser Package: www-browser [...] Reverse Provides: w3m 0.5.3-5ubuntu1.2 chromium-browser 18.0.1025.151~r130497-0ubuntu1 konqueror 4:4.8.2-0ubuntu2 firefox 11.0+build1-0ubuntu4 [...]
Virtual packages are quite a powerful concept and allow for a significant amount of flexibility in building packages, a single package can supersede a handful of individual packages, without breaking backwards compatibility with older dependant projects.
I also had the pleasure of having to actually understand what the hell the
strings that pass for Debian package version numbers mean. Debian
goes into the full details, but a quick overview wouldn’t hurt. The part of the
version string that burned me this time was the
Take the version string from the Ubuntu 14.04 package for
1:1.6.1-6ubuntu1. This breaks down into
epoch; upstream-version; debian-revision or
1; 1.6.1; 6ubuntu1. Epoch is this fun modifier that
allows the maintainer to basically reset the version numbers, by ignoring
anything of a lower epoch. Epoch defaults to
0 when not provided, so version
numbers are evaluated as expected.
If there is a major mishap in releases and the version numbers are beyond
recovery, the maintainer can increment the epoch version and essentially start
1:1.0 evaluates as newer than
3.1.4 (implied 0 epoch so 0:3.1.4). At
a glance, without domain specific knowledge, this can lead to quite interesting
results when trying to figure out what version should be installed.
All in all, I feel like I have a better grasp of packaging as a whole from this experience, not just with Debian, but also the details that plague anyone attempting to maintain a consistent experience for downstream consumers.