Build a development environment for Debian¶
Here is a memo about how some development activities can be done in Debian.
Compile a Debian package in debug mode¶
Sometimes a program crashes and you need to reinstall it to be able to debug it.
With debug symbols, you may attach a process with gdb and then follow the
execution with commands such as layout src
and layout split
instead of
layout regs
and layout asm
. There are several ways to get a program
built with debug symbols in Debian. For the rest of this section, let’s state
that the program you want to debug is in a package which name is foo
.
First, there is occasionally a debug package for foo
, named foo-dbg
or
something like that. In such case, you have a clean solution and nothing to do
more than to replace a package.
For most of the cases, such package doesn’t exist and you need to recompile
package foo
by adding some options to debuild
. This can be done in a
clean temporary directory by issuing the following commands:
sudo apt-get build foo
apt-get source foo
cd foo-*/
export DEB_BUILD_OPTIONS="nostrip noopt"
debuild -uc -us
sudo dpkg -i ../foo_*.deb
These commands first install all the necessary build dependency and extract
the Debian-patched version of foo
in a foo-version
directory. Running
debuild
into this directory is enough to build a foo_version_arch.deb
file in the main folder, the options are here to tweak the compiling process
(disable stripping symbols from executable files and disable optimization) and
the build process (don’t sign any produced files). Instead of calling debuild,
calling dpkg-buildpackage -rfakeroot
may work, as some documents suggest.
Set up your own Debian repository¶
You may want to install some package you compiled in several systems or to make
this package publicly available. This can be achieved thanks to reprepro
,
which is a simple tool to maintain a repository tree. To do that, let’s assume
you want a package tree in /var/packages/debian
.
First, create /var/packages/debian/conf/distributions
with something like:
Origin: My Repository
Label: My Repository
Suite: unstable
Codename: sid
Architectures: i386 amd64 source
Components: main
Description: My APT repositories
DebOverride: override.sid
DscOverride: override.sid
SignWith: 12345678
(SignWith
is an optional line which identifies a PGP key which is used to
sign the package tree)
Then create /var/packages/debian/conf/options
:
verbose
ask-passphrase
basedir /var/packages/debian
And create /var/packages/debian/conf/override.sid
, which can be empty but
may also contains lines which override package descriptions such as:
my-package Priority optional
my-package Section net
Then you can add .deb
files with:
reprepro includedeb sid /path/to/mypackage.deb
and source, changes and deb files all at once with:
reprepro include sid /path/to/mypackage.dsc
To serve this repo with a web server, you may want to exclude conf/
and
db/
directories from direct browsing to protect your specific configuration.
Finally, you need to add at least the first line in the
/etc/apt/sources.list
of each host which uses this new APT repository:
deb http://my-host.tld/debian sid main
deb-src http://my-host.tld/debian sid main
And also use apt-key add
to add the GPG public key of the repository to your
GPG keychain.
More detail in the Debian official wiki: https://wiki.debian.org/SettingUpSignedAptRepositoryWithReprepro
Package a Python library for Debian¶
Relevant Debian wiki articles:
In this section, let’s suppose you have a Python library which is packaged with
distutils
, setuptools
, distribute
or whatever. This library provides
a setup.py
file which can be used to install it on the system.
Debian wiki documents command line tools such as py2dsc
. This tool is a
shortcut for some of the initial steps but this section will focus on lower
level tools which help understanding how Debian packaging work.
For the sake of clarity, let’s say you’re working on library mylibrary
version 0.0.1
.
The starting point of every Debian package is the original files archive. This
archive is the one that may be downloaded from the websites which provide a
download link. For example, if your library is on PyPI, you would download
https://pypi.python.org/packages/source/m/mylibrary/mylibrary-0.0.1.tar.gz.
This file should be put in the parent directory of the folder where
mylibrary
lies, and named mylibrary_0.0.1.orig.tar.gz
(name, underscore, version). setup.py
can be used to create this file:
python setup.py sdist
cp dist/mylibrary-0.0.1.tar.gz ../mylibrary_0.0.1.orig.tar.gz
Side note: if you’re the author of the library, the command to upload it to PyPI is:
python setup.py sdist register upload
Once you have a proper original files archive the next step is to create a
debian
directory in the current directory. There are two ways to achieve
this:
Invoke magic from
python-stdeb
package:python setup.py --command-packages=stdeb.command debianize
Read Debian’s packaging documentation and create files by hand. To create/update
debian/changelog
file, you may use for example:dch --create -v 0.0.1-1 --package mylibrary
When you feel the package is almost ready, you need to test building the package without running tests nor signing anything:
DEB_BUILD_OPTIONS=nocheck debuild -uc -us
Usually lintian
will get angry and print error messages at this step because
it’s really hard to follow all of the Debian packaging rules the first time.
This is where the packaging process takes time, as you need to edit files in
debian
folder to fix the issues reported by lintian
.
Often the clean
function of the package doesn’t remove the .egg-info
folder which is created by setup.py build
. This is an issue because
debuild
finds out that mylibrary.egg-info
doesn’t exist in the original
files and thus treats it as a Debian-specific patch. To prevent this behavior,
you need to add this line to debian/clean
:
mylibrary.egg-info/*
Once lintian
has no more things to say, you can build the final package
and sign it with your GPG key:
debuild
The parent directory now contains the following files (here on a 64-bit system):
mylibrary_0.0.1-1_all.deb
mylibrary_0.0.1-1_amd64.build
mylibrary_0.0.1-1_amd64.changes
mylibrary_0.0.1-1.debian.tar.gz
mylibrary_0.0.1-1.dsc
mylibrary_0.0.1.orig.tar.gz
Now you would directly install the package using dpkg -i
or upload it to
a Debian package repository or wherever you like.
Test patches in git code with a clean package¶
Let’s say you’re working on mysoftware
(add features, fix bugs…) and you
need to test it “for real” on your Debian system. To make the installation
process really looks like a common installation, the best way is to build a
package out of the current development version. Let’s suppose mysoftware
uses git to manage its code. Here is how to build and install such test package:
First, update
debian/
directory (new entry indebian/Changelog
, no patches…). For the sake of the example, let’s say your testing version is0.99-1
.Create the original files archive:
git archive --prefix=mysoftware_0.99/ -o ../mysoftware_0.99.orig.tar.gz master
Build the package (without signing anything):
debuild -uc -us
Install it:
sudo dpkg -i ../mysoftware_0.99-1_*.deb