Posted by bdf on Sat 21 Jan 2006 at 17:18
In the first part of this text, we introduced the principal concepts of Debian package building. We're now ready to build an example package of a simple command line program.
I picked svnyoungest, a small auxiliary program to report the latest revision of a Subversion repository. You can find the source tarball of svnyoungest here. To interface directly with the Subversion library, it is written in C, but you can package programs from any development environment.
The source code is provided with a Makefile (no configure script though) that accepts these standard targets: all (the default), clean, distclean and install.
The first step is to create a debian subdir with packaging information. Probably the easiest approach is to use dh_make to generate one from a standard template. The package providing this command is called dh-make (with hyphen, not underscore).
apt-get install dh-make
dh_make requires the source directory to be named according to the common pattern packagename-version. So once we have the source available in svnyoungest-0.1, we can issue the dh_make command with appropriate options: -n indicates a native package (i.e. that is packaged by the original author), which is slightly simpler for demonstration purposes, -s indicates a single binary and -e sets the maintainer e-mail address to be used:
~/svnyoungest-0.1$ find . . ./svnyoungest.1 ./svnyoungest.c ./Makefile ./README ~/svnyoungest-0.1$ dh_make -n -s -e bruno@defraine.net Maintainer name : Bruno De Fraine Email-Address : bruno@defraine.net Date : Tue, 20 Dec 2005 10:28:12 +0100 Package Name : svnyoungest Version : 0.1 License : blank Type of Package : Single Hit to confirm: Done. Please edit the files in the debian/ subdirectory now. You should also check that the svnyoungest Makefiles install into $DESTDIR and not in / . ~/svnyoungest-0.1$ rm debian/*.ex debian/*.EX ~/svnyoungest-0.1$ find debian/ debian/ debian/changelog debian/compat debian/dirs debian/README.Debian debian/copyright debian/control debian/rules debian/docs debian/README ~/svnyoungest-0.1$ rm debian/README debian/README.Debian
Notice that the standard template used by dh_make contains a number of example files (extensions .ex or .EX). These files illustrate features for advanced packages (such as helper scripts, cron jobs, installation dialogs,...) and can be handy if your package needs them. In this case however, they would make the presentation needlessly complex, so I chose to remove them for the time being (they can easily be recreated by issuing dh_make with the -a switch). The template also provides a README and README.Debian file. I chose to delete both of them, respectively because my original source already contains a README document, and because I don't have additional Debian-specific remarks. This leaves us with an uncluttered debian subdir.
The first file to edit is probably the main debian/control file. The format and contents of this file should look familiar if you know the output of apt-cache show, and you can always find additional info in the deb-control(5) manpage. Note that the first and second parts refer to the source and binary packages respectively. In this case, it is straightforward to fill in the fields set up by the template:
Source: svnyoungest
Section: devel
Priority: optional
Maintainer: Bruno De Fraine
Build-Depends: debhelper (>= 4.0.0), libapr0-dev, libsvn0-dev
Standards-Version: 3.6.1
Package: svnyoungest
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: report the youngest revision of a svn repository path
svnyoungest is a small tool to report the youngest revision of a path in
a Subversion (svn) repository. It is similar to ''svnlook youngest'', but
works on the client side.
Since the generated debian/rules file invokes a number of debhelper tools, dh_make already included a build dependency for them. As the svnyoungest program uses functionality from the APR and svn libraries, I added their development packages. Other than that, I only had to provide a description text for the package.
Notice that there is no version number in the control file. This is because it can be extracted from another mandatory file: debian/changelog. This file contains an entry for each released version and is later installed as /usr/share/doc/packagename/changelog.Debian.gz. dh_make did already set up debian/changelog to document the initial release, so we don't need to edit it now. If you need to update it for a subsequent releases, I recommend using the debchange helper (also from the devscripts package), since the file format is rather stringent.
A third mandatory file is debian/copyright. Its format is not stipulated, but it should contain the license restrictions under which the software is distributed. It is installed with the documentation of the package. In this example, I just copy the license section from the README file.
Once we have the control data in place, it is the easiest to take a trial-and-error approach. dh_make already generated a debian/rules file for us, and before we edit anything, we try if it responds as expected to the standard targets:
~/svnyoungest-0.1$ fakeroot debian/rules clean (... invokes make clean; no errors ...)
Although the target clean does not produce an error, there is a small mismatch to be aware of: in the underlying Makefile, a complete clean is referred to as distclean, not clean (the latter one only deletes intermediate files). So in this case, we need to invoke make distclean. This can be easily corrected by changing the actions of the clean target in debian/rules:
# Add here commands to clean up after the build process.
-$(MAKE) distclean
We can then rerun the clean target and try the other consecutive targets:
~/svnyoungest-0.1$ fakeroot debian/rules clean (... invokes make distclean; no errors ...) ~/svnyoungest-0.1$ debian/rules build (... invokes make; no errors ...) ~/svnyoungest-0.1$ fakeroot debian/rules binary (... invokes make install ...) install: cannot create regular file `/usr/local/bin/svnyoungest': Permission denied (...)
We notice that there is an error during the binary target: the underlying make install tries to install to /usr/local instead of the temporary directory where we build the installation tree. It is not difficult to see why: debian/rules passes in this path as the DESTDIR variable, whereas the Makefile expects a variable PREFIX. Here's how we correct the relevant part of the binary target in debian/rules:
# Add here commands to install the package into debian/svnyoungest.
$(MAKE) install PREFIX=$(CURDIR)/debian/svnyoungest/usr
We then retry building the binary package. After this succeeds, we can check the generated installation tree in the temporary directory (created by default under debian/packagename).
~/svnyoungest-0.1$ fakeroot debian/rules binary (... invokes make install; no errors ...) ~/svnyoungest-0.1$ find debian/svnyoungest debian/svnyoungest debian/svnyoungest/usr debian/svnyoungest/usr/bin debian/svnyoungest/usr/bin/svnyoungest debian/svnyoungest/usr/sbin debian/svnyoungest/usr/man debian/svnyoungest/usr/man/man1 debian/svnyoungest/usr/man/man1/svnyoungest.1.gz debian/svnyoungest/usr/share debian/svnyoungest/usr/share/doc debian/svnyoungest/usr/share/doc/svnyoungest debian/svnyoungest/usr/share/doc/svnyoungest/README debian/svnyoungest/usr/share/doc/svnyoungest/copyright debian/svnyoungest/usr/share/doc/svnyoungest/changelog.gz debian/svnyoungest/DEBIAN debian/svnyoungest/DEBIAN/md5sums debian/svnyoungest/DEBIAN/control ~/svnyoungest-0.1$ cat debian/svnyoungest/DEBIAN/control Package: svnyoungest Version: 0.1 Section: devel Priority: optional Architecture: i386 Depends: libapr0 (>= 2.0.54), libc6 (>= 2.3.2.ds1-21), libsvn0 (>= 1.1.4-2) Installed-Size: 64 Maintainer: Bruno De Fraine Description: report the youngest revision of a svn repository path svnyoungest is a small tool to report the youngest revision of a path in a Subversion (svn) repository. It is similar to ''svnlook youngest'', but works on the client side.
This seems OK. Notice that the documentation is installed under the right location by the tools from debhelper. If something was omitted, we could have checked the debian/docs file and the dh_installdocs(1) manpage to see how to fix it. Similarly, we notice that the dependencies of the binary package have been provided by dh_shlibdeps.
We proceed by trying a complete debuild run. This will also run a package validator to verify the newly created package. We pass in the options -us -uc to turn off the package signing step.
~/svnyoungest-0.1$ debuild -us -uc (... regular build output ...) Now running lintian... E: svnyoungest: FSSTND-dir-in-usr usr/man/ Finished running lintian.
Apparently, something is blatantly wrong with our package, because the package checker lintian reports an error. This normally signifies a violation of the Debian Policy, and we can find more info at the lintian website. A quick investigation of the policy reveals that the manpages should go into /usr/share/man instead of /usr/man. Of course, this error was quite obvious to advanced packagers, but I wanted to demonstrate the importance of validating a package. The mistake can be corrected in debian/rules, by passing in a special MANDIR value:
DESTDIR=$(CURDIR)/debian/svnyoungest
...
# Add here commands to install the package into $(DESTDIR).
$(MAKE) install PREFIX=$(DESTDIR)/usr MANDIR=$(DESTDIR)/usr/share/man
If we then re-invoke debuild, we notice that the package now passes the lintian check. We finally obtain the desired Debian package, both in source and binary form:
~/svnyoungest-0.1$ debuild -us -uc (... regular build output ...) Now running lintian... Finished running lintian. ~/svnyoungest-0.1$ ls ../svnyoungest_0.1.* ../svnyoungest_0.1.dsc ../svnyoungest_0.1.tar.gz ~/svnyoungest-0.1$ ls ../svnyoungest_0.1_i386.* ../svnyoungest_0.1_i386.build ../svnyoungest_0.1_i386.deb ../svnyoungest_0.1_i386.changes
The resulting .deb file can be installed using dpkg -i.
More comprehensive information about creating Debian packages is available in the Debian New Maintainers' Guide and the Debian Developer's Reference.
If you would like to make your own .deb files downloadable by apt-get, check this article or this low-tech solution.
More advanced testing of packages can be done using pbuilder. Finally, this article describes how to integrate non-Debian packages with the standard reportbug tool.
We've covered checkinstall previously...
This guide is aimed more at people who want to understand the process, and do more complex things.
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
[ Parent ]
tong(64.231.xx.xx) on Sun 22 Jan 2006 at 20:28[ View Weblogs ]
tong
[ Parent ]