If a target is included as a command-line argument, that target is updated. Else the first target is used (default goal).
target_1 ... target_n: [prereq_1 ... prereq_n] [command_1] ... [command_n]
Commands are preceded by a TAB character.
If any prerequisite has an associated rule, make attempts to update it first.
If any prerequisite is newer than the target, the associated commands are executed.
Explicit : indicate a specific target to be updated if it is out of date with respect to any of its prerequisites.
Pattern : use wildcards instead of explicit names.
Implicit : either pattern rules or suffix rules found in the built-in rules database.
A rule does not have to be defined all at once.
The wildcards are the same as the bourne shell.
When a wldcard appears in a target or in a prerequisite it is expanded immediatelly by make. When it appears in a command then it is expandedn in the subshell.
Targets that do not represent files. Normally phony targets are always executed because the commands associated with the rule do notcreate the target name. But if a file named as the phony target exists this will prevent the rule execution. To prevent this problem, it is good practice to explicitly declare such targets as PHONY:
.PHONY: clean clean: echo "cleaning"
Automatically created by make if a rule is matched. Can be used within the commands list context.
$@: the target;
$%: filename element of an archive member specification;
$<: first prerequisite;
$?: all the prerequisites newer than the target;
$^: all the prerequisites with removed duplicates;
$+: as abovebut duplicates are not removed;
$*: stem of the target (stem is a name without suffix).
The VPATH variable consists of a list of directories to search when make needs a file that is not available in the current directory. The list will be searched for targets as well as prerequisites, but not for files mentioned in commands.
The vpath directive is a more precise way to achieve the same goals. The syntax is
vpath pattern directory-list
The stem of the target file is represented by a % character. Make built-in rules are all instances of pattern rules. Example, this one specifies how to compile a .o file from a .c file:
%.o: %.c $(CC) $(CFLAGS) -c $<
To list all the built-in rules:
$ make --print-data-base
A pattern can contain a prefix, a suffix or both. When the rule is used, the stem if the target is substituted to the stem of the prerequisites.
Is a built-in phony target uses to change make's default behaviour. For instance, .PHONY declares that its prerequisite should always be considered out of date.
Variable are alias to other strings defined via one of the four possible assignment operators.
Characters disallowed in a variable name are
=. To get the
value of a variable, enclose the variable name in
$() (single letter variable
names can omit the parentheses).
Variables a user may want to customize on the command line or in the environment are uppercase.
Spaces before a variable name are trimmend, while ones after the vale not.
Simply expanded. The righthand side is expanded immediately and the result
saved as the variable value. Are defined using the
:= assignment operator.
Recusively expanded. The righthand side is (re)expanded every time the
variable is used by another expression that is not a recursive assignment. Are
defined using the
Conditional assignment. Assignment is performed if and only if the variable
does not yet have a value. Defined by the
Append assignment. Appends text to a variable (even if undefined). For simple variables this can be replaced by the following:
simple := $(simple) newstuff
But the same is not allowed for recursive variables, it yields an infinite loop when expanded. Thus the append operator was the correct way to append text to recursive variables.
Righthand side of
+= is expanded immediately if the lefthand side was
originally defined as a simple variable. Otherwise, its evaluation is deferred.
Lefthand side of a variable assignment is always immediatelly expanded.
A macro is just a variable that can contain embedded newlines. Macros are
created using the
define dosomething @echo Creating $@ touch $@ endef
A macro can be used within a command like a variable.
Macro names are always immediatelly expanded. The macro body expansion is deferred by default, but if we use the assignment operator it follows the same rules as the variables.
Variable definitions are parsed as follows:
immediate = deferred immediate ?= deferred immediate := immediate immediate += deferred or immediate define immediate [=] deferred endef define immediate ?= deferred endef define immediate := immediate endef define immediate += deferred or immediate endef immediate: immediate deferred ifeq/ifneq/ifdef/ifndef immediate
If a target require a special treatment, for example a specific variable definition, we have two options:
foo.o: foo.h $(COMPILER.c) -DUSE_NEW_MALLOC=1 $(OUTPUT_OPTION) $<
(better) Define a rule that has as the prerequisite all the variables to be used just within such target context. The commands are taken from the rule shared by all the other targets
foo.o: CPPFLAGS += -DUSE_NEW_MALLOC=1
Parts of a makefile can be omitted or selected while the makefile is being read using conditional processing.
if-condition text if the condition is true else text if the condition is false endif
The if-condition can be one of:
ifdef variable-name ifndef variable-name ifeq test ifneq test
ifdef VARIABLE echo "defined" else echo "not defined" endif
Conditional processing directives can be used within command scripts as well as at the top level.
Within the test part of the conditional spaces are important.
ifeq (a, a)
Is true. While
ifeq ( a, a)
Is false. To prevent such errors we can use the quoted version:
ifeq 'a' 'a'
External pieces of makefile can be included via the
include directive. If one
of the included files cannot be found make reports the error and continue with
the makefile processing to try to find a rule to build the missing include
file. If a rule is found, the target is created and the makefile is parsed
again, else the error is reported an make stops.
Functions are called as we deference a variable, but includes one or more parameters separated by commas. A function can get data from four sources: parameters passed using call, global variables, automatic variables, and target-specific variables.
A user defined function is stored in a variable or a macro. Parameters are referenced within the body of the macro with $1, $2, etc.
The syntax for expandig a variable or macro is
$(call macro-name[, param1...])
call is a built-in make function that expands its first argument and replaces occurrences of $1, $2, etc., with the remaining arguments it is given. If parameters are not given then we can omit the call keyword (macro-name) is a normal macro.
All functions have the form
$(function-name arg1[, arg2...])
Many functions accept a single argument, treating it as a list of space-separated words. Many others accept a pattern as an argument. This patterns uses the same syntax as the pattern rules.
Filter. Select a set of files from a list of space separated words. The pattern must match the entire pattern word to be included in the output list (similar to grep -w). A pattern can contain only one %. If additional % characters are included all but the first are treated as literal characters.
Filter-out. Does the opposite of filter
Find string. Search for a string in a list of space separated words. The string cannot contaain widcards.
Search and replace. There are two versions, one that don't handles wildcards,
subst and one that handles them,
patsubst. Replaces all occurrences of the
search string with the replacement string.
With the wildcard version, the pattern can contain a single %. The search pattern must match the entire value of text.
Note: Substitution references are a portable way of performing the same substitution
Returns the nth word in text.
First word in text. Equivalent to $(word 1,text).
Word list. Returns the words in text from start to end, inclusive.
Sorts its list argument in lexicographic order and removes duplicates. Also strips extra blanks.
Shell command. Accepts a single argument that is expanded and passed to a subshell for execution. Standard output is then read and returned as the value if the function. Newlines are colapsed into a single space. Standard error is not returned.
Wildcard. Accept a list of patters and performs expansion of each one. If a pattern does not match any file the empty string is returned. Normal shell globbing characters are supported: ~, *, ?, [...], and [^...]. The alternative is to use the shell for expansion, but is slower.
Directory portion of each word in list.
File portion of each word in the list.
Returns the suffix of each word in its argument.
$(suffix name, list)
Removes suffix from a list of wordsl
Appends the given suffix to each word in a list.
Prepends the given prefix to each word in a list.
Concatenates the first element of list1 with the first element of list2, the second element of list1 with the second element of list2, and so on.
eval is a special function to feed text directly to the make parser.
The argument to
eval is first scanned for variables and expanded (as all
arguments to all functions are), then the text is parsed and evaluated as
if it had come from an input file.
The argument to
eval is expanded twice: once when
make prepares the
argument list for
eval, and once again by
if function (not to be confused with the conditional directives
ifndef) selects one of two macro expansions depending
on the "value" od the conditional expression. The condition is true if contains
any characters (even space).
A hook is a function reference that can be redefined by a user to perform their own custom tasks during a standard operation. Example
foo-lib: build-lib-hook = @echo "building foo lib" bar-lib: build-lib-hook = @echo "building bar lib"
Depending on the target the
build-lib-hook expands differently.
define build-lib $(AR) $(ARFLAGS) $@ $1 $(call build-lib-hook,$@) endef
Commands are one-line shell scripts. Make grabs each line and passes it to a
subshell for execution. By default the
/bin/sh shell is used and overwrites
PATH variable value.
Shell execution control statements must be "single line". Semicolons are used to divide the control statements parts. Example:
for i in `seq 1 10`; do echo $$i; done;
An error in one of the commands immediatelly stops the makefile processing. Note that comma separated multiple shell commands are interpreted as one command by the make parser and are passed to the same subshell for execution.
When a subshell is created, make adds few variables to the environment:
Each subprocess make spawns inherits the three std file descriptors: stdin, stdout, and stderr. It is possible for a command script to read the stdin.
If during the built of a target an error happens by default make stops but the
partially built file is not deleted. Even worst this file has its timestap
updated, thus, on the next rebuild, such a target is considered up-to-date and
thus not rebuilt.
If a target is added as a prerequisite of the special
then errors in any target command will cause make to delete the target.
test: test.c gcc -o $< $@ strip test
In the example if strip fails the target is considered up-to-date anyway.
A complementary problem occurs when
make is interrupted by signal, such as
Ctrl-C. In this case
make deletes the target if the target is not in the
prerequisites list of the special
PRECIOUS superseeds the
@: Do not echo the command. To hide all the commands of a target make it a prerequisite of the special target
-: Errors in the command line should be ignored by make. To ignore all the errors generated by the commands of a target make id a prerequisit of the special target
+: Executes the command even if the
--just-printcommand-line option is given to make.
gcc compiler has an option to generate a source file
tree in a format comprensible by make. The dependency list is generated by
compiling the source with the
The following is a makefile snip, described by the GNU make docuentation, for automatic dependency generation.
ifneq ($(MAKECMDGOALS),clean) -include $(sources:.c=.d) endif %.d: %.c $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ $(SED) 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ $(RM) $@.$$$$
Note that the command is executed in one line. This is due to the fact that the temporary file name extension is set to the current process pid ($$). If we execute the multiple shell commands in separate subshells then the pid can change.
@character are not echoed by make when the command is executed.