Warning | |
---|---|
This exercise is a jump up in complexity, so it gets harder to give precise copy-and-paste instructions. It is therefore time to stop sticking closely to the example and start trying to feel your own way through the thicket, still loosely guided by the steps in the exercise. |
The previous exercise still wasn't very realistic. GNU Hello is very well-behaved, but in practice, software makers put their files in the wrong directories, with the wrong permissions. They omit manpages, link against libraries they don't use, hardcode paths and other settings, and generally generate bugs, the list goes on and on. So in practice, software needs to be patched before it can be packaged. Of course you offer your patches to upstream, so patching should be done in nice discrete blocks, so that when upstream copies one of your patches - or fixes a bug in another way -, you don't need to wade through complex multipatches to remove the part that isn't needed any more. To make matters still worse, while you are packaging the new version of some software, a bug may be solved in an older version, and you may need to patch and repackage that.
So this time, we're going to patch the software we package, and we're going to bring our packaging effort under version control, then generate source and binary packages straight from the VCS.
Procedure 2.4. Patching packages
Fetching the package
For this exercise, we are going to work with scaramanga
, which I scripted and actually use for mirroring Ubuntu, as well as a couple of other distros.
It's not very sophisticated, which is perfect for the purpose of this exercise.
And as it is a script, it doesn't need compiling.
cd ~/packaging
mkdir scaramanga
cd scaramanga
wget http://www.cs.rug.nl/~jurjen/scaramanga-0.0.4.tgz
tar zxvf scaramanga-0.0.4.tgz
Initial Debianization
cd scaramanga-0.0.4
dh_make --copyright gpl -f ../scaramanga-0.0.4.tgz --single
Note | |
---|---|
Please verify that trying to build the package fails |
Preparing for scripts instead of compiled programs
Modifying debian/rules
Since packaging doesn't this time involve running configure, make and make install, and installation of files is just a matter of copying, we can simplify debian/rules
:
#!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 build: clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. $(MAKE) clean dh_clean install: dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/scaramanga. $(MAKE) DESTDIR=$(CURDIR)/debian/scaramanga install # Build architecture-independent files here. binary-indep: install dh_testdir dh_testroot dh_installchangelogs dh_installdocs dh_installexamples # dh_install # dh_installmenu # dh_installdebconf # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_python # dh_installinit # dh_installcron # dh_installinfo dh_installman dh_link dh_strip dh_compress dh_fixperms # dh_perl # dh_makeshlibs dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb # We have nothing to do by default. binary: binary-indep .PHONY: clean binary-indep binary install
| |
| |
| |
All the |
Changing the target architecture in debian/control
Disregarding the rest of debian/control
, we can already set the line:
Architecture: all
instead of
Architecture: any
In the any
case, the package building software will try to build packages for any architecture you ask from the source.
In the all
case, only one binary package will be built, which should work on any architecture.
(Am I the only one who finds the terms and meanings counterintuitive?)
Note | |
---|---|
Please verify that running debuild -rfakeroot still fails, and that this is because the Makefile doesn't respect the |
Patching
Now that make install
fails, we can basically do two things.
We can either fix the Makefile, or we can fix debian/rules.
We do the latter, using dpatch
.
Adjusting debian/rules
#!/usr/bin/make -f # -*- makefile -*- <snip> clean: clean-patched unpatch unpatch: dpatch deapply-all rm -rf patch-stamp debian/patched clean-patched: dh_testdir dh_testroot dh_prep ${MAKE} clean rm -rf debian/scaramanga debian/files debian/substvars install: patch-stamp dh_testdir <snip> binary: binary-indep patch: patch-stamp patch-stamp: dpatch apply-all dpatch cat-all >patch-stamp .PHONY: build clean unpatch clean-patched binary-indep binary install patch
Clean before unpatching. This makes sense: reverting patches in a directory that contains files generated by the build process may easily fail. | |
Patch before installing.
In case of a compiled program. patching will come before |
Creating patches
dpatch-edit-patch -d'Altered Makefile to install into $DESTDIR instead of $DEST' 010-Makefile-respect-DESTDIR
That drops us into a shell, in which we edit the Makefile so that it does install into $DESTDIR
if that variable is set.
Note | |
---|---|
Please do so now, and also consider whether that |
When done editing, we exit 0 from the shell, and the patch is created for us in debian/patches
.
Warning | |
---|---|
Please note that it is not a good idea to run |
Listing the patches to be applied
The patch we just created won't be applied during packaging inless we list it in debian/patches/00list
:
echo 010-Makefile-respect-DESTDIR >> debian/patches/00list
Note | |
---|---|
To see whether the patch is indeed applied, run debuild -rfakeroot and see that it runs |
Editing the control files
Note | |
---|---|
By now you should be able to remove the clutter from |
Warning | |
---|---|
Be aware that |
Bringing the packaging under version control
mkdir -p ~/svn-dp-repo
svnadmin create ~/svn-dp-repo
Now that we've got a ../datepipe_0.1.0-1.dsc
, we can use the svn-buildpackage
suite to bring and keep it under version control:
cd ..
mkdir scaramanga-svn
cd scaramanga-svn
svn-inject -l1 ../scaramanga_0.0.4-1.dsc file:///$HOME/svn-dp-repo
<snip lots of lines of output>
Committed revision 5.
Storing trunk copy in /home/jurjen/packaging/scaramanga.
svn checkout file:///home/jurjen/svn-dp-repo/scaramanga/trunk /home/jurjen/packaging/scaramanga -q
Done!
Your working directory is /home/jurjen/packaging/scaramanga - have fun!
Removing tempdir /home/jurjen/packaging/tmp.nErHDqipqz.
cd scaramanga
Note | |
---|---|
Just to keep us in sync: I am now working in |
Building from versioned packaging
svn-buildpackage --svn-ignore --svn-builder=debuild --svn-lintian -rfakeroot -kj.bokma@rug.nl
Note | |
---|---|
The |
Trying out the package
In ../build-area
you can see the various files that svn-buildpackage
has delivered.
Install the binary package on a machine where you have root, and run
scaramanga
This script will only run as scaramanga, which you are not. (You are jurjen).
You can try using sudo:
sudo -u scaramanga /usr/bin/scaramanga
Adding a user during install
Scaramanga refuses to run because it expects to run with the UID of a dedicated user.
The name of that user can be configured in /etc/scaramanga
, but an elegant solution would be to add a user scaramanga
when the package is installed, and remove it when the package is removed.
This is one of the things that can be done in {pre,post}{install,rm}
scripts.
To be precise, debian/preinstall
and debian/postrm
are the scripts to add.
Because we removed the {preinstall,postrm}.ex
in a previous step, and because our working directory now has a name that dh_make
doesn't understand, we cannot use dh_make -a to give us back our examples.
But we can copy the examples straight out of /usr/share/debhelper/dh_make/debian/
.
For convenience, I will give example here of preinst
:
#!/bin/sh # preinst script for scaramanga # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * <new-preinst> `install' # * <new-preinst> `install' <old-version> # * <new-preinst> `upgrade' <old-version> # * <old-preinst> `abort-upgrade' <new-version> # for details, see http://www.debian.org/doc/debian-policy/ or # the debian-policy package case "$1" in install|upgrade) addgroup --system scaramanga adduser --system --no-create-home --ingroup scaramanga --disabled-password --disabled-login --gecos 'mirrorer' scaramanga mkdir /srv/mirror ;; abort-upgrade) ;; *) echo "preinst called with unknown argument \`$1'" >&2 exit 1 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0
Providing sensible defaults
Note | |
---|---|
Now that our |
Committing changes to version control
It is time to commit our changes:
svn add debian/preinstall
svn add debian/patches/200-provide-sensible-default-config.dpatch
svn commit -m "added preinstall and cleaned up config file"
Note | |
---|---|
Notice that svn-buildpackage without the |
svn propedit svn:ignore debian
An editor pops up (if you set $EDITOR) and you enter:
*.debhelper.log
svn commit -m"set svn:ignore on debian to include debhelper log"
svn-buildpackage --svn-builder=debuild --svn-lintian -rfakeroot -kj.bokma@rug.nl
Adding to the changelog
Then we want to update debian/changelog
.
This is done through creating a new tag:
svn-buildpackage --svn-builder=debuild --svn-tag --svn-lintian -rfakeroot -kj.bokma@rug.nl
Then editing debian/changelog
:
scaramanga (0.0.4-2) unstable; urgency=low * Added preinstall to create mirrordir and dedicated user, and provided sensible default config -- Jurjen Bokma <j.bokma@rug.nl> Sun, 04 Oct 2009 21:07:21 +0200 scaramanga (0.0.4-1) unstable; urgency=low * Initial release (Closes: #9999) -- Jurjen Bokma <j.bokma@rug.nl> Sat, 03 Oct 2009 20:57:15 +0200
And re-building:
svn-buildpackage --svn-builder=debuild -rfakeroot -kj.bokma@rug.nl
Note | |
---|---|
Now rebuild the package using svn-buildpackage with the appropriate options, upload it to the target system, rebuild the repository indices, install the package, and see whether it works. |
Warning | |
---|---|
Please be advised that if you had omitted updating the changelog and hadn't used a simple local repository that rebuilds its entire index with each upload, but a more sophisticated one like |
Note | |
---|---|
Note that sudo -u scaramanga /usr/bin/scaramanga -d debian still fails because the default directory to mirror to doesn't exist. Fix that and rebuild. |