The Debian and Ubuntu distributions organize their software using deb packages. Debian has some fancy tools (debhelper) which help build these packages. This paper explains the structure of a deb package and shows that it is easy to build a deb package manually without using the debhelper tools.
Suppose you have a package installed called hello. You want to know where (what repository) that package came from. Use the apt-cache policy command like this:
bash$ apt-cache policy hello hello: Installed: 2.2-2 Candidate: 2.2-2 Version table: *** 2.2-2 0 500 http://ca.archive.ubuntu.com gutsy/main Packages 100 /var/lib/dpkg/status
The important parts are the installed version number and the URL. The URL shows which repository it is from (ca.archive.ubuntu.com) and it's pocket and component (gutsy/main). But here is it's listing in /etc/apt/sources.list:
deb http://ca.archive.ubuntu.com/ubuntu/ gutsy main restricted
So you can see that the repository is actually at http://ca.archive.ubunu.com/ubuntu. So I cruise to that URL with firefox, go into the pool directory and eventually find the hello_2.2-2_i386.deb package:
http://ca.archive.ubuntu.com/ubuntu/pool/main/h/hello/hello_2.2-2_i386.deb
The deb file is an archive containing several files. You could think of it as a zip file, but debian doesn't use the zip utility. Instead, debian chose to use the old ar command from binutils. ar is most commonly used by programmers to combine several object files (for instance produced by gcc with suffix .o) into a single library file with the suffix .a. If you are a programmer and have a library file in one of your projects you can manipulate that file using the ar command. For instance, to look at a listing of the contents of the popular libvorbis.a library I can use the ar command with the -t switch:
bash$ ar -t /usr/lib/libvorbis.a mdct.o smallft.o block.o envelope.o window.o lsp.o lpc.o analysis.o synthesis.o psy.o info.o floor1.o floor0.o res0.o mapping0.o registry.o codebook.o sharedbook.o lookup.o bitrate.o
The old ar command can be used in a more general sense to create an archive of any type of file, but it has some limitations compared to zip. The two biggest limitations are:
So we create a temporary directory, move the hello package to the temporary directory, then extract it's contents using the ar command.
bash$ mkdir temp bash$ mv hello* temp bash$ cd temp bash$ ar x hello* bash$ ls control.tar.gz data.tar.gz debian-binary hello_2.2-2_i386.deb
The deb file contains three files: control.tar.gz, data.tar.gz, debian-binary.
The last file is just a text file containing the version number of the debian system, which at this time is 2.0:
bash$ cat debian-binary 2.0
Of course, the control and data files are stored as tarballs because ar doesn't do compression or directory structures. So next unpack the tarballs
bash$ tar -xzvf control.tar.gz ./ ./control
The control file contains information that the debian needs to calculate dependencies and display information about the file. Here's a copy of the hello package control file:
bash$ cat control Package: hello Version: 2.2-2 Section: devel Priority: optional Architecture: i386 Depends: libc6 (>= 2.5-0ubuntu1) Installed-Size: 584 Maintainer: Ubuntu Core DevelopersOriginal-Maintainer: Santiago Vila Description: The classic greeting, and a good example The GNU hello program produces a familiar, friendly greeting. It allows non-programmers to use a classic computer science tool which would otherwise be unavailable to them. . Seriously, though: this is an example of how to do a Debian package. It is the Debian version of the GNU Project's `hello world' program (which is itself an example for the GNU Project).
Section 5.3 of the Debian Policy Manual specifies the fields of the control file.
The data tarball contains the actual files which we will install on the system, assuming that the current directory is root.
bash$ tar -xzvf data.tar.gz ./ ./usr/ ./usr/share/ ./usr/share/doc/ ./usr/share/doc/hello/ ./usr/share/doc/hello/NEWS ./usr/share/doc/hello/copyright ./usr/share/doc/hello/changelog.gz ./usr/share/doc/hello/changelog.Debian.gz ./usr/share/man/ ./usr/share/man/man1/ ./usr/share/man/man1/hello.1.gz ./usr/bin/ ./usr/bin/hello
The ar tool is easy to use. The control file is well specified in the policy manual. It's easy to set up a directory structure for the binary files and make the tarball. On the otherhand, the debhelper tools are complicated and poorly documented. So I think it is actually easier to create custom packages by hand (or write a simple bash script) rather than use the debian packaging tools.