Packaging scripts for Debian

June 2009


There is a lot of info on Debian packaging, but it's a bit scattered. The Wikipedia page on the Debian build toolchain is a good place to start. The Complete Guide to Packaging for Ubuntu has many useful links. Those to the Debian New Maintainers' Guide and the Debian Binary Package Building HOWTO should be mentioned here, as well as the Debian Policy Manual and the Debian Developers' Reference.

When delving deeper, the PBuilder HOWTO (on cleanroom building) and the Common Debian Build System should be read.

  1. Create a script to package

    Well, I had got a script, firewall, which I wanted to package. So I made a directory, of which the name must be of the form <name>-<version>, and I created a tree below it:

    find firewall-0.0.3/
    firewall-0.0.3/
    firewall-0.0.3/etc
    firewall-0.0.3/etc/init.d
    firewall-0.0.3/etc/init.d/firewall
    firewall-0.0.3/etc/firewall
    firewall-0.0.3/etc/firewall/rules.stop
    firewall-0.0.3/etc/firewall/rules.start
    firewall-0.0.3/usr
    firewall-0.0.3/usr/sbin
    firewall-0.0.3/usr/sbin/firewall
    firewall-0.0.3/usr/sbin/fire_stop

  2. Create a Makefile

    We need a minimal Makefile in firewall-0.0.3:

    all:
    clean:
    
    install:
    install -d $(DESTDIR)/etc/firewall
    install -m 755 etc/init.d/firewall $(DESTDIR)/etc/init.d/
    install -m 755 usr/sbin/firewall $(DESTDIR)/usr/sbin/
    install -m 755 usr/sbin/fire_stop $(DESTDIR)/usr/sbin/
    install -m 600 etc/firewall/rules.start $(DESTDIR)/etc/firewall/rules.start
    install -m 600 etc/firewall/rules.stop $(DESTDIR)/etc/firewall/rules.stop
    	

  3. Creating the debian directory:

    We need to create a debian directory for a single package, and there is no original tar bundle, so from firewall-0.0.3 we call:

    dh_make -e j.bokma@cs.rug.nl --native -s

  4. Editing in the debian dir

    The most important file is control. Be sure, when creating packages that contain only scripts, that the Architecture is all. In that case, only one binary package will be built for all architectures. If OTOH you set it to any, packages will be built for all architectures, one for each.

    Now also create suitable preinst, postinst, prerm and postrm scripts. update-rc.d should be called from post{inst,rm}. Starting and stopping services should be done through invoke-rc.d:

    if which invoke-rc.d >/dev/null 2>&1; then
        invoke-rc.d firewall stop
    else
        /etc/init.d/firewall stop
    fi
    	

  5. Create the package

    dpkg-buildpackage
    dpkg-buildpackage: set CFLAGS to default value: -g -O2
    dpkg-buildpackage: set CPPFLAGS to default value:
    dpkg-buildpackage: set LDFLAGS to default value:
    dpkg-buildpackage: set FFLAGS to default value: -g -O2
    dpkg-buildpackage: set CXXFLAGS to default value: -g -O2
    dpkg-buildpackage: source package firewall
    dpkg-buildpackage: source version 0.0.3
    dpkg-buildpackage: source changed by Jurjen Bokma <j.bokma@rug.nl>
    dpkg-buildpackage: host architecture amd64
    fakeroot debian/rules clean
    dh_testdir
    dh_testroot
    rm -f build-stamp configure-stamp
    # Add here commands to clean up after the build process.
    /usr/bin/make clean
    make[1]: Entering directory `/home/jurjen/packaging/firewall-0.0.3'
    make[1]: Nothing to be done for `clean'.
    make[1]: Leaving directory `/home/jurjen/packaging/firewall-0.0.3'
    dh_clean
    dpkg-source -b firewall-0.0.3
    dpkg-source: info: using source format `1.0'
    dpkg-source: info: building firewall using existing firewall_0.0.3.orig.tar.gz
    dpkg-source: info: building firewall in firewall_0.0.3.diff.gz
    dpkg-source: warning: newly created empty file 'debian/docs' will not be represented in diff
    dpkg-source: warning: file firewall-0.0.3/debian/dirs has no final newline (either original or modified version)
    dpkg-source: warning: ignoring deletion of file firewall.sh~
    dpkg-source: warning: ignoring deletion of file etc/init.d/firewall~
    dpkg-source: warning: ignoring deletion of file etc/firewall/rules.start~
    dpkg-source: warning: ignoring deletion of file usr/sbin/firewall~
    dpkg-source: info: building firewall in firewall_0.0.3.dsc
    debian/rules build
    dh_testdir
    # Add here commands to configure the package.
    touch configure-stamp
    dh_testdir
    # Add here commands to compile the package.
    /usr/bin/make
    make[1]: Entering directory `/home/jurjen/packaging/firewall-0.0.3'
    make[1]: Nothing to be done for `all'.
    make[1]: Leaving directory `/home/jurjen/packaging/firewall-0.0.3'
    #docbook-to-man debian/firewall.sgml > firewall.1
    touch build-stamp
    fakeroot debian/rules binary
    dh_testdir
    dh_testroot
    dh_clean -k
    dh_installdirs
    # Add here commands to install the package into debian/firewall.
    /usr/bin/make DESTDIR=/home/jurjen/packaging/firewall-0.0.3/debian/firewall install
    make[1]: Entering directory `/home/jurjen/packaging/firewall-0.0.3'
    install -d /home/jurjen/packaging/firewall-0.0.3/debian/firewall/etc/firewall
    install -m 755 etc/init.d/firewall /home/jurjen/packaging/firewall-0.0.3/debian/firewall/etc/init.d/
    install -m 755 usr/sbin/firewall /home/jurjen/packaging/firewall-0.0.3/debian/firewall/usr/sbin/
    install -m 755 usr/sbin/fire_stop /home/jurjen/packaging/firewall-0.0.3/debian/firewall/usr/sbin/
    install -m 600 etc/firewall/rules.start /home/jurjen/packaging/firewall-0.0.3/debian/firewall/etc/firewall/rules.start
    install -m 600 etc/firewall/rules.stop /home/jurjen/packaging/firewall-0.0.3/debian/firewall/etc/firewall/rules.stop
    make[1]: Leaving directory `/home/jurjen/packaging/firewall-0.0.3'
    dh_testdir
    dh_testroot
    dh_installchangelogs
    dh_installdocs
    dh_installexamples
    dh_installman
    dh_fixperms
    dh_installdeb
    dh_shlibdeps
    dh_gencontrol
    dpkg-gencontrol: warning: unknown substitution variable ${shlibs:Depends}
    dpkg-gencontrol: warning: unknown substitution variable ${misc:Depends}
    dh_md5sums
    dh_builddeb
    dpkg-deb: building package `firewall' in `../firewall_0.0.3_all.deb'.
    signfile firewall_0.0.3.dsc

    You need a passphrase to unlock the secret key for
    user: "Jurjen Bokma <j.bokma@rug.nl>"
    1024-bit DSA key, ID F81A6012, created 2008-05-07


    dpkg-genchanges  >../firewall_0.0.3_amd64.changes
    dpkg-genchanges: including full source code in upload
    signfile firewall_0.0.3_amd64.changes

    You need a passphrase to unlock the secret key for
    user: "Jurjen Bokma <j.bokma@rug.nl>"
    1024-bit DSA key, ID F81A6012, created 2008-05-07


    dpkg-buildpackage: full upload (original source is included)

  6. Check the package with lintian

    lintian ../firewall_0.0.3_all.deb
    W: firewall: binary-without-manpage usr/sbin/fire_stop
    W: firewall: binary-without-manpage usr/sbin/firewall
    W: firewall: readme-debian-contains-debmake-template
    W: firewall: changelog-file-not-compressed changelog

Now the package is ready, and it can be uploaded or installed. Of course, you wish to test it, by installing and deinstalling and reinstalling.