First Debian Package
Thu 14 January 2016In this post we learn how to create our first Debian package. We get lost in the maze of Debian documentation available out there. We try not to fall asleep reading these endless pages. And finally we succeed creating a simple yet beautiful Debian package.
PNMixer is being packaged here, as it's a project I'm working on, and it's indeed my first Debian package.
References
The most complete piece of information out there is the Debian New Maintainers' Guide. If you're a noob like me, you'd better take some time to read it. I refer to it often in this post.
We also use a little bit of the Debian Policy Manual.
The Overview of Debian Maintainer Tools can be a good reading.
I also found a good tutorial at this address, it's quick but there are every steps you need:
How to create debian package from source
Installing stuff
We're gonna use dh_make
(dh stands for Debian helper) to make the package.
Beware of the tricky naming, the package name has an hyphen while the binary has an underscore.
apt-get install dh-make
To package a software that uses autotools, we will need dh-autoreconf
.
apt-get install dh-autoreconf
We will also need plenty of other utilities, and they all come from the devscripts
package.
apt-get install devscripts
To check the package for errors, we will use lintian
.
apt-get install lintian
Creating the package skeleton
Before using dh_make
we may define some environment variables. dh_make
will pick them up,
and use them automatically, making our task easier. You can even add that to your .bashrc
if you feel like packaging often.
export DEBEMAIL='your@mail.com'
export DEBFULLNAME='Your Name'
OK, so now, let's grab the archive of the software we're packaging.
wget https://github.com/nicklan/pnmixer/releases/download/v0.6/pnmixer-0.6.1.tar.gz
Unpack it, enter the directory:
tar -xzf pnmixer-0.6.1.tar.gz
cd pnmixer-0.6.1
Then create the package skeleton.
dh_make --copyright gpl3 -f ../pnmixer-0.6.1.tar.gz
Here, you just have one question to answer: the type of package.
A quick man dh_make
will give you hints. For PNMixer, the package type is "single binary".
dh_make
created a debian
sub-directory: this is the skeleton, holding all the files needed to
build the package. You can have a look at it, don't be shy.
ls debian
But also (and that's a little bit unusual), dh_make
created some files in the parent directory.
$ ls -1 ..
pnmixer-0.6.1
pnmixer_0.6.1.orig.tar.gz
pnmixer-0.6.1.tar.gz
You have to get used to that, because that's the way the Debian helpers work. So you'd better have a clean parent directory, otherwise you'll be confused quickly. Just for you to know, the package will end up here after it's built.
OK, now let's start the real job: edit the skeleton files created by dh_make
.
The control file
References: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#control.
At first, the most important: read the doc I just mentioned :) Then, you can
safely edit the control
file:
vi debian/control
Start by filling the obvious fields, like Maintainer
or Homepage
.
Uncomment the VCS-*
fields if you intend to submit your package to Debian.
To fill the Section
, have a look at the Debian list of sections.
It's all easy to fill, except for the field Build-Depends
.
As you can see, it is already populated with a few things:
debhelper
because we're building the package using Debian helpers.autotools-dev
because PNMixer uses the autotools.
build-essential
is not mentioned, but it is implicit for binary packages.
It is mentioned here
and here.
At first, if the package uses autoreconf
, it is recommanded to use dh-autoreconf
instead
of autotools-dev
. It is not clear in the documentation, but I was told to do so by a
reviewer of my package. Then I found the Debian Autoreconf Wiki page,
where everything is explained.
OK, so good-bye autotools-dev.
sed -i 's/autotools-dev/dh-autoreconf/' debian/control
Now we must add the other dependencies of our package. Libraries are probably easy to figure if you know well the program you're packaging. But the exact list of build tools needed is more complicated than it seems.
Indeed, what exactly implies build-essential
? And dh-autoreconf
?
build-essential
apt-cache show build-essential
outputs an interesting line:
the real definition is in the Debian Policy Manual.
OK, where's the Debian Policy? I googled it, and after digging a little bit, here is the info we're after: https://www.debian.org/doc/debian-policy/ch-source.html#s-pkg-relations
The required packages are called build-essential, and an informational list can be found in /usr/share/doc/build-essential/list (which is contained in the build-essential package).
Alright, let's have a look at the file!
vi /usr/share/doc/build-essential/list
From what I understand, it contains make
, gcc
and libc6-dev
(the C standard library).
dh-autoreconf
From the wiki page mentioned above:
In general dh-autoreconf is a superset of autotools-dev...
Ok, so let's try to know more about autotools-dev
.
apt-cache show autotools-dev
is our friend in this matter, let me quote it:
It also documents in /usr/share/doc/autotools-dev/README.Debian.gz best practices and guidelines for using autoconf, automake and friends on Debian packages. This is a must-read for any developers packaging software that uses the GNU autotools, or GNU gettext.
OK, let's go there:
vi /usr/share/doc/autotools-dev/README.Debian.gz
It's a big piece of writing, that I barely read to be honest.
But from my average knowledge of what are the autotools, I assume it
provides autoconf
, automake
and gettext
.
what's missing then?
Alright, after this little hide & seek game through the documentation,
let's get back to our matter. What other build tool do I need for my package?
Answer is: pkg-config
and intltool
. I believe there not implied by any of
the dependencies we just went through, so I wrote them down.
libraries
Figuring out the libraries you package need may be easy if it's a little piece
of software and you know it well. A quick look at the autoconf.ac
should tell
you the truth. For PNMixer, I could write the libraries needed without the need
of any tool.
However, being curious, I gave a try to dpkg-depcheck
, as suggested by the Debian manual.
pkg-depcheck -d ./configure
The output is rather... crowded. It's difficult to pick up the right things in such a long list. So, I don't know if there a better tool for the job, but I was not really convinced by this one.
The final control file
Source: pnmixer
Section: sound
Priority: optional
Maintainer: My Name <my@name.com>
Build-Depends: debhelper (>= 9), dh-autoreconf, pkg-config, intltool,
libasound2-dev, libglib2.0-dev, libgtk-3-dev (>= 3.6), libnotify-dev, libx11-dev
Standards-Version: 3.9.6
Homepage: https://github.com/nicklan/pnmixer
Vcs-Git: git://anonscm.debian.org/collab-maint/pnmixer.git
Vcs-Browser: https://anonscm.debian.org/gitweb/?p=collab-maint/pnmixer.git;a=summary
Package: pnmixer
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Simple mixer application for system tray
PNMixer is a simple mixer application designed to run in your system tray.
It integrates nicely into desktop environments that don't have a panel that
supports applets and therefore can't run a mixer applet. In particular it's
been used quite a lot with fbpanel and tint2, but should run fine in any
system tray.
.
PNMixer is designed to work on systems that use ALSA for sound management.
Any other sound driver like OSS or FFADO, or sound server like PulseAudio
or Jackd, are currently not supported (patches welcome).
The copyright file
References: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#copyright
OK! Now it's time to take care of the copyright
file. Read the doc mentioned above,
then edit the file and add what's missing.
vi debian/copyright
Don't forget to read the comments at the end of the file, and remove it afterward.
The changelog file
References: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#changelog
Easy to setup, just stick to the syntax and you'll be fine. Here's my changelog as an example:
pnmixer (0.6.1-1) unstable; urgency=low
* Initial release (Closes: #745669)
-- My Name <my@name.com> Sun, 06 Dec 2015 19:18:02 +0700
The bug number here is the ITP (Intent To Package) bug number. It makes sense if you want your package to make it to Debian upstream, and therefore follow the procedure for package submission.
The rules file
References: https://www.debian.org/doc/manuals/maint-guide/dreq.en.html#rules
As you can see, this is a Makefile (hopefully you're familiar with the syntax).
You can remove the rules.dh7
file, which is the same as rules
.
Then, edit the rules
file. You can remove everything that's not needed,
ie every comment line, to make the file more readable. I was told by a reviewer
to remove also the two uncommented lines, so in the end there's nothing
left in the file, except the build rule.
Now, you may remember that earlier on this page, we decided to use dh-autoreconf
instead of autotools-dev
. It's now time to make this change effective.
Edit the main rule so that dh
is invoked with autoreconf instead of autotools-dev.
#!/usr/bin/make -f
%:
dh $@ --with autoreconf
The docs file
References: https://www.debian.org/doc/manuals/maint-guide/dother.en.html#docs
Specify documentation files that should be installed. By default, it already includes some standard files. Just add other files if you want. As an example:
echo 'README.md' >> debian/docs
The man page
References: https://www.debian.org/doc/manuals/maint-guide/dother.en.html#manpage
If your package doesn't provide a man page, you should write one. Example files are provided, written in different languages, it's up to you to pickup your favorite language and write your manual page. As a quick example:
cd debian
mv manpage.1.ex pnmixer.1
vi pnmixer.1
man -l pnmixer.1
Then, list your manual pages in the file package.manpages
. So in our case, we just
have one file to list:
echo 'debian/pnmixer.1' > debian/pnmixer.manpages
The watch file
References: https://www.debian.org/doc/manuals/maint-guide/dother.en.html#watch
The watch
file is not so easy to setup. Some common upstream source sites are mentioned
in the watch.ex
file, but Github is not amongst them. However you can find more here:
https://wiki.debian.org/debian/watch
To test your setup, type something like that:
uscan pnmixer-0.6.1 --report --verbose
The menu file
At the moment of this writing, it seems that the menu file shouldn't be used anymore if
your package already provides a desktop file. It was not very clear at the beginning.
If you add a menu file, and check your package with lintian
(see below),
you will have this warning:
The command is listed both in a menu file and a desktop file
Per the tech-ctte decision on #741573, this is now prohibited.
Please remove the reference from the menu file.
But after removing the command
line from the menu file, I get an error:
pnmixer: menu-item-missing-required-tag command usr/share/menu/pnmixer:5
Puzzled I was, and indeed, the messages are a little bit misleading. I had to dig the net, and I found a few interesting discussions on that matter. I'll provide the links here for the sake of history, and for people who like to read IT stories :)
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=806387.
- https://lwn.net/Articles/597697/
- https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=741573
The last link tells the end of the story.
The other files
All the other example files that are unused should be removed. It's best to use lintian
(explained below) for that, it will help you in that process.
In the end, here is what my archive looks like:
$ ls -1 debian
changelog
compat
control
copyright
docs
files
pnmixer
pnmixer.1
pnmixer.debhelper.log
pnmixer.manpages
pnmixer.substvars
rules
source
watch
Building the package
Now it's time to build the package. If you're lucky like me, the command will succeed at the first try.
dpkg-buildpackage -us -uc
Now have a look at the parent directory, this is where the package files are created:
$ ls -1 ..
pnmixer-0.6.1
pnmixer_0.6.1-1_amd64.changes
pnmixer_0.6.1-1_amd64.deb
pnmixer_0.6.1-1.debian.tar.xz
pnmixer_0.6.1-1.dsc
pnmixer_0.6.1.orig.tar.gz
pnmixer-0.6.1.tar.gz
pnmixer-dbgsym_0.6.1-1_amd64.deb
You can have a look at the content of your packages with the debc
command.
debc pnmixer_0.6.1-1_amd64.changes
Installing
You may want to try to install the package. The manual recommends to use the debi
command:
sudo debi pnmixer_0.6.1-1_amd64.changes
Checking for errors
References: https://www.debian.org/doc/manuals/maint-guide/dother.en.html.
To check a package for errors, we use lintian
. The basic command:
lintian -i -I --show-overrides pnmixer_0.6.1-1_amd64.changes
You will probably have warnings and errors, nobody gets it right the first time. Be patient and fix them one by one :)
More tips and tricks
Adding a missing file to the skeleton
Let's suppose that, when you created your package skeleton for the first time, your forgot to specify the licence. How to add it afterward? It's really easy!
rm debian/copyright
dh_make --addmissing --copyright gpl3 -f ../pnmixer-0.6.1.tar.gz
Getting rid of the "useless dependency" warning
Let's suppose you have this kind of warning messages when building the package:
dpkg-shlibdeps: warning: package could avoid a useless dependency if debian/pnmixer/usr/bin/pnmixer was not linked against ...
If you feel that you're not responsible for this (ie, you're not explicitely linking against an unused library),
you can get rid of that by adding this line to the rules
file:
export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed