Building a .deb package
Starting off, wishing you all a Happy New Year 5020 (gatakali 5019)!
This is a tutorial-for-the-impatient about building .deb packages, meant for installing locally (e.g. your own computer). There are many third-party helpers like checkinstall or fpm, but we’re going to use the same tools used by Debian package maintainers. If you want your deb to be included in the official Debian archive, it needs to be more rigorous and thorough. For a local install, we can be a little flexible. Familiarity with these will help you become a Debian Developer some day :)
As an example, we’re going to consider GNU Stow. It’s a neat Perl tool to keep your home directory clean and under a version control system. A couple of years ago, Debian sid had version 2.2.0 but upstream had released 2.2.2 already, so we’re going to package it.
tl;dr:
debmake --revision 0~local1 --invoke debuild
Debianization
First step is to “debianize” the upstream sources. We’re going to use debmake
(dh_make
is similar but older one, but works too. And not to be confused with
deb-make
which is deprecated and removed from Debian).
wget https://ftp.gnu.org/gnu/stow/stow-2.2.2.tar.gz
tar xf stow-2.2.2.tar.gz
cd stow-2.2.2/
debmake
works especially well if the upstream is a well-behaved source, such
as GNU software. As a trial run:
./configure
make
If there are errors in either of the above steps, you likely have some packages
missing. Just apt-get install
them as needed. Luckily, Stow doesn’t need
anything more than a recent Perl installation. Run make clean
before you go
on. We need a few environment variables, which I hope are self-explanatory:
export DEBFULLNAME="Anamika Asok"
export DEBEMAIL="asok@example.com"
You might want to quickly read man debmake
to familiarize with the
overall options. We’re going to need these:
-j, --judge
run dpkg-depcheck to judge build dependencies and identify file paths.
-b --binaryspec "binarypackage[:type],..."
type "perl" implies a Perl script package
-r, --revision "rev"
set the Debian package revision.
Using -j
generates a stow.build-dep.log
which lists all the build-time
dependencies needed to compile the package. You can just apt-get install
them,
if needed. Switch -b
takes values like perl, python, bin, lib, etc. which
adjusts certain Debian packaging variables. If you leave it out, debmake
will
usually make a pretty good guess.
Debian Revision
Choosing the correct Debian revision (-r
) is very important. Most likely,
Debian would release an official stow-2.2.2
later and we want to
upgrade to it instead of keeping our local install. Revision number helps in
this smooth upgrade path. There are strict rules about versioning, but I’ll
try to summarize.
Most Debian packages are of the form X.Y.Z-N
where everything before the
hyphen is the upsteam_version and after hyphen is the debian_revision. In
our case X.Y.Z = 2.2.2
. The Debian revision number N
is usually single
digit, incremented by the package maintainer, starting from 1
. We want our
revision number to lower than official Debian’s, so N = 0
is good. We can compare
whether two versions are less than (lt
) or greater than (gt
), thus:
╭── dpkg --compare-versions 2.2.2-0 lt 2.2.2-1 && echo true
╰─▷ true
If the revision number is omitted (usually for Debian’s infrastructure packages
like build-essential
or debianutils
), it’s taken as zero. X.Y.Z
is same as
X.Y.Z-0
. This collides with our choice of N = 0
above. Oops! We want
something which sorts “less than zero”. And that is tilda (~
). Think of ~
as
a minus sign, like a negative number.
╭── dpkg --compare-versions 2.2.2-0~ lt 2.2.2 && echo true
╰─▷ true
If there’s a minus sign, there’s gotta be a plus sign (+
):
╭── dpkg --compare-versions 2.2.2 lt 2.2.2-0+ && echo true
╰─▷ true
In short, 2.2.2-0~ < 2.2.2-0 (=2.2.2) < 2.2.2-0+
.
If we ourselves are building stow-2.2.2
many times, let’s call our successive
packages as local1
, local2
, etc.
In short, since we want our package to have as low version number as possible, a good choice would be:
--revision 0~local1
Usually “~yourname” is used for a backport and “+yourname” for a recompile.
“recompile” (e.g. binary NMU), means a package was recompiled without changing the source. This often occurs when one of the libraries a package depends on has changed, and it needs to be recompiled against the newer library. The debian_revision normally will be +b1 (+b2 etc).
“backport” means a “recompile” but from higher Debian release to a lower Debian release (e.g. sid -> testing or testing -> stable).
Invoking debmake
This is easy:
debmake --judge --revision 0~local1 -b":perl"
The output lines starting with I:
are info, W:
are warnings and E:
are
errors. This generates a directory called debian/
. This process is hence
“debianization”.
tree debian/
├── changelog
├── compat
├── control
├── copyright
├── patches
│ └── series
├── README.Debian
├── rules
:
:...
debian/rules
is a separate topic in itself. In essence, it’s a just a Makefile
which fulfils certain make targets (like build
, clean
, install
etc.). See
maint-guide for more.
Editing control and changelog
Edit debian/control
. Change Section: manual, Priority: extra, and add a
suitable description.
:
...
Section: manual
Priority: extra
Homepage: https://www.gnu.org/software/stow/
...
Description: software package installation manager
GNU Stow is a tool for managing the installation of multiple
software packages in the same run-time directory tree.
.
The approach used by Stow is to install each package into its
own tree, then use symbolic links to make it appear as though
the files are installed in the common tree.
Debian package priorities are sorted as required > important > standard >
optional > extra
.
Add a new changelog entry in debian/changelog
. Keep it as UNRELEASED since
we’re not going to publish it in testing
or unstable
.
stow (2.2.2-0~local1) UNRELEASED; urgency=low
* Initial release. Built from pristine upstream sources.
-- Anamika Asok <asok@example.com> Thu, 21 Jan 2016 22:30:17 +0200
You can manipulate changelog entries with dch -i
.
Building the package
No need of -uc -us
since UNRELEASED
. nocheck
will skip running make test
or make check
.
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage
This generates:
../stow_2.2.2-0~local1_all.deb
../stow_2.2.2-0~local1_amd64.changes
../stow_2.2.2-0~local1.dsc
Info about the package (note uppercase -I
):
dpkg -I ../stow_2.2.2-0~local1_all.deb
You can list the contents of the deb:
dpkg -c ../stow_2.2.2-0~local1_all.deb
And, install it, finally (lowercase -i
, phew!):
sudo dpkg -i ../stow_2.2.2-0~local1_all.deb
You can remove the package with dpkg -D
or apt-get purge stow
.
Going further (optional)
Use -i
(--invoke
) to build the package right after debianization (but
without editing debian/changelog
etc.)
debmake --judge --revision 0~local1 -b":perl" -i dpkg-buildpackage
You can sign *.dsc
and *.changes
files using your PGP key (4096-bit RSA
recommended, as of today).
export DEBSIGN_KEYID=1234ABCD
debsign ../stow_2.2.2-0~local1.dsc
debsign ../stow_2.2.2-0~local1_amd64.changes
debsign picks the correct signing key from GPG keyring based on the “Maintainer”
line in debian/control
, even if DEBSIGN_KEYID
is defined. Anyways, you can
force a different key with -k ABCD1234
.
Lintian is a tool to check the .deb for conformance to Debian policy.
lintian -EviI ../stow_2.2.2-0~local1_all.deb
Simplified, debuild
runs dpkg-buildpackage + linitian
in a clean way by
sanitizing environment variables, etc. Highly prefereable than just running
dpkg-buildpackage
.