Changes between Version 1 and Version 2 of CaffeinatedMake


Ignore:
Timestamp:
01/19/11 08:38:20 (11 years ago)
Author:
geofft
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • CaffeinatedMake

    v1 v2  
    1 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. 
     1The `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. 
    22 
    3 == Tabs vs Spaces == 
     3== About make == 
    44 
    5 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 "»" 
     5Make 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. 
    66 
    7 == Targets == 
     7=== A simple Makefile === 
     8{{{ 
     9#!make 
     10foo: foo.o 
     11        gcc -o foo foo.o 
     12foo.o: foo.c foo.h 
     13        gcc -c foo.c 
     14}}} 
    815 
    9 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: 
     16You 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. 
    1017 
    11  * `common-build-indep` 
    12  * `clean` 
     18=== A simple Makefile, `debian/rules` edition === 
     19{{{ 
     20#!make 
     21#!/usr/bin/make -f 
    1322 
    14 When referring to targets like these, you use a double-colon after the target name.  (TODO: explain why, or is that out of scope?) 
     23install: build 
     24        DESTDIR=$(CURDIR)/debian/$(package) make install 
    1525 
    16 When creating your own targets, you use single colons. 
     26build: 
     27        ./configure --prefix=/usr 
     28        make 
    1729 
    18 == Variables == 
     30binary: install 
     31        dh_installdocs 
     32        dh_installinit 
     33        ... 
     34}}} 
     35 
     36This 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. 
     37 
     38Debhelper 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. 
     39 
     40Note that in this example, building the "binary" target requires the "install" target to be successfully built, and that requires the "build" target. 
     41 
     42=== A simple `debian/rules` Makefile, CDBS edition === 
     43{{{ 
     44#!make 
     45#!/usr/bin/make -f 
     46 
     47include /usr/share/cdbs/1/rules/debhelper.mk 
     48include /usr/share/cdbs/1/class/autotools.mk 
     49 
     50DEB_DH_INSTALL_ARGS=--no-restart-on-upgrade 
     51}}} 
     52 
     53CDBS, 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`. 
     54 
     55To 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`. 
     56 
     57== Syntax == 
     58 
     59Make 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. 
     60 
     61=== Tabs vs Spaces === 
     62 
     63In 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. 
     64 
     65When 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 "»". 
     66 
     67=== Targets === 
     68 
     69Makefiles 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. 
     70 
     71If 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: 
     72 
     73{{{ 
     74#!make 
     75#!/usr/bin/make -f 
     76 
     77include /usr/share/cdbs/1/rules/debhelper.mk 
     78include /usr/share/cdbs/1/class/autotools.mk 
     79 
     80configure/mypackage:: 
     81        make dependency 
     82 
     83}}} 
     84 
     85This 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. 
     86 
     87When 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. 
     88 
     89=== Variables === 
     90 
     91Make 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). 
    1992 
    2093Variable names are generally in all caps by convention. 
     
    34107$(FOO) 
    35108 
    36 == Functions == 
     109=== Functions === 
    37110 
    38111Functions in make are called with $(function argument0 argument1).   
    39112 
    40 === Common Functions === 
    41  
    42 The `shell` function allows you to run a shell command and returns the output. 
     113The `shell` function allows you to run a shell command and returns the output: 
    43114 
    44115ARCH = $(shell uname -m)  
     
    46117would set ARCH to the hardware type. 
    47118 
    48 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. 
     119The `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. 
    49120 
    50 == Conditionals == 
     121=== Conditionals === 
    51122 
    52123The 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: