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
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
- Obtain the source of the program I want to build, and unpack it into a new directory.
makeuntil I’m satisfied with the result.
- I then run
checkinstallwithin that directory.
checkinstallasks a few questions and then builds a package, an
.rpm, say, from the result of a
- 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.