wiki:CaffeinatedMake

Version 1 (modified by jdreed, 10 years ago) (diff)

--

The 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.

Tabs vs Spaces

In Makefiles, tabs are used to delineate rules inside a target (see below). When intending code (within a conditional, for example), use spaces, not tabs. 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. You generally don't care about the names of rules, with some exceptions:

  • common-build-indep
  • clean

When referring to targets like these, you use a double-colon after the target name. (TODO: explain why, or is that out of scope?)

When creating your own targets, you use single colons.

Variables

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).

Common Functions

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 shell 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.