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 (http://www.debian.org/doc/manuals/maint-guide/) should be referred to!|
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.
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:
These can be installed via the following command:
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:
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:
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.
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
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.
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.
Again many examples can be found online of these files.
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.
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:
Note that these deb-helper scripts not only copy files to their correct location but also index them such that applications know the existence 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.
Use deb-helper, it's awesome!
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 relevant place and you don't have to worry about it.
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.:
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:
(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:
Building your package
Most commonly a package can be built with the following command (from the my-package_1.0.0 directory):
However if you are feeling clever and want it to automatically build a version in git (from the directory managed by git)
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 http://keyring.debian.org/creating-key.html. 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:
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:
Verifying your Package
|No package will be accepted into any Debian Repository while it contains Lintian Errors! Fix them!|
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.
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
- 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.).
Apr 23, 2013
Johan van der Knijff
As a follow-up to this, in the blog post below I describe how I used this guide to create Debian packages for jpylyzer:
Two minor corrections (I think) to this guide:
1. in the Getting Started section:
Directory name: by default, Dh_make doesn't accept package and version names that are separated by underscores (''), and expects a dash('-') instead. Underscores are only allowed in combination with the _-p flag.
2. in the Verifying your Package section:
I think this should be the other way round?