2003-09-29
Revision History | |
---|---|
Revision 2 | |
Revision 1 | 2003-09-29 |
First DocBook/XML version. |
Table of Contents
buildcore.mk
: A frameworkdebhelper.mk
: A rule fragmentmakefile.mk
and Single vs. Multi
Binary packagesIn 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 .deb
s
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
.deb
s 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
.