When the same sequence of commands is useful in making various targets, you
can define it as a canned sequence with the
define directive, and
refer to the canned sequence from the rules for those targets. The canned
sequence is actually a variable, so the name must not conflict with other
Here is an example of defining a canned sequence of commands:
define run-yacc yacc $(firstword $^) mv y.tab.c $@ endef
run-yacc is the name of the variable being defined;
endef marks the end of the definition; the lines in between are the
define directive does not expand variable references
and function calls in the canned sequence; the ‘$’ characters,
parentheses, variable names, and so on, all become part of the value of the
variable you are defining.
See Defining Variables Verbatim,
for a complete explanation of
The first command in this example runs Yacc on the first prerequisite of whichever rule uses the canned sequence. The output file from Yacc is always named y.tab.c. The second command moves the output to the rule's target file name.
To use the canned sequence, substitute the variable into the commands of a
rule. You can substitute it like any other variable
(see Basics of Variable References).
Because variables defined by
define are recursively expanded
variables, all the variable references you wrote inside the
are expanded now. For example:
foo.c : foo.y $(run-yacc)
‘foo.y’ will be substituted for the variable ‘$^’ when it occurs in
run-yacc's value, and ‘foo.c’ for ‘$@’.
This is a realistic example, but this particular one is not needed in
make has an implicit rule to figure out these
commands based on the file names involved
(see Using Implicit Rules).
In command execution, each line of a canned sequence is treated just as
if the line appeared on its own in the rule, preceded by a tab. In
make invokes a separate subshell for each line. You
can use the special prefix characters that affect command lines
(‘@’, ‘-’, and ‘+’) on each line of a canned sequence.
See Writing the Commands in Rules.
For example, using this canned sequence:
define frobnicate @echo "frobnicating target $@" frob-step-1 $< -o $@-step-1 frob-step-2 $@-step-1 -o $@ endef
make will not echo the first line, the
But it will echo the following two command lines.
On the other hand, prefix characters on the command line that refers to a canned sequence apply to every line in the sequence. So the rule:
frob.out: frob.in @$(frobnicate)
does not echo any commands. (See Command Echoing, for a full explanation of ‘@’.)