Because I’ll be deploying a new server in the near future and I want to keep it as clean as possible I decided (again) to try to find out how to create a .deb package (as used for example by Debian and Ubuntu Linux) for some software that doesn’t follow the autotools way of doing things. This time I found a/the way. But first some background info.

In the Unix/Linux world many programs are compiled from source in three steps:

make install

Usually the necessary files for this have been created using the autotools. The goal of the first step is to create a so-called Makefile that contains instructions on how to compile and install the files (as done in the two subsequent make steps.

Some software packages, however, include a ready-made Makefile that, in addition, doesn’t accept the environment variable DESTDIR. This last point is what makes packaging the application into a .deb file a bit tricky. The reason for this is that the package build scripts want to install the files of your application in a temporary directory and not into system-wide directories like /usr/bin/ etc. during the packing process. As such, packaging does not require root privileges.

At work we use many programs and tool sets developed by ourselves and other scientists. I know from my own experience that setting up autotools for your program is not trivial. Actually, for lack of time I’ve never successfully done it and for most of the rather simple programs that I’ve written setting up a complete autoconf/automake environment seems a bit overkill. I usually ended up writing a simple Makefile that compiles to code and installs it (usually in /usr/local/bin).

Merlin by Abecasis et al. is a great piece of software developed at the University of Michigan. However, as you may have expected by now, its Makefile does not accept the DESTDIR variable, instead running make tells you that in order to install in a different directory you’ll have to run

make INSTALLDIR=/some/other/directory

Therefore, all quick and dirty .deb recipes one finds on the Internet do not work without some adaptations. So here is what I did to make a .deb of it. It won’t be a full tutorial on how to do packaging, see the references at the end of this post for that. I’ll assume here that you have your build environment set up (e.g. the build-essential and fakeroot packages, as well as some others).

tar -xzf merlin-1.1.2.tar.gz
cd merlin-1.1.2
dh_make --single --email youremail@address --file ../merlin-1.1.2.tar.gz

Now the basic files are ready. Apart from the untarred source files the files needed for Debian packaging have also been created (in merlin-1.1.2/debian).

Time to make the necessary changes. First, since the Makefile included with merlin does not accept the DESTDIR variable that the Debian packaging system uses we’ll patch the Makefile in such a way that it works (I tried to fix this in the debian/control file, but in the end adapting the Makefile was much easier). I do this by changing the line



# default installation directory
ifeq ($(DESTDIR),"")

Let’s do some polishing of the package. I don’t want to make the perfect package, but adding a bit of text to the debian/control file make a lot of difference. This is what it looked like after my edits:

Source: merlin
Section: science
Priority: extra
Maintainer: Lennart C. Karssen <youremail@address>
Build-Depends: debhelper (>= 7)
Standards-Version: 3.8.3
Package: merlin
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Package for fast pedigree analysis
 MERLIN uses sparse trees to represent gene flow in pedigrees
 and is one of the fastest pedigree analysis packages around
 (Abecasis et al, 2002).

Also editing the file debian/changelog is a good idea, especially since I changed the source code (remember the Makefile?). This is what I wrote:

merlin (1.1.2-1) unstable; urgency=low
  * Initial release
  * Adjusted Makefile to make DESTDIR work.
 -- Lennart C. Karssen <youremail@address>  Tue, 05 Apr 2011 12:04:21 +0200

Officially you should edit the debian/copyright file as well, but since the merlin licence doesn’t allow distribution of the source or the binaries I didn’t bother.

To finally build the package run

dpkg-buildpackage -rfakeroot -us -uc

This creates a .deb file in the directory where you started. As a final touch you can check your package for errors with

lintian ../merlin_1.1.2-1_amd64.deb


Related Images: