## Packaging From Scratch

Requirements: build-essential, automake, gnupg, lintian, fakeroot and pbuilder.

In this example we will be using the GNU hello program as our example. You can download the source tarball from ftp.gnu.org. For the purposes of this example, we will be using the `~/hello/` directory.

    mkdir ~/hello
    cd ~/hello
    wget http://ftp.gnu.org/gnu/hello/hello-2.1.1.tar.gz

We will also compare our package to one that is already packaged in the Ubuntu repository. For now, we will place it in the `ubuntu` directory so we can look at it later. To get the source package, make sure you have a "deb-src" line in your `/etc/apt/sources.list` file for the Main repository. Then, simply execute:

    mkdir ubuntu
    cd ubuntu
    apt-get source hello
    cd ..

Unlike most apt-get commands, you do not need to have root privileges to get the source package, because it is downloaded to the current directory. In fact, it is recommended that you only use apt-get source as a regular user, because then you can edit files in the source package without needing root privileges.

What the apt-get source command does is:

1. Download the source package. A source package commonly contains a .dsc file describing the package and giving md5sums for the source package, an .orig.tar.gz file containing the source code from the author(s), and a .diff.gz file containing patches applied against the source code with the packaging information.

2. Untar the .orig.tar.gz file into the current directory.

3. Apply the gunzipped .diff.gz to the unpacked source directory.

If you manually download the source package (.dsc, .orig.tar.gz, and .diff.gz files), you can unpack them in the same way apt-get source does by using dpkg-source as follows:

    dpkg-source -x *.dsc

The first thing you will need to do is make a copy of the original (sometimes called "upstream") tarball in the following format: `<packagename>_<version>.orig.tar.gz`. This step does two things. First, it creates two copies of the source code. If you accidentally change or delete the working copy you can use the one you downloaded. Second, it is considered poor packaging practice to change the original source tarball unless absolutely necessary. See la sezione chiamata “Common Mistakes” for reasons.

    cp hello-2.1.1.tar.gz hello_2.1.1.orig.tar.gz
    tar -xzvf hello_2.1.1.orig.tar.gz

The underscore, "_", between the package name (hello) and the version (2.1.1), as opposed to a hyphen, "-", is very important. Your source package will incorrectly be built as a Debian native package.

We now have a `hello-2.1.1` directory containing the source files. Now we need to create the customary debian directory where all the packaging information is stored, allowing us to separate the packaging files from the application source files.

    mkdir hello-2.1.1/debian
    cd hello-2.1.1/debian/

We now need to create the essential files for any Ubuntu source package: `changelog`, `control`, `copyright`, and `rules`. These are the files needed to create the binary packages (.deb files) from the original (upstream) source code. Let us look at each one in turn.

### changelog

The `changelog` file is, as its name implies, a listing of the changes made in each version. It has a specific format that gives the package name, version, distribution, changes, and who made the changes at a given time. If you have a GPG key, make sure to use the same name and email address in `changelog` as you have in your key. The following is a template `changelog`:

    package (version) distribution; urgency=urgency

      * change details
        more change details
      * even more change details

    -- maintainer name <email address>[two spaces]  date

The format (especially of the date) is important. The date should be in RFC822 format, which can be obtained from the 822-date program.

Here is a sample `changelog` file for hello:

    hello (2.1.1-1) dapper; urgency=low

       * New upstream release with lots of bug fixes.

    -- Captain Packager <packager@coolness.com>  Wed,  5 Apr 2006 22:38:49 -0700

Notice that the version has a -1 appended to it, or what is called the Debian revision, which is used so that the packaging can be updated (to fix bugs for example) with new uploads within the same source release version.

Ubuntu and Debian have slightly different package versioning schemes to avoid conflicting packages with the same source version. If a Debian package has been changed in Ubuntu, it has ubuntuX (where X is the Ubuntu revision number) appended to the end of the Debian version. So if the Debian hello package was changed by Ubuntu, the version string would be `2.1.1-1ubuntu1`. If a package for the application does not exist in Debian, then the Ubuntu version is 0 (e.g., `2.1.1-0ubuntu1`).

Now look at the `changelog` for the Ubuntu source package that we downloaded earlier:

    less ../../ubuntu/hello-2.1.1/debian/changelog

Notice that in this case the distribution is unstable (a Debian branch), because the Debian package has not been changed by Ubuntu. Remember to set the distribution to your target distribution release.

At this point create a `changelog` file in the `debian` directory where you should still be.

### control

The control file contains the information that the package manager (such as apt-get, synaptic, and aptitude) uses, build-time dependencies, maintainer information, and much more.

For the Ubuntu hello package, the control file looks something like:

    Source: hello
    Section: devel
    Priority: optional
    Maintainer: Captain Packager <packager@coolness.com>
    Standards-Version: 3.6.1

    Package: hello
    Architecture: any
    Depends: ${shlibs:Depends}
    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).

Create `control` using the information above (making sure to provide your information for the Maintainer field).

The first paragraph gives information about the source package. Let us go through each line:

- Source: This is the name of the source package, in this case, hello.

- Section: The apt repositories are split up into sections for ease of browsing and categorization of software. In this case, hello belongs in the devel section.

- Priority: This sets the importance of the package to users. It should be one of the following:

  - Required - packages that are essential for the system to work properly. If they are removed it is highly likely that your system will break in an unrecoverable way.

  - Important - minimal set of packages for a usable system. Removing these packages will not produce an unrecoverable breakage of your system, but they are generally considered important tools without which any Linux installation would be incomplete. Note: This does not include things like Emacs or even the X Window System.

  - Standard - Somewhat self explanatory.

  - Optional - in essence this category is for non-required packages, or the bulk of packages. However, these packages should not conflict with each other.

  - Extra - packages that may conflict with packages in one of the above categories. Also used for specialized packages that would only be useful to people who already know the purpose of the package.

- Maintainer: The package maintainer with email address.

- Standards-Version: The version of the Debian Policy to which the package adheres (in this case, version 3.6.1). An easy way to find the current version is apt-cache show debian-policy | grep Version.

- Build-Depends: One of the most important fields and often the source of bugs, this line lists the binary packages (with versions if necessary) that need to be installed in order to create the binary package(s) from the source package. Packages that are essential are required by build-essential and do not need to be included in the Build-Depends line. In the case of hello, all the needed packages are a part of build-essential, so a Build-Depends line is not needed. The list of build-essential packages can be found at `/usr/share/doc/build-essential/list`.

The second paragraph is for the binary package that will be built from the source. If multiple binary packages are built from the source package, there should be one section for each one. Again, let us go through each line:

- Package: The name for the binary package. Many times for simple programs (such as hello), the source and binary packages' names are identical.

- Architecture: The architectures for which the binary package(s) will be built. Examples are:

  - all - The source is not architecture-dependent. Programs that use Python or other interpreted languages would use this. The resulting binary package would end with `_all.deb`.

  - any - The source is architecture-dependent and should compile on all the supported architectures. There will be a .deb file for each architecture ( `_i386.deb` for instance)

  - A subset of architectures (i386, amd64, ppc, etc.) can be listed to indicate that the source is architecture-dependent and does not work for all architectures supported by Ubuntu.

- Depends: The list of packages that the binary package depends on for functionality. For hello, we see `${shlibs:Depends}`, which is a variable that substitutes in the needed shared libraries. See the `dpkg-source` man page for more information.

- Recommends: Used for packages that are highly recommended and usually are installed with the package. Some package managers, most notably aptitude, automatically install Recommended packages.

- Suggests: Used for packages that are similar or useful when this package is installed.

- Conflicts: Used for packages that will conflict with this package. Both cannot be installed at the same time. If one is being installed, the other will be removed.

- Description: Both short and long descriptions are used by package managers. The format is:

      Description: <single line synopsis>
       <extended description over several lines>

  Note that there is one space at the beginning of each line in the long description. More information on how to make a good description can be found at http://people.debian.org/~walters/descriptions.html.

### copyright

This file gives the copyright information. Generally, copyright information is found in the `COPYING` file in the program's source directory. This file should include such information as the names of the author and the packager, the URL from which the source came, a Copyright line with the year and copyright holder, and the text of the copyright itself. An example template would be:

    This package was debianized by {Your Name} <your email address>
    {Date}

    It was downloaded from: {URL of webpage}

    Upstream Author(s): {Name(s) and email address(es) of author(s)}

    Copyright:
    	Copyright (C) {Year(s)} by {Author(s)} {Email address(es)}

    License:

As one can imagine, hello is released under the GPL license. In this case it is easiest to just copy the `copyright` file from the Ubuntu package:

    cp ../../ubuntu/hello-2.1.1/debian/copyright .

You must include the complete copyright unless it is is GPL, LGPL, BSD, or Artistic License, in which case you can refer to the corresponding file in the `/usr/share/common-licenses/` directory.

Notice that the Ubuntu package's `copyright` includes a license statement for the manual. It is important that all the files in the source be covered by a license statement.

### rules

The `rules` file is an executable Makefile that has rules for building the binary package from the source packages. For hello, it will be easier to use the `rules` from the Ubuntu package:

    #!/usr/bin/make -f
    # Sample debian/rules file - for GNU Hello.
    # Copyright 1994,1995 by Ian Jackson.
    # I hereby give you perpetual unlimited permission to copy,
    # modify and relicense this file, provided that you do not remove
    # my name from the file itself.  (I assert my moral right of
    # paternity under the Copyright, Designs and Patents Act 1988.)
    # This file may have to be extensively modified

    package = hello
    docdir = debian/tmp/usr/share/doc/$(package)

    CC = gcc
    CFLAGS = -g -Wall
    INSTALL_PROGRAM = install

    ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
      CFLAGS += -O2
    endif
    ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
      INSTALL_PROGRAM += -s
    endif

    build:
            $(checkdir)
            ./configure --prefix=/usr
            $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)"
            touch build

    clean:
            $(checkdir)
            rm -f build
            -$(MAKE) -i distclean
            rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars

    binary-indep:   checkroot build
            $(checkdir)
    # There are no architecture-independent files to be uploaded
    # generated by this package.  If there were any they would be
    # made here.

    binary-arch:    checkroot build
            $(checkdir)
            rm -rf debian/tmp
            install -d debian/tmp/DEBIAN $(docdir)
            install -m 755 debian/postinst debian/prerm debian/tmp/DEBIAN
            $(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \
                    prefix=$$(pwd)/debian/tmp/usr install
            cd debian/tmp && mv usr/info usr/man usr/share
            cp -a NEWS debian/copyright $(docdir)
            cp -a debian/changelog $(docdir)/changelog.Debian
            cp -a ChangeLog $(docdir)/changelog
            cd $(docdir) && gzip -9 changelog changelog.Debian
            gzip -r9 debian/tmp/usr/share/man
            gzip -9 debian/tmp/usr/share/info/*
            dpkg-shlibdeps debian/tmp/usr/bin/hello
            dpkg-gencontrol -isp
            chown -R root:root debian/tmp
            chmod -R u+w,go=rX debian/tmp
            dpkg --build debian/tmp ..

    define checkdir
            test -f src/$(package).c -a -f debian/rules
    endef

    binary: binary-indep binary-arch

    checkroot:
            $(checkdir)
            test $$(id -u) = 0

    .PHONY: binary binary-arch binary-indep clean checkroot

Let us go through this file in some detail. One of the first parts you will see is the declaration of some variables:

    package = hello
    docdir = debian/tmp/usr/share/doc/$(package)

    CC = gcc
    CFLAGS = -g -Wall
    INSTALL_PROGRAM = install

    ifeq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
      CFLAGS += -O2
    endif
    ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
      INSTALL_PROGRAM += -s
    endif

This section sets the CFLAGS for the compiler and also handles the `noopt` and `nostrip` DEB_BUILD_OPTIONS for debugging.

Next is the `build` rule:

    build:
    	$(checkdir)
    	./configure --prefix=/usr
    	$(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)"
    	touch build

This rule runs ./configure with the proper prefix, runs make, and creates a `build` file that is a timestamp of the build to prevent erroneous multiple compilations.

The next rule is `clean`, which runs make -i distclean and removes the files that are made during the package building.

    clean:
    	$(checkdir)
    	rm -f build
    	-$(MAKE) -i distclean
    	rm -rf *~ debian/tmp debian/*~ debian/files* debian/substvars

Next we see an empty `binary-indep` rule, because there are no architecture-independent files created in this package.

There are, however, many architecture-dependent files, so `binary-arch` is used:

    binary-arch:    checkroot build
    		$(checkdir)
    		rm -rf debian/tmp
    		install -d debian/tmp/DEBIAN $(docdir)
    		install -m 755 debian/postinst debian/prerm debian/tmp/DEBIAN
    		$(MAKE) INSTALL_PROGRAM="$(INSTALL_PROGRAM)" \
    		prefix=$$(pwd)/debian/tmp/usr install
    		cd debian/tmp && mv usr/info usr/man usr/share
    		cp -a NEWS debian/copyright $(docdir)
    		cp -a debian/changelog $(docdir)/changelog.Debian
    		cp -a ChangeLog $(docdir)/changelog
    		cd $(docdir) && gzip -9 changelog changelog.Debian
    		gzip -r9 debian/tmp/usr/share/man
    		gzip -9 debian/tmp/usr/share/info/*
    		dpkg-shlibdeps debian/tmp/usr/bin/hello
    		dpkg-gencontrol -isp
    		chown -R root:root debian/tmp
    		chmod -R u+w,go=rX debian/tmp
    		dpkg --build debian/tmp ..

First, notice that this rule calls the `checkroot` rule to make sure the package is built as root and calls the `build` rule to compile the source. Then the `debian/tmp/DEBIAN` and `debian/tmp/usr/share/doc/hello` files are created, and the `postinst` and the `prerm>` scripts are installed to `debian/tmp/DEBIAN`. Then make install is run with a prefix that installs to the `debian/tmp/usr` directory. Afterward the documentation files (NEWS, ChangeLog, and the debian changelog) are gzipped and installed. dpkg-shlibdeps is invoked to find the shared library dependencies of the hello executable, and it stores the list in the `debian/substvars` file for the ${shlibs:Depends} variable in `control`. Then dpkg-gencontrol is run to create a control file for the binary package, and it makes the substitutions created by dpkg-shlibdeps. Finally, after the permissions of the `debian/tmp` have been set, dpkg --build is run to build the binary .deb package and place it in the parent directory.

### postinst and prerm

The `postinst` and `prerm` files are examples of maintainer scripts. They are shell scripts that are executed after installation and before removal, respectively, of the package. In the case of the Ubuntu hello package, they are used to install (and remove) the info file. Go ahead and copy them into the current `debian` directory.

    cp ../../ubuntu/hello-2.1.1/debian/postinst .
    cp ../../ubuntu/hello-2.1.1/debian/prerm .

### Building the Source Package

Now that we have gone through the files in the `debian` directory for hello in detail, we can build the source (and binary) packages. First let us move into the root of the extracted source:

    cd ..

Now we build the source package using dpkg-buildpackage:

    dpkg-buildpackage -S -rfakeroot

The -S flag tells dpkg-buildpackage to build a source package, and the -r flag tells it to use fakeroot to allow us to have fake root privileges when making the package. dpkg-buildpackage will take the `.orig.tar.gz` file and produce a `.diff.gz` (the difference between the original tarball from the author and the directory we have created, `debian/` and its contents) and a `.dsc` file that has the description and md5sums for the source package. The `.dsc` and `*_source.changes` (used for uploading the source package) files are signed using your GPG key. If you do not have a GPG key, add the -us -uc flags to the invocation of dpkg-buildpackage. Your package will build but it cannot be uploaded until it is signed.

In addition to the source package, we can also build the binary package with pbuilder:

    dpkg-buildpackage -S -rfakeroot

Using pbuilder to build the binary packages is very important. It ensures that the build dependencies are correct, because pbuilder provides only a minimal environment, so all the build-time dependencies are determined by the `control` file.

We can check the source package for common mistakes using lintian:

    cd ..
    lintian -i *.dsc

Capitolo 3. Basic Packaging |  | Packaging with Debhelper