[Distutils] Thoughts about Distutils and Debian

Gregor Hoffleit flight@hoffleit.de
Thu, 11 May 2000 08:46:38 +0200

Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: quoted-printable


I'm currently trying to make up my mind how Distutils and building Debian
packages fit together.

I have to impression we're faced with something like a chicken and egg
problem. ...

Since not everybody knows the Debian package format, I'll give a short

A short story of .deb's and Debian packages

A .deb package is in fact really, really simple:

  freefly;158> ar tv python-ldap_1.8-1_i386.deb=20
  rw-r--r-- 0/0      4 Nov 30 15:58 1999 debian-binary
  rw-r--r-- 0/0   1078 Nov 30 15:58 1999 control.tar.gz
  rw-r--r-- 0/0  52562 Nov 30 15:58 1999 data.tar.gz

  freefly;159> ar x python-ldap_1.8-1_i386.deb=20

  freefly;160> cat debian-binary=20

  freefly;161> tar tvpzf control.tar.gz=20
  drwxr-xr-x root/root         0 1999-11-30 15:58:41 ./
  -rwxr-xr-x root/root       553 1999-11-30 15:58:05 ./postinst
  -rwxr-xr-x root/root       461 1999-11-30 15:58:05 ./prerm
  -rw-r--r-- root/root       660 1999-11-30 15:58:41 ./md5sums
  -rw-r--r-- root/root       392 1999-11-30 15:58:41 ./control

  freefly;162> tar tvpzf data.tar.gz=20
  drwxr-xr-x root/root         0 1999-11-30 15:58:04 ./
  drwxr-xr-x root/root         0 1999-11-30 15:58:01 ./usr/
  drwxr-xr-x root/root         0 1999-11-30 15:58:01 ./usr/lib/
  drwxr-xr-x root/root         0 1999-11-30 15:58:01 ./usr/lib/python1.5/
  -rw-r--r-- root/root       228 1999-11-30 15:48:07 ./usr/share/doc-base/p=

The nice thing is that you can simply unpack the file with standard Unix
tools. The same is true for the reverse: You can build a .deb with ar and
tar only.

What's the stuff in control.tar.gz ?
postinst and prerm (and preinst and postrm) are optional scripts that are
called at various points of the installation/deinstallation of a package;
control is a text file describing the package:

  freefly;163> cat control
  Package: python-ldap
  Version: 1.8-1
  Section: net
  Priority: optional
  Architecture: i386
  Depends: libc6 (>=3D 2.1), libopenldap1
  Installed-Size: 99
  Maintainer: Gregor Hoffleit <flight@debian.org>
  Description: An LDAP module for Python.
   This module provides an Python interface to the LDAP client library
   (LDAP is the Lightweight Directory Access Protocol). It has been
   compiled with OpenLDAP.

Building a valid .deb package is as simple as

    echo 2.0 >debian-binary
    vi control
    tar -c -z -f control.tar.gz ./control
    tar -c -z -f data.tar.gz -C build .
    ar cv my1stdeb-0.0.deb debian-binary control.tar.gz data.tar.gz

Now while this is a valid .deb file, there's more to a valid Debian package
than this: Packages have to follow some rules in order to

  (a) not to hose the system were they're unpacked
  (b) fit into the Debian archive scheme
  (c) support building from source
  (d) support auto-building from source

These rules are put together in the Debian Policy manual
(http://www.debian.org/doc/debian-policy/) and the Debian Packaging manual.

The most interesting things in our context are certainly (c) and (d).

A valid Debian package should be built from a source package. A source
package consists of a tarball of the upstream version (xyz_1.2.orig.tar.gz),
a diff file with Debian's changes to the package (xyz_1.2-5.diff.gz) and a
text file with a description of the package (xyz_1.2-5.dsc) including things
like md5sums of the source files and GPG signed by the maintainer of the
package. (If you have these three files, you can unpack the source tree with
"dpkg-source -x xyz_1.2-5.dsc", or with

    tar -xzpf xyz_1.2.orig.tar.gz
    zcat xyz_1.2-5.diff.gz | patch -p1

Debian's equivalent to an RPM spec file is a ./debian directory in the
source tree. Typically, this directory looks like this:

  freefly;193> cd python-ldap-1.8/
  freefly;194> ls -ld debian/*
  -rw-r--r--    1 flight   flight        323 Mai 10 21:28 debian/README.Deb=
  -rw-r--r--    1 flight   flight        203 Mai 10 21:28 debian/TODO.Debian
  -rw-r--r--    1 flight   flight       1644 Mai 10 21:28 debian/changelog
  -rw-r--r--    1 flight   flight        392 Mai 10 21:28 debian/control
  -rw-r--r--    1 flight   flight        799 Mai 10 21:28 debian/copyright
  -rw-r--r--    1 flight   flight        228 Mai 10 21:28 debian/doc-base
  -rw-r--r--    1 flight   flight        133 Mai 10 21:28 debian/postinst
  -rw-r--r--    1 flight   flight        130 Mai 10 21:28 debian/prerm
  -rwxr-xr-x    1 flight   flight       1576 Mai 10 21:28 debian/rules*

The most important thing is debian/rules (note the connotation ;-), which is
in fact an (executable) Makefile with targets "build", "clean",
"binary-indep", "binary-arch" and "binary".

Provided the tools used in this rules Makefile are installed, building all
packages from a source tree is done by calling

    debian/rules binary

"debian/rules binary-indep" would build only the packages that are flagged
architecture-independent (like a 100% pure Python package); "debian/rules
binary-arch" would build the architecture-dependent packages for the
architecture of the system we're running on (e.g. i386, m68k, sparc,
hurd-i386 or perhaps bsd-i386 or cygwin-i386).

For a normal package, "rules build" calls "./configure; make", "rules clean"
calls "make clean", "rules binary" calls "make DESTDIR=3D'pwd'/debian/tmp
install" and "dh_builddeb" (from a simplified view).

Needless to say that Debian's build tools (and autobuild daemon's) rely on
the presence of ./debian/rules to build binary packages for every
architecture from their source packages.

Enters Distutils

So where exactly does Distutils fit into this picture, how much sense makes
bdist_deb, and what should it do ?

=46rom the theory above, you see that it's possible and even quite easy to
write a bdist_deb target that builds a valid .deb file (using ar and tar)
for any Distutil'ed package. The problem is that that's still only a
third-class Debian package: Fine for rapid-prototyping of .deb packages, but
without support for Debian's infrastructure.

If we'd like to do better, we have to support debian/rules somehow. I'm
still not sure what's the best way to do this, and how bdist's "source
distributions" fit into this.

Possible ideas:

bdist_deb could create a source archive with a debian/rules skeleton that
just works(tm). The debian/rules skeleton would just call up setup.py in
different places. I.e. bdist_deb source distribution command creates a
source package; this source package uses (in debian/rules) simple setup.py
targets like "clean", "build" and "install" and finally builds the .deb file
using standard Debian tools.

In an ideal world (any Distutil'ed package maps perfectly in a Debian
package) this would be fine. In our world, Debian maintainers still would
have to merge their changes with new upstream versions, therefore providing
a debian/rules skeleton is perhaps not enough.

Maybe the bdist_deb binary distribution command then could simply call up
"debian/rules binary" to build the binary packages.

A little bit more elaborated thoughts to come, I hope.


Content-Type: application/pgp-signature

Version: GnuPG v1.0.1 (GNU/Linux)
Comment: For info see http://www.gnupg.org