Copyright 2003 Colin Walters. Permission is granted to copy, distribute and/or modify this document under the terms of the GPL.
2003-09-29
Revision History | |
---|---|
Revision 2 | |
Revision 1 | 2003-09-29 |
First DocBook/XML version. |
Table of Contents
In a single sentence: CDBS is a framework based on Makefile inheritance for building Debian packages.
It is essentially a set of Makefile fragments which you may include into your debian/rules. Each makefile fragment can have effects in different parts of your build process.
The original motivating factor for CDBS was originally that more and more programs today are created using GNU configure scripts and GNU automake, and as such they are all very similar to configure and build. I realized that a lot of duplicated code in everyone's debian/rules could be factored out. But CDBS isn't only useful for packages which use the GNU autotools. It is a flexible core upon which you can create your own custom build systems.
CDBS might change incompatibly in the future, and to allow for this, all the rules and classes are in a verison-specific subdirectory. That's the reason for the 1 in /usr/share/cbds/1. For right now though, during the initial development of cdbs, when few packages are using it, I might break compatibility in small ways. You will be warned if this happens.
Every CDBS-using debian/rules should eventually include /usr/share/cdbs/1/rules/buildcore.mk (it might be included automatically via dependencies, as we will see later). This Makefile fragment sets up all of the core default Makefile structure and variables, but doesn't actually do anything on its own.
You can use the buildcore.mk rules to hook in your own build system to actually implement each stage of compiling, installing, and building .debs if you wish.
However, cdbs also provides classes which contain makefile rules and variables implementing some or all of these steps. Classes tend to be declarative; they say your program has particular properties. Suppose for instance that your package uses a regular Makefile to compile, and has the normal make and make install targets. In that case, you can say:
include /usr/share/cdbs/1/class/makefile.mk
And you get all the code to run make automagically. This basically works by adding code to the common-build-arch, common-build-indep, common-install-arch, and common-install-indep targets inside buildcore.mk. It might be instructive to look at makefile.mk now.
The next important piece of the puzzle is to actually build .debs from the now compiled software. You could implement this step yourself if you wished, but most people will want to take advantage of Debhelper to do it mostly automatically. To do this, simply add another line like:
include /usr/share/cdbs/1/rules/debhelper.mk
Note that if you use debhelper.mk, you must add a Build-Depends on debhelper (>= 4.1.0). This is the minimum version; it is recommended to use at least 4.1.46 to get some additional Debhelper features.
With just the two lines above, you should have a reasonable first cut at a fully functional build system! To recap, your debian/rules should now look like:
#!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/makefile.mk
And that's all! Note that makefile.mk and debhelper.mk both include buildcore.mk, so you don't need to include it explicitly.
Incidentally, you should usually include debhelper.mk first, before other rules. This will turn on optional Debhelper-using parts of other rules, if any, which is usually what you want.
Now, let's look at some common situations. Say that your package uses GNU autoconf and automake. In that case, you can use the provided autotools class. One thing to note is that the autotools class actually builds upon the makefile class. This autotools class will take care of details such as updating the config.{sub,guess} files, running ./configure with the standard arguments, etc. So now our debian/rules looks like:
#!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk
However, suppose you need to pass --disable-frobnication to ./configure. How do you do this? Well, it couldn't be easier. The autotools.mk file includes a number of variables which you can override, like this:
#!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk DEB_CONFIGURE_EXTRA_FLAGS := --disable-frobnication
Note that the variable is set after the rule fragment is included. This is necessary for it to have any effect. There are a few exceptions to this; but generally variables should be set after rule fragments are included.
Now, let's suppose your package is a little bit strange (e.g. Perl); perhaps it has a ./Configure script which isn't made by autoconf; this script might instead expect the user to interactively configure the program . In that case, you can just implement the common-configure rule, by adding something like the following to your debian/rules:
common-configure:: ./Configure --blah --blargh < debian/answers
Note that if you do this, you can't include autotools.mk, since then you'll get two implementations of common-configure, which is sure to fail. It would be nice to be able to partially override rule fragments; this is a tricky problem, but I hope to address it.
Suppose that your package generates extra cruft as a side effect of the build process that's not taken care of by the upstream clean rule, and ends up bloating your diff. To handle this (until upstream fixes it), you can simply add stuff to the clean rule as follows:
clean:: rm -f foo/blah.o po/.intltool-merge-cache
Almost all of the current rules are double colon rules (See the GNU Make manual). This means you can simply add to them without overriding the default.
You can also add dependencies to the rules. For example, suppose you have a multi-binary package which builds both a program and a shared library, and the program depends on the shared library. To tell CDBS to build the shared library before the program, just do something like:
binary/program:: binary/libfoo
However, this must come before you include buildcore.mk. This is due to the way make works.
And speaking of multi-binary packages:
If you have a single binary package, the default common-install implementation in makefile.mk tries to use the upstream Makefile to install everything into debian/packagename, so it will all appear in the binary package. If you're using debhelper.mk, to remove files, move them around, just override the binary-post-install/<packagename> target
binary-post-install/mypackage: mv debian/mypackage/usr/sbin/myprogram \ debian/mypackage/usr/bin/myprogram rm debian/mypackage/usr/share/doc/mypackage/INSTALL
If you have a multi-binary package, makefile.mk (by default) uses the upstream Makefile to install everything in debian/tmp. After this, the recommended method is to use debhelper.mk (which uses dh_install) to copy these files into the appropriate package. To do this, just create packagename.install files; see the dh_install man page.
Suppose you'd like to keep separated patches, instead of having them all in your .diff.gz. cdbs lets you hook in arbitrary patch systems, but (as with the rest of cdbs), it has its own default implementation, called simple-patchsys.mk. To use it, just add:
include /usr/share/cdbs/1/rules/simple-patchsys.mk
to your debian/rules. Now, you can drop patch files into the debian/patches directory, and they will be automatically applied and unapplied. Note that currently patches must end in .patch.
Like the simple patch system detailed previously, the dpatch patch system allows you to seperate your changes to the upstream tarball into multiple seperate patches instead of a monolithic diff.gz. This is a wrapper to the dpatch tools contained in the dpatch Debian package, and it's named dpatch.mk. To use it, add:
include /usr/share/cdbs/1/rules/dpatch.mk
to your debian/rules. If you use autotools.mk, be sure to include dpatch.mk after autotools.mk. Additionally, remember to add dpatch to your Build-Depends.
Finally, for a more complete treatment of dpatch files, their format, and their application, please read the documentation included in the dpatch package. Notably, /usr/share/doc/dpatch/README.gz and the dpatch(1) manpage.
Some Debian developers may be familiar with DBS, where you include a tarball of the source inside the Debian source package itself. This has some advantages, and some disadvantages. If you'd like to use this, just include tarball.mk, and specify DEB_TAR_SRCDIR. Note that it must be first in the list of included rules.
Often this is caused by the fact that cdbs passes CFLAGS along with the make invocation. A sane build system allows this - CFLAGS are for the user to customize. Setting CFLAGS shouldn't override other internal flags used in the package like -I. However if fixing the upstream source is too difficult, you may do this:
DEB_MAKE_INVOKE := $(DEB_MAKE_ENVVARS) \ make -C $(DEB_BUILDDIR)
That will avoid passing CFLAGS. But note this breaks the automatic implementation of DEB_BUILD_OPTIONS.