Referencing existing files
Task: In the last example make assumed there always was no prerequisite satisfied at invocation time, means you have to be naked before getting dressed. Well, I prefer having a mug of coffee after installing the basics and before putting on the uncomfortable articles. Now, how can I allow the following sequence to work?

$ make shirt trousers socks
$ drink coffee
$ make coat

Basic approach: Ascertaining the steps to the coat must be split in two parts. For this to work, make has to save the state after the first run. So I create an empty file after finishing each target, with the filename equal to the target’s name. When I now take out the .PHONY-line, make will conclude from an existing file to a satisfied target. Exactly speaking, it will compare the timestamps of target’s and prerequisite’s files. See next chapter for details on this.

Any rules in the last example lead to the same commands and differed in their prerequisites only. For those rules that have no prerequisites (e.g. socks) I don’t even need an implicit rule. The explicit ones can be pooled, because of their commands being all identic. Thus I get a shorter and pretty clear Makefile:

User-defined variables and functions
Use = or := to assign values to variables, depending on if potentially contained variables and functions should be expanded at using or declaration time. To retrieve the stored value, write $(myvar). To have make executing the value (like a function), write $(call myvar).

BTW: The minus sign (-) in front of the rm causes make to ignore any errors that occure while doing rm. This way a make naked coat will end at the coat, even for people who’re already naked at starting time.

Combining multiple Makefiles
Divide and konquer! For heavy projects (e.g. compiling the Linux kernel) you need giant Makefiles. They will become much clearer, when you split them into separate, smaller parts.

When make encounters an include-command, it will stop processing the current Makefile, read the included Makefile and then continue where it left off. If you don’t want it to abort when the included Makefile’s missing, just say -include Makefile(s).

Patterns
Thanks to the pattern-notation I need not write a separate rule for each postscript file. Generalizing the last example:

%.pdf: %.ps; -ps2pdf $<

The make tiger.pdf will work as before. But now a simple make (no targets) won’t work any more. make must be told a target’s name.

$ make
make: *** No targets. Stop.
$ make tiger.pdf
ps2pdf tiger.ps

The following Makefile will create the file tiger.pdf even when you call make without any parameters:

all : tiger.pdf
%.pdf: %.ps; -ps2pdf $<

Now, this works fine for the tiger. What if I want to convert any files in the current directory? No problem – the $(wildcard)­function can hand me a list of all *.ps files, and the $(patsubst)-function will change it to a list of PDF filenames:

all: $(patsubst %.ps,%.pdf,$(wildcard *.ps))
%.pdf: %.ps; -ps2pdf $<

Built-in functions
$(subst from,to,text) Replace from with to in text.
$(patsubst pattern,replacement,text) Replace words matching pattern with replacement in text.
$(strip string) Remove excess whitespace characters from string.
$(findstring find,text) Locate find in text.
$(filter pattern…,text) Select words in text that match one of the pattern words.
$(filter-out pattern…,text) Select words in text that do not match any of the pattern words.
$(sort list) Sort the words in list lexicographically, removing duplicates.
$(dir names…) Extract the directory part of each file name.
$(notdir names…) Extract the non-directory part of each file name.
$(suffix names…) Extract the suffix (the last dot and following characters) of each file name.
$(basename names…) Extract the base name (name without suffix) of each file name.
$(addsuffix suffix,names…) Append suffix to each word in names.
$(addprefix prefix,names…) Prepend prefix to each word in names.
$(join list1,list2) Join two parallel lists of words.
$(word n,text) Extract the nth word (one-origin) of text.
$(words text) Count the number of words in text.
$(wordlist s,e,text) Returns the list of words in text from s to e.
$(firstword names…) Extract the first word of names.
$(wildcard pattern…) Find file names matching a shell file name pattern (not a `%’ pattern).
$(error text…) When this function is evaluated, make generates a fatal error with the message text.
$(warning text…) When this function is evaluated, make generates a warning with the message text.
$(shell command) Execute a shell command and return its output.
$(origin variable) Return a string describing how the make variable variable was defined.
$(foreach var,words,text) Evaluate text with var bound to each word in words, and concatenate the results.
$(call var,param,…) Evaluate the variable var replacing any references to $(1),$(2) with the first, second, etc. param values.

Automatic variables
$@ The name of the target.
$% The target member name, when the target is an archive member.
$< The name of the first (or only) prerequisite.
$? The names of all the prerequisites that are newer than the target, with spaces between them.
$^
$+ The names of all the prerequisites, with spaces between them. The value of $^ omits duplicate prerequisites, while $+ retains them and preserves their order.
$* The stem with which an implicit rule matches.
$(@D)
$(@F) The directory part and the file-within-directory part of $@
$(*D)
$(*F) The directory part and the file-within-directory part of $*
$(%D)
$(%F) The directory part and the file-within-directory part of $%
$( $( $(^D)
$(^F) The directory part and the file-within-directory part of $^
$(+D)
$(+F) The directory part and the file-within-directory part of $+
$(?D)
$(?F) The directory part and the file-within-directory part of $?

To use an NMAKE special character as a literal character, place a caret (^) in front of it. NMAKE ignores carets that precede other characters. The special characters are:

: ; # ( ) $ ^ \ { } ! @ —

A caret (^) within a quoted string is treated as a literal caret character. A caret at the end of a line inserts a literal newline character in a string or macro.

In macros, a backslash () followed by a newline character is replaced by a space.

In commands, a percent symbol (%) is a file specifier. To represent % literally in a command, specify a double percent sign (%%) in place of a single one. In other situations, NMAKE interprets a single % literally, but it always interprets a double %% as a single %. Therefore, to represent a literal %%, specify either three percent signs, %%%, or four percent signs, %%%%.

To use the dollar sign ($) as a literal character in a command, specify two dollar signs ($$). This method can also be used in other situations where ^$ works.