Debian Package Management, Part 2: A Developer's Guide

In the first part of this series, which appeared in the December 2000 issue of Linux Journal, I talked about how to manage Debian packages made by other people. This article is an introduction to making your own Debian packages, both fake and real ones. For complete documentation, look at the Resources section. The next (and last) article in this series will examine building a more complex Debian

A deb is an ar archive, with a magic number of !<arch>, consisting of three files. The first file is named debian-binary. It is a text file with a series of newline separated lines. Currently it has only one line, the format version number, 2.0. The next file is called control.tar.gz. It is a gzipped tarball of the package control information, including the control file and some shell scripts that run before and after installation and removal. The third member of the archive is data.tar.gz and contains the file hierarchy to be installed.


Equivs let you easily make fake debs that contain only meta-information, not actual software. Two uses of equivs are tricking the debian package management system into thinking you have a package installed when you built it from source, and making metapackages for convenience. Metapackages don't contain any software, but "depend" on other packages. When you install them, APT thoughtfully installs the other packages for you. This is how the "task" packages in debian work. task-helix-gnome, task-x-window-system, and task-c++-dev are all metapackages.

To build fake debs with equivs you'll need the following debian packages: equivs, perl, debhelper, dpkg-dev, devscripts, make and fakeroot. All these dependencies will be met with apt-get install equivs, since equivs depend on all the others.

For this example, I'm going to create a metapackage for my web server setup. The first thing to do is run equivs-control <<i>packagename> where packagename is the name of the package you want to build. I used "task-webserver". Now edit the control file, task-webserver (see listing 1.) In the control file, you can also use | to indicate that you want one of several packages installed but don't care which one. For example, if you need either Postfix or Exim, you could say:

Depends: exim|postfix

Listing 1. Control File task-webserver

Everything in the control file is in the form field: value format, like e-mail headers, except for the final field, "Description". The text after the colon on the first line is the short description field, and the long description is on the following lines, indented with a single space.

Once you've created the control file, run equivs-build task-webserver. A .deb file is created in the current directory.

Real debs

To build real debs that contain software, you'll need: binutils, cpp, cpio, dpkg-dev, file, gcc, libc6-dev, make, patch, perl dh-make, debhelper, devscripts, fakeroot and lintian. If your package needs to prompt the user for configuration information when it installs, get debconf.

Building a real deb for a program means taking the source, adding a debian subdirectory and editing a few files in it.

In the debian directory, these are the important files:

* control - Describes the package, including name, version, and dependencies.

* changelog - The changelog lists changes to the Debian package, not necessarily to the original program. You can create it best with dh_make and add new entries with dch -i.

* postinst, preinst, postrm, and/or prerm - Executables, usually shell or Perl scripts, that get run by dpkg during installation and removal of a package. It is important that these scripts can cope with (and recover from) being interrupted. If these scripts need to ask the user questions, they should use debconf.

* conffiles - The list of configuration files which dpkg will handle.

* shlibs - List of shared libraries supplied by package (not used in these examples since we're not building any libraries).

* docs - List of documentation files.

* *.menu - Menu entries.

* copyright - Copyright statement and license.

A Simple Example

The GNU hello program is one of the simplest packages. To get the source package, execute apt-get source hello. In the debian subdirectory of the hello-<<i>version> directory are several files:

* hello.1 - manpages can be kept in the debian directory. Since GNU hello does not have a manpage, the Debian maintainer added it.

* postinst and prerm - two simple and similar scripts. postinst installs the GNU Info entries, then, if it is being called to configure the package, it makes a symlink from /usr/share/doc/hello to /usr/doc/hello for compliance with the Filesystem Hierarchy Standard. prerm, run before the package is removed, simply removes the info entries and the symlink.

* rules - (see listing 2) probably the most important file in building a deb. It is a Makefile that goes about building the package in a tmp directory under the debian directory of the source tree. This tmp directory gets tarred up to become data.tar.gz. The names of the rules are mandatory and outlined in the Debian Packaging Manual.

Listing 2. Rules File for deb Making

The build target builds the program, then creates a file build, which signifies to make that this step is done.

The clean target removes the build file, runs the program's own make clean and gets rid of the temporary files created by the Debian build process.

If there was a binary-independent package to build, the binary-indep target would handle that. Here it does nothing other than check if the package builder is root, and then build the program.

The most complex target is binary-arch, which installs the program into the debian/tmp directory.

The installation goes like this: use the nstall program to create the necessary directories, then use it to copy in the postinst/prerm scripts, run make install with the install prefix as the current directory plus debian/tmp/usr, move in and compress the info file, then copy in the rest of the documentation.

Now the package starts to take shape: dpkg-shlibdeps hello takes the shared libraries that the binary hello relies on, figures out what packages they are contained in and puts that list in the file debian/substvars, which is used to replace ${shlibs:Depends} in the rules file when the package is built. dpkg-gencontrol builds the finalized control file (by default) in debian/tmp/DEBIAN/control, does a little cleanup on the permissions of the directories and finally builds the package with dpkg --build debian/tmp.

The checkdir that everything keeps calling is a define that looks for hello.c and debian/rules, to make sure the package is being built from the directory just above the debian subdirectory.

The last section is fairly generic to all rules files. The binary target builds both binary-dependent and -independent packages, checkroot makes sure the builder of the package is either root or running fakeroot and the last is a bit of Makefile magic that allows you to have a target that is not really the name of a file.

Now that you've got a directory full of source and a subdirectory full of weird-looking text files, some proof that it actually makes a .deb might be nice. Run fakeroot debian/rules binary, and a .deb with a name starting with "hello" will be created in the directory above the source directory. (Different versions of the program will have different version numbers between the "hello" and the ".deb".) Fakeroot is a hack to let you, as an ordinary user, build debs that install root-owned files.

For more examples, you can apt-get source your favorite packages to see how they are transformed into little binaries of apt-gettable goodness.

David Blackman is a student system administrator at Stuyvesant High School in New York City.


Geek Guide
The DevOps Toolbox

Tools and Technologies for Scale and Reliability
by Linux Journal Editor Bill Childers

Get your free copy today

Sponsored by IBM

8 Signs You're Beyond Cron

Scheduling Crontabs With an Enterprise Scheduler
On Demand
Moderated by Linux Journal Contributor Mike Diehl

Sign up and watch now

Sponsored by Skybot