The `debian/rules` file in a Debian package uses GNU Make syntax. Most `make` syntax is straightforward, but there are several places where it differs from shell syntax. == About make == Make is a system for running certain shell commands under certain conditions: in particular, these conditions can involve previously running other commands. It is most often used for compiling large programs (e.g., "to build myprogram, use these commands which require main.o and library.o to be built; to build a .o file from a .c file, use this command"), because it can keep track of what work it has already done. However, it also turns out to be a good fit for the process of building a package. === A simple Makefile === {{{ #!make foo: foo.o gcc -o foo foo.o foo.o: foo.c foo.h gcc -c foo.c }}} You can build foo by running "make foo". If "foo" doesn't exist, or is older than "foo.o", this will execute the first gcc line. But first, if foo.o doesn't exist, or is older than either foo.c or foo.h, it will execute the second gcc line. If either foo.c or foo.h exist, Make will given an error that it, quite understandably, doesn't know how to create those files. === A simple Makefile, `debian/rules` edition === {{{ #!make #!/usr/bin/make -f install: build DESTDIR=$(CURDIR)/debian/$(package) make install build: ./configure --prefix=/usr make binary: install dh_installdocs dh_installinit ... }}} This is (part of) a `debian/rules` file using debhelper. When you tell the build system (`dpkg-buildpackage` in particular, but you'll probably be using `debuild` or `sbuild` on top of that) to build a package, it will run `debian/rules binary` to create the binary package. This is why the file is executable and has a "shebang line" indicating that it should be run with make; you don't actually call the "make" command. Debhelper is a higher-level tool for building packages than constructing the entire package yourself. All the debhelper commands start with `dh_`; you can run `ls /usr/bin/dh_*` to see the list. The traditional way to use debhelper is to have the "binary" target run a bunch of debhelper commands that set up all the things needed by the package -- documentation, window system menu configuration, shared library setup, initscripts, etc. etc. Debhelper commands are generally configured by appropriately-named other files in the `debian/` subdirectory. Note that in this example, building the "binary" target requires the "install" target to be successfully built, and that requires the "build" target. === A simple `debian/rules` Makefile, CDBS edition === {{{ #!make #!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk DEB_DH_INSTALLINIT_ARGS=--no-restart-on-upgrade }}} CDBS, the Common Debian Build System, is a higher-level system on top of (usually) debhelper. You include some CDBS rules and class files to say what type of rules you want and what class of package you're building, and it goes off and sets up the right targets and calls basically every dh_* script. "autotools.mk" indicates we're using a standard autotools-based package (i.e., `./configure; make; make install`), and CDBS will do the right things for it (`--prefix`, `DESTDIR`, etc.). This is a complete CDBS-based `debian/rules`. To configure things in CDBS, you generally either set variables or use double-colon rules (see below). In this case we tell CDBS to call `dh_install` with `--no-restart-on-upgrade`. == Syntax == Make is a bit picky about syntax. Here's what you need to know, but [http://www.gnu.org/software/autoconf/manual/make/ the official manual] is handy. === Tabs vs Spaces === In Makefiles, tabs are used to delineate rules inside a target (e.g., the gcc lines in the first example). You ''must'' use a tab, not eight spaces. When intending Make-syntax code (within a conditional, for example), use spaces, not tabs, to make it clear that it's not a target. Emacs can either make this simple or more confusing. If you get lost, or get weird syntax errors, try `M-x whitespace-mode` in Emacs, which will represent spaces as "·" and tabs as "»". === Targets === Makefiles primarily contain "targets", which specify what actions to take to build a certain component of the package. CDBS sets up a [http://build-common.alioth.debian.org/cdbs-doc.html#id2542963 large number of targets] that you can hook if you need to. If you're hooking a CDBS target, you generally use a double colon, because Make will not otherwise let you define a target twice (see the section on [http://www.gnu.org/software/autoconf/manual/make/Multiple-Rules.html multiple rules] in the manual). Suppose you had a program with a buggy Makefile, that required you to run "make dependency" before you ran normal "make" (and didn't specify this dependency). You could work around it in the packaging like so: {{{ #!make #!/usr/bin/make -f include /usr/share/cdbs/1/rules/debhelper.mk include /usr/share/cdbs/1/class/autotools.mk configure/mypackage:: make dependency }}} This will cause the built-in rules for the `configure/mypackage` to be run first (i.e., `./configure`), then yours, before it goes on to `make/mypackage`. Note that because Debian source packages can build multiple binary packages, CDBS adds the binary package name to the target. When creating your own targets, especially if you're building files in your `debian/rules` (not generally recommended but sometimes acceptable), you use single colons as usual. === Variables === Make variables are not shell or environment variables. Make inherits variables from the environment, but does not set them (unless you export the variable, much like the shell). Variable names are generally in all caps by convention. `FOO = bar` would set variable FOO to bar. You can append to a variable with += `FOO += baz` Variable FOO now contains "bar baz". To refer to variables, you enclose them with parens and a dollar sign: $(FOO) === Functions === Functions in make are called with $(function argument0 argument1). The `shell` function allows you to run a shell command and returns the output: ARCH = $(shell uname -m) would set ARCH to the hardware type. The `wildcard` function is a Make function that supports globbing, but also can be used to test for files. For example, `$(wildcard /etc/gdm/gdm.conf-custom)` could be used to test for the presence of that file on the build system. You can compare its output against the empty string to see if the file is absent. === Conditionals === The most common conditionals are ifeq and ifneq which test for equality and inequality, respectively. Using the ARCH variable from the example above, you could do the following: {{{ ifeq ($(shell uname -m),x86_64) # do 64-bit stuff else # do something else endif }}} As in most languages, the `else` clause is optional.