[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ next ]


Debian New Maintainers' Guide
Chapter 3 - Modifying the source


Please note that there isn't space here to go into all the details of fixing upstream sources, but here are some basic steps and problems people often run across.


3.1 Set up quilt

The quilt program offers the basic method to record modification to the source for the Debian packaging. Since slightly different default is desirable for Debian packaging, let's set up ~/.quiltrc as follows. [11]

     d=. ; while [ ! -d "$d/debian" -a `readlink -e $d` != / ]; do d="$d/.."; done
     if [ -d "$d/debian" ] && [ -z "$QUILT_PATCHES" ]; then
         # Debian packaging case and unset $QUILT_PATCHES
         QUILT_PATCHES=debian/patches
         QUILT_PATCH_OPTS="--unified-reject-files"
         QUILT_DIFF_ARGS="-p ab --no-timestamps --no-index --color=auto"
         QUILT_REFRESH_ARGS="-p ab --no-timestamps --no-index"
         QUILT_COLORS="diff_hdr=1;32:diff_add=1;34:diff_rem=1;31:diff_hunk=1;33:diff_ctx=35:diff_cctx=33"
         if ! [ -d $d/debian/patches ]; then mkdir $d/debian/patches; fi
     fi

See quilt(1) and /usr/share/doc/quilt/quilt.html for how to use quilt.


3.2 Fixing upstream bug

Let's assume you find an error in the upstream Makefile file as follows where "install: gentoo" should have been "install: gentoo-target".

     install: gentoo
             install ./gentoo $(BIN)
             install icons/* $(ICONS)
             install gentoorc-example $(HOME)/.gentoorc

Let's fix this and record this with the quilt command as fix-gentoo-target.patch. [12]

     $ mkdir debian/patches
     $ quilt new fix-gentoo-target.patch
     $ quilt add Makefile

You change the Makefile file as follows.

     install: gentoo-target
             install ./gentoo $(BIN)
             install icons/* $(ICONS)
             install gentoorc-example $(HOME)/.gentoorc

Ask quilt to refresh the patch to create debian/patches/fix-gentoo-target.patch and add its description.

     $ quilt refresh
     $ quilt header -e
     ... describe patch

3.3 Installation of files to the destination

Normally, programs install themselves in the /usr/local subdirectory. Since it is reserved for system administrator's (or user's) private use, Debian packages must not use that directory but should use system directories such as the /usr/bin subdirectory following the Filesystem Hierarchy Standard (FHS, /usr/share/doc/debian-policy/fhs/fhs-2.3.html).

Normally, make(1) is used to automate building the program and the execution of "make install" installs programs directly to the desired destination by the install target of the Makefile file. In order for Debian to provide binary packages, the build system installs programs to the file tree image created under a temporary directory instead to the actual destination.

These 2 differences between (1) the normal program installation and (2) the Debian packaging can be transparently addressed by the debhelper package through the dh_auto_configure and dh_auto_install commands if the following conditions are met.

Programs that use GNU autoconf automatically follow the GNU conventions and their packaging is almost automatic. With this and other heuristics, the debhelper package estimates that it works for about 90% of packages without making any intrusive changes to their build system. So the packaging is not as complicated as it may seem.

If you need to make changes in the Makefile file, you should make sure to support these $(DESTDIR) variable. The $(DESTDIR) variable is unset in it and is prepended to each file path used for the program installation. The packaging script will set $(DESTDIR) to the temporary directory.

The temporary directory used by the dh_auto_install command is chosen as debian/package for single binary packages. [13] Everything that is contained in the temporary directory will be installed on a user's system when they install your package, the only difference is that dpkg will be installing the files in the root directory.

Bear in mind that even though your program installs in debian/package, it still needs to behave correctly when placed in the root directory, i.e. when installed from the .deb package. So you must not allow the build system to hardcode strings like /home/me/deb/package-version/usr/share/package into the package file.

Here's the relevant part of gentoo's Makefile file [14]:

     # Where to put binary on 'make install'?
     BIN     = /usr/local/bin
     
     # Where to put icons on 'make install'?
     ICONS   = /usr/local/share/gentoo

We see that the files are set to install under /usr/local. Change those paths to:

     # Where to put binary on 'make install'?
     BIN     = $(DESTDIR)/usr/bin
     
     # Where to put icons on 'make install'?
     ICONS   = $(DESTDIR)/usr/share/gentoo

But why in that directory, and not some other? Because Debian packages never install files beneath /usr/local -- that tree is reserved for the system administrator's use. Such files on Debian systems go under /usr instead.

The more exact locations for binaries, icons, documentation etc. are specified in the Filesystem Hierarchy Standard (see /usr/share/doc/debian-policy/fhs/). I recommend you browse it and read the sections that might concern your package.

So, we should install the binary in /usr/bin instead of /usr/local/bin, the manual page in /usr/share/man/man1 instead of /usr/local/man/man1 etc. Notice how there's no manual page mentioned in gentoo's Makefile, but since the Debian Policy requires that every program has one, we'll make one later and install it in /usr/share/man/man1.

Some programs don't use Makefile variables to define paths such as these. This means you might have to edit some real C sources in order to fix them to use the right locations. But where to search, and exactly what for? You can find this out by issuing:

     $ grep -nr -e 'usr/local/lib' --include='*.[c|h]' .

grep will run recursively through the source tree and tell you the filename and the line number for all matches.

Edit those files and in those lines replace usr/local/lib with usr/lib.

     $ vim '+argdo %s/usr\/local\/lib/usr\/lib/gce|update' +q \
           $(find . -type f -name '*.[c|h]')

Be careful that you don't mess up the rest of the code! :-)

After that you should find the install target (search for line that starts with install:, that will usually work) and rename all references to directories other than ones defined at the top of the Makefile.

After your upstream bug fix, gentoo's install target said:

     install: gentoo-target
             install ./gentoo $(BIN)
             install icons/* $(ICONS)
             install gentoorc-example $(HOME)/.gentoorc

Let's fix this and record this with the quilt command as debian/patches/install.patch.

     $ quilt new install.patch
     $ quilt add Makefile

Let's change this for Debian package as following using the editor:

     install: gentoo-target
             install -d $(BIN) $(ICONS) $(DESTDIR)/etc
             install ./gentoo $(BIN)
             install -m644 icons/* $(ICONS)
             install -m644 gentoorc-example $(DESTDIR)/etc/gentoorc

You've surely noticed that there's now a "install -d" command before the other commands in the rule. The original Makefile didn't have it because usually the /usr/local/bin and other directories already exist on the system where one runs "make install". However, since we will install into our own empty (or even nonexistent) directory, we will have to create each and every one of those directories.

We can also add in other things at the end of the rule, like the installation of additional documentation that the upstream authors sometimes omit:

             install -d $(DESTDIR)/usr/share/doc/gentoo/html
             cp -a docs/* $(DESTDIR)/usr/share/doc/gentoo/html

After careful check, if everything is fine, ask quilt to refresh the patch to create debian/patches/install.patch and add its description.

     $ quilt refresh
     $ quilt header -e
     ... describe patch

Now you have a series of patches.

  1. Upstream bug fix: debian/patches/fix-gentoo-target.patch

  1. Debian specific packaging modification: debian/patches/install.patch

Whenever you make changes that are not specifically related to Debian package such as debian/patches/fix-gentoo-target.patch, be sure to send them to the upstream maintainer so they can be included in the next program revision and be useful to everyone else. Also remember to make your fixes not specific to Debian or Linux (or even Unix!) prior to sending them -- make them portable. This will make your fixes much easier to apply.

Note that you don't have to send the debian/* files upstream.


3.4 Differing libraries

There is one other common problem: libraries are often different from platform to platform. For example, a Makefile can contain a reference to a library which doesn't exist on Debian systems. In that case, we need to change it to a library which does exist in Debian, and serves the same purpose.

So, if there is a line in your program's Makefile (or Makefile.in) that says something like this (and your program doesn't compile) [15]:

     LIBS = -lcurses -lsomething -lsomethingelse

Let's fix this as debian/patches/ncurse.patch by changing curses into ncurses.

     $ quilt new ncurse.patch
     $ quilt add Makefile
     $ sed -i -e "s/-lcurses/-lncurses/g" Makefile
     $ quilt refresh
     $ quilt header -e
     ... describe patch

[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ next ]


Debian New Maintainers' Guide

version 1.2.25, 2010-12-22 12:44:34 UTC

Josip Rodin joy-mg@debian.org