Creating Debian Packages
For some time I'm now working with Debian Linux. Since I'm happy with it, I decided to create binary packages from the source I have.
Now, how are debian packages created? Of course, there is the Debian New Maintainers' Guide. I started reading it but soon I recognized that this explains package creation the "complete way". The guide shows how to "./configure && make && make install" an arbitrary (not neccessarily own) source package. Now my point of view is different: I have a simple (no "./configure") but well known (my own) source package which creates a few files that have to been installed. At this point I dropped more or less the official guide.
- I'm not a Debian programmer/maintainer/expert/whatever,
- this is not an official Debian guide,
- this document is far from being complete or exact.
However I think it's helpful to understand to to create debian packages for some particular programs. It might meet your requirements or not.
To put it simple, debian packages are simple ar(1) archives. An example:
> ls -l total 28 -rw-r--r-- 1 root root 26030 2006-01-12 18:50 tcpproxy_2.0.0beta12-1_i386.deb > ar tv tcpproxy_2.0.0beta12-1_i386.deb rw-r--r-- 0/0 4 Jan 12 18:50 2006 debian-binary rw-r--r-- 0/0 426 Jan 12 18:50 2006 control.tar.gz rw-r--r-- 0/0 25412 Jan 12 18:50 2006 data.tar.gz
see ar's manpage for the details. A debian package contains three files:
- debian-binary
-
contains a archive format version number which is "2.0" (without the quotes).
- control.tar.gz
-
a gzip'ed tar archive of some package control files.
- data.tar.gz
- the gzip'ed tarball of the package files. This is what is installed with apt-get or dpkg.
The archived data.tar.gz dosn't show anything special:
> ar p tcpproxy_2.0.0beta12-1_i386.deb data.tar.gz | tar tzvf - drwxr-xr-x root/root 0 2006-01-12 18:50:11 ./ drwxr-xr-x root/root 0 2006-01-12 18:50:11 ./usr/ drwxr-xr-x root/root 0 2006-01-12 18:50:11 ./usr/sbin/ -rwxr-xr-x root/root 40756 2006-01-12 18:50:11 ./usr/sbin/tcpproxy drwxr-xr-x root/root 0 2006-01-12 18:50:11 ./usr/share/ drwxr-xr-x root/root 0 2006-01-12 18:50:11 ./usr/share/man/ drwxr-xr-x root/root 0 2006-01-12 18:50:11 ./usr/share/man/man1/ -rw-r--r-- root/root 17793 2006-01-12 18:50:11 ./usr/share/man/man1/tcpproxy.1
It's really just what you want to have installed. The control.tar.gz contains some package control files:
> ar p tcpproxy_2.0.0beta12-1_i386.deb control.tar.gz | tar tzvf - drwxr-xr-x root/root 0 2006-01-12 18:50:11 ./ -rw-r--r-- root/root 116 2006-01-12 18:50:11 ./md5sums -rw-r--r-- root/root 244 2006-01-12 18:50:11 ./control
The file is md5sums optional, control is the only thing that is really required, it describes the package. Let's take a look at it.
> ar p tcpproxy_2.0.0beta12-1_i386.deb control.tar.gz | tar xzvf - ./control ./control > cat control Package: tcpproxy Version: 2.0.0beta12-1 Section: net Priority: optional Architecture: i386 Depends: libc6 (>= 2.2.4-4) Installed-Size: 58 Maintainer: Wolfgang Zekoll <wzk@quietsche-entchen.de> Description: tcpproxy is a transparent TCP proxy.
Since every debian package contains a control file you have lot's of other examples around. The Debian Guide, "4.1 `control' file" what can be put into the file and how it should be done exactly.
You could now start creating the required tar files on your own, write "2.0" to debian-binary, pack everything together with ar and put the result into your repository. Good idea but it's not working. Or better, it's not fully working. Packages created that way are accepted by dpkg, apt-get will download and install them but will tell that the package is "not a valid DEB package". There is obviously some "hidden magic" in debian archives and it took me some time to figure out how to create packages the right way.
After some research on the net I found the hint that the debian archive format should be handled with dpkg-deb and assuming that it's an ar compatible thing is not correct. Interesting. dpkg-deb's manpage explains how to create debian packages in plain words. First you need the directory tree of files you want to have installed (exactly what you would put into the data.tar.gz). In this tree's top directory (the tree's "root" directory) you create a directoy named "DEBIAN" where you put the control files (the files for control.tar.gz). The whole stuff is then packed togheter with a "dpkg-deb -b".
Assuming that I use the directory tmp to contains all this stuff files, then the recursive listing for the tcpproxy package would be
> ls -lR tmp tmp: total 8 drwxr-xr-x 2 root root 4096 Jan 12 20:03 DEBIAN/ drwxr-xr-x 4 root root 4096 Jan 12 20:03 usr/ tmp/DEBIAN: total 8 -rw-r--r-- 1 root root 244 Jan 12 20:03 control -rw-r--r-- 1 root root 116 Jan 12 20:03 md5sums tmp/usr: total 8 drwxr-xr-x 2 root root 4096 Jan 12 20:03 sbin/ drwxr-xr-x 3 root root 4096 Jan 12 20:03 share/ tmp/usr/sbin: total 40 -rwxr-xr-x 1 root root 40756 Jan 12 20:03 tcpproxy* tmp/usr/share: total 4 drwxr-xr-x 3 root root 4096 Jan 12 20:03 man/ tmp/usr/share/man: total 4 drwxr-xr-x 2 root root 4096 Jan 12 20:03 man1/ tmp/usr/share/man/man1: total 20 -rw-r--r-- 1 root root 17793 Jan 12 20:03 tcpproxy.1
Running
> dpkg-deb -b tmp tcpproxy_2.0.0beta12-1_i386.deb
in the directory above tmp creates then a debian package that is fully (at least to my understanding) compatible to dpkg and apt-get - no more "not a valid DEB package".
Let's look at another example debian package.
> ls -l ftpproxy_1.2.1-1_i386.deb -rw-r--r-- 1 wzk wzk 74108 2006-01-12 20:21 ftpproxy_1.2.1-1_i386.deb > ar p ftpproxy_1.2.1-1_i386.deb control.tar.gz | tar xzvf - ./ ./postinst ./postrm ./prerm ./md5sums ./control
The control file describes the archive, what's in in which version and what is required to install it, see deb-control(5) for a full description. md5sums is optional, if present it should list the MD5 sums of the files in the archive:
> cat md5sums 821541451ad557337fdd0a886b0c8831 usr/sbin/ftp.proxy 536c2e9eb89bef73b8d3d3f2aaf7b58b usr/share/man/man1/ftp.proxy.1.gz f784fed7d69b95b87888e27468ace25a usr/share/doc/ftpproxy/copyright 669566801ef2f4142235f66ff61352a6 usr/share/doc/ftpproxy/HISTORY.gz aeb17e33a3a169fe4173aebfeb857d9c usr/share/doc/ftpproxy/README.debian ...
This file can be created with
> md5sum `find . -type f | awk '/.\// { print substr($0, 3) }'` >DEBIAN/md5sums
from the package's top directory.
preinst, postinst, prerm and postrm are optional scripts that are run before or after the package has been installed or removed.
> cat postinst
#!/bin/sh -e
update-inetd --comment-chars "#disabled#" --disable ftpproxy
update-inetd --group OTHER --add "ftpproxy stream tcp nowait root /usr/sbin/tcpd /usr/sbin/ftpproxy -e -l"
# symlink management generated by debstd
if [ "$1" = "configure" ]; then
if [ -d /usr/doc -a ! -e /usr/doc/ftpproxy -a -d /usr/share/doc/ftpproxy ]; then
ln -sf ../share/doc/ftpproxy /usr/doc/ftpproxy
fi
fi
This example modifies the system's inetd configuration. Other possible actions are e.g. starting a standalone daemon after installation or shutting it down before removing it.
There are more files that could be in the control.tar.gz, unfortunately explains the official Debian guide the files only in conjunction with the dh_ tools.
Some other documents you might want to read:
- To mention it again: the official Debian New Maintainers' Guide. Take a look at it (at least the specifications) to get a rough idea of what is going on.
- the dpkg-deb(1) manual page,
- the deb(5) manual page,
- the deb-control(5) manual page.