I’ve always been a fan of compiling certain programs from source instead of relying on the choices made by some Linux distribution-maintainer. The reason for this is that Linux distributions often provide oldish versions of a particular program, whereas I want to (or need to) have bleeding-edge code running. (One example that comes to mind is the ancient OpenLDAP version provided by RedHat.) Compiling from source is typically made easy by the ./configure; make; make install trio. I specify the exact options I want to ./configure, can set environment variables to tweak something, hack into the configure script (seldom necessary), and then install the result, or even just copy what I need to its destination directories. This is all fine and dandy when I need the software on a single machine, but doing all that on a number of servers is tedious and error-prone, quite apart from the fact that such installations cannot be “undone” or catalogued in the system’s list of installed software. Updates are forgotten or ignored, un-installation becomes nearly impossible, etc. Theoretically it would be possible to do the source- configuration and installation from Puppet, but that becomes really messy. In other words, creating packages distribution to my server “farm” becomes a must. Depending on whether I need the package on a RedHat- or Debian-based machine, the tools differ, the dependencies are different, etc., etc., etc. Packaging is a royal PITA, and I’ve always tried to avoid doing it. (If you don’t believe me, take a look at one of a multitude of .spec files for a BIND name server, say, and you’ll see what I mean.) Even within similar distributions (Fedora, RHEL, …) the packaging recipes differ. I believe I’ve found a very good solution, at least for myself, and you may like it as well. The program is called checkinstall, and I think of it as a shim between ./configure and the target binary package. To build a package I proceed as follows:

  1. Obtain the source of the program I want to build, and unpack it into a new directory.
  2. Run ./configure and make until I’m satisfied with the result.
  3. I then run checkinstall within that directory. checkinstall asks a few questions and then builds a package, an .rpm, say, from the result of a make install.
  4. Test the result by installing the package.

The way checkinstall works is it runs the make install on my behalf, recording the file operations that an install would have done. (It does this with the aid of an $LD_PRELOAD library.) By default checkinstall does not install the files on the build system; I’ll want to do that with the final package. It then bundles up the result and builds a package (Slackware, Debian, or RPM). checkinstall has rudimentary support for executing pre- and post-scripts, it can install documentation. I can invoke checkinstall with options which override some of the “magic” it has determined by itself. (Above screen shot gives an idea of the values checkinstall has determined automatically.) I’ve only just started using checkinstall, but I like it already. Update: Kris points me to fpm, which also looks quite good.

Linux, CLI, yum, and rpm :: 17 Mar 2011 :: e-mail