Marc Wäckerlin
Für eine libertäre Schweiz

«Debianize» a Project

August 8, 2014

This is outdated, use my new bootstrap-build-environment project instead! (new blog post for that topic will follow)

This article describes, how to add fully automated Debian package building to an existing project, as preparation for a Jenkins build job. Good projects are based on the GNU Buildsystem, that means, they are built by invoking ./configure && make all install. A new buildtarget will be added, so that make deb creates debian packages.

Add Build Number

Debian packages often contain an additional buildnumber, instead of a package name with a simple version number, so they are numbered, e.g. packagename-1.0.0~wheezy.4. When setting up a repository using reprepro, this will be important, because reprepro puts all the files in a flat directory with no separate pathes for the distribution, so a file packagename-1.0.0 produces a checksum conflict, if the same file exists for two different distributions, such as for Debian Wheezy and for Ubuntu Trusty. They consider this as a feature, I consider it as a bug. Anyway, let’s work around it.

The solution is, that the package builder adds an optional local file containing the additional build text. I name the file build-string. To append ~wheezy.4, call echo -n "~wheezy.4" > build-string before executing aclocal && automake -a && automake (I hide these calls in file ./bootstrap.sh).

In file configure.in, the file is appended to the version number. if you normally call AC_INIT(packagename, 1.0.0) to initialize the package name and version number1. Now we simply have to add the file inclusion:

In file configure.in add:

AC_INIT(packagename, 2m4_esyscmd_s(
  if test -f build-string; then
    cat build-string
  fi
))

The file build-string should be included in your distribution. If not available, an empty file should be provided.

In global makefile.am add:

EXTRA_DIST = build-string

build-string:
	touch build-string

MAINTAINERCLEANFILES = build-string

Variables for Configuration

Configure allows you convert *.in-files by replacing some variables. This is what we do:

  • The first line in README shall be the package description, as title, followed by an empty line
  • Beginning from the third line in README, there follows the full text
  • File AUTHORS should be copied to debian
  • Variable DISTRO should contain the distribution name

In file configure.in add:

README=$(tail -n +3 README)
README_DEB=$(tail -n +3 README | sed -e 's/^$/./g' -e 's/^/ /g')
DESCRIPTION=$(head -1 README)
AUTHOR=$(head -1 AUTHORS)
AC_SUBST(AUTHOR)
_AM_SUBST_NOTMAKE([AUTHOR])
AC_SUBST(DESCRIPTION)
_AM_SUBST_NOTMAKE([DESCRIPTION])
AC_SUBST(README)
_AM_SUBST_NOTMAKE([README])
AC_SUBST(README_DEB)
_AM_SUBST_NOTMAKE([README_DEB])
DISTRO=$(lsb_release -sc)
AC_SUBST(DISTRO)

AC_OUTPUT

Debian Files Generated by Configure

To build Debian packages, a subdirectory debian is required for configuration files. Configure creates a makefile and in addition the following files in the debian subdirectory:

  • debian/changelog
  • debian/control

In configure.in add:

AC_CONFIG_FILES(makefile debian/changelog debian/control)

Files Required

GNU Build System

configure.in

AC_INIT(projectname, 1.0.0m4_esyscmd_s(
  if test -f build-string; then
    cat build-string
  fi
))

AM_INIT_AUTOMAKE(3)

AC_CONFIG_FILES(makefile debian/changelog debian/control)

README=$(tail -n +3 README)
README_DEB=$(tail -n +3 README | sed -e 's/^$/./g' -e 's/^/ /g')
DESCRIPTION=$(head -1 README)
AUTHOR=$(head -1 AUTHORS)
AC_SUBST(AUTHOR)
_AM_SUBST_NOTMAKE([AUTHOR])
AC_SUBST(DESCRIPTION)
_AM_SUBST_NOTMAKE([DESCRIPTION])
AC_SUBST(README)
_AM_SUBST_NOTMAKE([README])
AC_SUBST(README_DEB)
_AM_SUBST_NOTMAKE([README_DEB])
DISTRO=$(lsb_release -sc)
AC_SUBST(DISTRO)

AC_OUTPUT

automake.am

EXTRA_DIST = debian bootstrap.sh build-string

dist_bin_SCRIPTS = setup-debootstrap.sh

deb: distdir
	cd ${distdir} && dpkg-buildpackage

build-string:
	touch build-string

distclean-local:
	-rm -rf ${distdir}

MAINTAINERCLEANFILES = configure ltmain.sh INSTALL COPYING aclocal.m4	\
                       install-sh missing makefile.in @PACKAGE@_@VERSION@* \
                       debian/changelog debian/control build-string

Debian Configuration

debian/changelog.in

The author from file AUTHORS, here inserted as @AUTHOR@ must be identical to the name of key which is used to sign the package. Here the developer is the packager. Otherwise replace the generic @AUTHOR@ by the packager’s GPG key name.

@PACKAGE@ (@VERSION@) @DISTRO@; urgency=low

  * Please see ChangeLog of @PACKAGE@

 -- @AUTHOR@  Mon, 02 Jul 2012 10:27:36 +0200

debian/control.in

This is an example, change it to your needs.

Source: @PACKAGE@
Section: devel
Priority: extra
Maintainer: @AUTHOR@
Build-Depends: debhelper, autotools-dev, subversion-tools, lsb-release
Standards-Version: 3.9.2

Package: @PACKAGE@
Architecture: all
Depends: ${misc:Depends}
Description: @DESCRIPTION@
@README_DEB@

debian/rules

#!/usr/bin/make -f

%:
        dh $@ 
  1. In fact, I have the least-version number to be the subversion revision number, which is automatically detected, but here in this example I’ll keep is short and simple
  2. 0.0
  3. 9 tar-pax

comments title