Debian Packages
As was mentioned earlier in this book, the Ubuntu project is based on the Debian GNU/Linux distribution. Among many other technological legacies, Ubuntu has inherited the Debian package system. In fact, many core Ubuntu developers involved early on will credit Debian’s packaging system as the reason that Debian proved such an attractive point of departure and represented its major attraction over other GNU/Linux distributions As a result, almost all aspects of package management—from the formats to the tools—are identical on Ubuntu and Debian. In many situations, unmodified Debian packages can simply be installed on Ubuntu. In nearly all situations, unmodified Debian source packages can be built on Ubuntu. As a result, our first step will be to examine an Ubuntu DEB in some depth to understand the anatomy of the package and the way that it implements the features described in the preceding sections.
Source Packages
DEB source packages are clearly expressed in what is usually a three- or two-file format but may also include source packages that consist of many more files as well. This means that the package itself contains multiple files and downloading “a source package” may in fact involve downloading a small assortment of different files. Source packages can be broadly classified as either native DEB packages or nonnative DEB packages. A native DEB is a piece of software where there is no difference between the upstream version and the DEB package. In most cases, native packages are specific to either Ubuntu, Debian, or another Debian-based distribution. In other words, a native package will require no changes in order to create the package. A DEB source package will always consist of a “pristine” source archive in the form of a gzip-compressed GNU tar file and a DSC file that will list the contents of the package and can be considered the “core” of a source package. An example DSC for a program called most that I maintain looks like this:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Format: 1.0 Source: most Binary: most Architecture: any Version: 5.0.0a-1 Maintainer: Benjamin Mako Hill <mako@debian.org> Standards-Version: 3.7.3 Build-Depends: debhelper (>= 4), libslang2-dev Files: 30f2131b67f61716f6fe1f65205da48b 155233 most_5.0.0a.orig.tar.gz 07e3eb05ad5524fe6d885f5cdc2eb902 20160 most_5.0.0a-1.diff.gz -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFH4IoAic1LIWB1WeYRAjyOAKCrLCfuZA7b8JcvYTFYeuHrF7r34wCfVTBS /jGUfIrELNq173sM9CorZA4= =/Cia -----END PGP SIGNATURE-----
The file is signed with a GnuPG or PGP key to ensure the integrity of the file and the identity of the author. If you were to check this signature with GPG, you would see that it was signed by my GPG key. The DSC file also contains information on the version of the source format (in this case, it’s the “old” format, 1.0), the name of the source package, the version of the package (split into the version of the upstream source and the version of the package after the final -), the name and e-mail of the maintainer, the architecture on which the software will run, the version of policy (marked as “standards”) against which the software was created, the software that must be present to build the package, and a list of the other files this source package contains, identified by file size and MD5 hashes.
In a native DEB, there would be only a single compressed tar (tar.gz) file. In this nonnative package, there would be additional files that represent all changes to the package. This is so all the changes that the DEB packager made are clearly visible. This is sometimes done for license reasons but is usually done just so that users can see exactly what the packager has done and what has been changed. This also makes it easy for the package maintainer to understand where a problem lies if there is an error. Changes made to a package are usually expressed in a gzip-compressed diff file that expresses all the differences between the package source and the pristine source. In the case above, it is listed as most_5.0.0a-1.diff.gz. In newer versions of the DEB source package format, additional tar files containing additions or changes to the pristine source archive are also permitted, as long as they are listed in the DSC file in the list of files.
When unpacked and with all necessary patches applied, every DEB source package will unpack into a single directory of the form packagename-version with a mandatory debian directory as a subdirectory. In the vast majority of packages, almost all changes to the source will be made inside this directory. This directory will contain a number of files—more than I have space to cover here. Most important among these are the control file and the rules file. The control file will include most of the information about the source package found in the DSC file (which is autogenerated using control file data) and additional information describing each binary package. The control file expresses all interpackage relationships including Depends, Conflicts, Provides, Replaces, Recommends, Suggests, and Enhances. As the “hard” requirements, the first four are most important. Suggests and Enhances are rarely used by any program. The file will also include both a single-line and a multiline description. A sample control file (the control for most) is shown below:
Source: most Section: text Priority: optional Maintainer: Benjamin Mako Hill <mako@debian.org> Standards-Version: 3.7.3 Build-Depends: debhelper (>=4), libslang2-dev Package: most Architecture: any Depends: ${shlibs:Depends} Description: Pager program similar to more and less
The long-form description was removed from the output but in fact followed the final description line and includes text that is indented by one space and where paragraphs are separated by a single “.”. As mentioned previously, the control file consists of a series of stanzas. The first stanza will always begin with Source: and will include information on the source package. Each following stanza will describe a single binary package. In this case, there is only one binary package, which, like the source package, is named most. This situation—a single source package creating a single binary package of the same name—is a very common case.
The rules file is a GNU Make makefile and contains all of the makefile rules to create and build a package. Running debian/rules binary from within the unpacked source package directory will result in the creation of a Debian package in one directory above (../) if your system has all the necessary dependencies installed. In most cases, the software will build and “install” into a series of subdirectories within the debian directory; these files in their temporary location will then be included as the package contents.
Additional files in the debian directory include the copyright file, the changelog for the package, optional scripts to be run after and before installation or removal of the package, and extra configuration data plus anything else that the packager would like to include.
Binary Packages
Debian binary packages are very simple in format, so it is unnecessary to spend much time on them here. More important, they are almost never manipulated by hand. Binary packages are merely installed and removed. Changes to a binary package are made first in the source package and then new, changed binary packages are rebuilt. In Ubuntu and Debian, binary packages are a single file in an archive in the ar format. In the archive is debian-binary, which contains a series of lines, separated by newlines. At the moment, only the format version number is included. The second member of the archive is named control.tar.gz, and it contains the package control information (as described previously). The third and last member is called data.tar.gz, and it contains the file system archive as a gzipped tar archive.