View Source

h1. Debian Packaging (.deb)

In order to increase the adoption and sustainability of the tools delivered by SCAPE we will be creating Debian packages that aid the end-user in installing and easily deploy these tools in literally hundreds of servers.

This guide is intended ONLY as a reference for getting started. Once you are comfortable with the tools and the challenges then the official maintainers guide ([]) should be referred to\! 

h2. What you must end up with

A file named something like *package-name_1.3.2_amd64.deb* 

Lets explain the parts:

*package-name*: A *short* name which perfectly describes your package, e.g. droid, ffmpeg, vlc. The package name should be something searchable beyond the lifetime of the project and should not include any project names or names of technologies that are likely to disappear. The package name should be transferable to a future maintainer without needing to be changed. 

*1.3.2*: The version number in *X.Y.Z* format conforms to the Debian and GNU version numbering standard of major.minor.revision. For clarity these are explained here:

*X (major):* A major release where usage of the tool changes significantly, either via user interface or API. If you change the function of an existing API call then this version number *MUST* be incremented. It basically tells other systems that they may not work any more. 

*Y (minor):* Functionality and API calls can be added but existing ones *MUST* remain the same. 

*Z (revision)*: For security patches and bug fixes only\! All *Z* revisions *SHOULD* relate to one or more tickets raised in an issue tracker. 

*\_amd64*: The supported architecture (other examples include *i386* and *all*). Ideally tools which are not architecture dependant should be distributed as *all*.

h2. Pre-Requisites

Firstly you will need a debian/ubuntu machine which is capable of running the tool you wish to package or compile. Ideally this should be a *Ubuntu LTS* (10.04, 12.04 etc) machine which is most likely to be supported by the institutions who wish to run your tool. 

*Note:* If you are compiling your tool with static libraries (e.g. from Python to C) then any debian/ubuntu distribution can be used to *build* the package, however *testing* the package to be distributed on a *Ubuntu LTS* version *SHOULD* be carried. 

On your build machine you will need the following packages: 
* build-essential
* dh-make
* devscripts
* debhelper 
* lintian

These can be installed via the following command:

sudo apt-get install build-essential dh-make devscripts debhelper lintian

h2. Getting Started

Typically here there are 2 situations:
# You have a piece of software that is *already* installable using ./configure, make and make install (i.e. it has a makefile). In this situation all that is needed is to carry out the "_debianisation"_. This is where the maintainers guide (+[+|]+) is excellent as this is the main case it outlines.
# Your package does not have a makefile and has never been made _installable_. The first question to ask here is should it? Would it make sense to have a makefile which can build and/or install your package. This way you can easily build and install it on most platforms that support make. If not then do continue here and you'll hopefully find out later in the process where a makefile comes in useful.

In either situation you will need to end up with a directory containing your application and this directory *MUST* be named something like my-package_1.0.0. So if you *don't* have one already:

mkdir my-package_1.0.0
If you have got here and you don't have any already packaged code (a tar ball with makefile etc) then you will need to build a *native* package. Otherwise the steps here stay the same:

cd my-package_1.0.0
dh_make --help
Follow the dh_make help text to fill in your _name, email_ and any other details. Typically you will be building a _single (-s)_ package.
Note also that the package name should match the folder prefix (e.g. my-package). Doing this later will get you all confused\! 

If this command executes correctly you will end up with a *debian* folder full of example files (all explained in the maintainers guide). You only really need to focus on 4 of them. *Control, Rules, Copyright* and *Changelog*.

h2. The control file

This file tells the packaging system about your package. It contains the following information:
* Package Name
* Package Short Description
* Package Long Description

These are used to allow people to find your package among every other package, choose your words carefully, ask yourself how someone with no knowledge of the package might find it. 
* Developer Name
* Homepage

Then the even more essential bits:
* Compatible Architecture 
** Choose from ALL, ANY, i386, i686, amd64, ia64, sparc64, ...
* Build Dependencies (Build-Depends\:)
* Run Dependencies (Depends\:)

Note that the build dependencies could be completely different from the required run dependencies and thus are treated completely separate. 

h2. The copyright

Yes yes, boring but an absolute requirement. Make sure you separate the copyright of the upstream code (i.e. the program) from any copyright on the packaging files. If the upstream code is a combination of libraries then *ALL* copyright and licensing for these must also be detailed. A trick here is to use paths e.g. 

Copyright: The National Archives (UK)
License: .....
Copyright: ...
Again many examples can be found online of these files. 

h2. The changelog

If you are using a revision control system properly (with branches and tags) then you should just be able to generate the changelog automatically from your commit history up until the tag you are currently packaging. The changelog should detail all changes to the upstream code, however many also use it to detail the changes to the packaging files. 

If you are generating the changelog from the commit history (which you should) then please don't commit the changelog to your revision control system\! As soon as you commit it, it is already out of date.

Note that the changelog is really fussy in its format, but it is a format vim recognises. 

In order to make the process of generating a changelog for a github hosted project easier, the OPF has written a GitHub 2 Changelog service (url coming soon). Using this you can simply add a call to this service to your *rules* file and download the changelog as part of the package building process. 

h2. The rules file

This file is a makefile that should *only contain debian specific* make rules. Typically it is used to call ./configure, make and make install of the upstream code and provide pathing information in order to build a binary package ready for distribution.

Additionally however, the deb-helper scripts are also called from this file to automatically install items like documentation, manpages and set up any configuration interfaces for the package. These deb-helper scripts can (and should) also be used to verify that the system being used for both building and installing the package is in the correct state.

The following is an example _install_ section:

binary-indep: install
dh_testdir <\- test required directories exist
dh_testroot <\- test the user has root privileges
dh_installchangelogs <\- copy the changelogs to the correct location on whatever platform
dh_installdocs <\- copy the documentation to the correct location
dh_installexamples <\- copy the examples to the correct location
dh_installman <\- copy the man page to the correct location
dh_installdebconf <\- set up the configuration wizard for the user
Note that these deb-helper scripts not only copy files to their correct location but also index them such that applications know the&nbsp;existence&nbsp;of the man page (for example) and can guide the user to this resource (e.g. through tab completion).

installdebconf is perhaps the most obvious example of this. Deb Conf allows you to prompt the user for input whilst the package is being installed. Deb Conf automatically creates the interface in which this is done, e.g. via a terminal (ncurses) or via a full GUI.&nbsp;

Use deb-helper, it's awesome\!&nbsp;

h2. Specifying a manpage, doc, example etc

# In your debian directory create a file called my-package.\[docs,manpages,examples\]
# List the paths of the files which are these in this file.


These files are which is read by dh_install\[docs,examples,man\]

and thus the files listed on each line are copied to the&nbsp;relevant&nbsp;place and you don't have to worry about it.

h2. Specifying arbitrary files (anything that doesn't fit into the above categories)

*Step 1:* Create a _my-package.install_ file in the _debian_ folder (e.g. _jpwrappa.install_ for package _jpwrappa_). In this file each line represents a pair of source/destination paths, e.g.:

jpwrappa/config.xml etc/jpwrappa
jpwrappa/profiles/* etc/jpwrappa/profiles/

In the above example the files will be installed in directory _/etc/jpwrappa_ on the destination system. Do _not_ prepend file paths by any '/' characters!

*Step 2*: Add destination directories to /debian/dirs, e.g.:


(Actually I'm not even 100% sure if this step is absolutely necessary - please try for yourself!)

*Step 3*: Add _dh_install_ command to _/debian/rules_, e.g. like this:

# Build architecture-independent files here.
binary-indep: install

(Note: I have no idea about the 'proper' place to put this, but at least it works!).

The information in this subsection is based on the following sources:

[Stack Overflow|]

[Ubuntu Manpage on _dh_install_|]

h2. Building your package

Most commonly a package can be built with the following command (from the my-package_1.0.0 directory):

dpkg-buildpackage -tc
However if you are feeling clever and want it to automatically build a version in git (from the directory managed by git)


h2. Building a Signed Debian Package (and dealing with the fall out)

If you want to build a fully signed debian package, which you should\! Then you will need to first generate a key (if you don't have one).

A good guide to generating a key can be found at&nbsp;[|]. Once you have your key KEEP IT REALLY SAFE.

To build your package with this key you will need a command like the following one:

dpkg-buildpackage -tc -k594F7FBA
Note that if you are building an i386 and amd64 version of a package, potentially on two different machines then you need to check the hashes of the .dsc and .tar.gz files match in the two changes files\!

If they do not match then you will need to hack this by picking one of the tar.gz's and dsc's and matching the hashes to the actual files you have in one of the files.

Once this is done, remove the PGP sections at the top and bottom of the .changes file and then re-sign the changed file using the following command:

debsign -k594F7FBA my-package_1.0.0_i386.changes

h2. Verifying your Package

No package will be accepted into any Debian Repository while it contains Lintian Errors\! Fix them\!&nbsp;
Lintian is the tool used to verify your package is well formed (not that it works). As well as looking at install paths, dependencies and well formed control files, lintian also checks spelling and other common errors that are made during the package building process.&nbsp;

Lintian only works on a built package and can be used by issuing the following command:lintian my-package_1.0.0_all.deb
Output lines start with one of the following:
* *I:* Information Message&nbsp;
* *E:* Error (should be fixed)
* *W:* Warning (must be fixed)

More information on most of the errors and warnings can be found online ([More info.|]).