The
makefile language is partially
declarative programming where end conditions are described but the order in which actions are to be taken is not. This type of programming can be confusing to programmers used to
imperative programming. Makefiles can contain the following constructs: •
Explicit rule: defines when and how to update a target, listing
prerequisites (dependent targets) and commands that define the update action, called the
recipe •
Implicit rule: defines when and how to remake a class of files based on their names, including how a target depends on a file with a name similar to the target and an update recipe •
Variable definition: associates a text value with a name that can be substituted into later text •
Directive: instruction to do something special such as include another makefile •
Comment: line starting with
Rules Each rule begins with a
dependency line which consists of the rule's
target name followed by a colon (:), and optionally a list of targets (also known as prerequisites) on which the rule's target depends. target [target ...]: [component ...] [command 1] . . . [command n] Usually a rule has a single target, rather than multiple. A dependency line may be followed by a recipe: a series of
TAB indented command lines that define how to generate the target from the components (i.e. source files). If any prerequisite has a more recent timestamp than the target file or the target does not exist as a file, the recipe is performed. The first command may appear on the same line after the prerequisites, separated by a semicolon, targets: prerequisites ; command for example, hello: ; @echo "hello" Each command line must begin with a tab character. Even though a
space is also
whitespace, Make requires tab. Since this often leads to confusion and mistakes, this aspect of makefile syntax is subject to criticism.
Eric S. Raymond describes it as "one of the worst design botches in the history of Unix" and
The Unix-Haters Handbook said "using tabs as part of the syntax is like one of those pungee [sic] stick traps in
The Green Berets". Feldman explains the choice as caused by a
workaround for an early implementation difficulty, and preserved by a desire for
backward compatibility with the very first users: GNU Make since version 3.82 allows the choice of any symbol (one character) as the recipe prefix using the .RECIPEPREFIX special variable: .RECIPEPREFIX := : all: :@echo "recipe prefix symbol is set to '$(.RECIPEPREFIX)'" Each command is executed in a separate
shell. Since operating systems use different shells, this can lead to unportable makefiles. For example, GNU Make (all POSIX Makes) executes commands with
/bin/sh by default, where
Unix commands like
cp are normally used. In contrast, Microsoft's
nmake executes commands with cmd.exe where
batch commands like
copy are available but not necessarily cp. Since a recipe is optional, the dependency line can consist solely of components that refer to other targets: realclean: clean distclean The following example rule is evaluated when Make updates target file.txt via . If file.html is newer than file.txt or file.txt does not exist, then the command is run to generate file.txt from file.html. file.txt: file.html lynx -dump file.html > file.txt A command can have one or more of the following prefixes (after the tab): •
minus (-) specifies to ignore an error from the command •
at (@) specifies to
not output the command before it is executed •
plus (+) specifies to execute the command even if Make is invoked in "do not execute" mode Ignoring errors and silencing echo can alternatively be obtained via the special targets and . Microsoft's NMAKE has predefined rules that can be omitted from these makefiles, e.g. .
Macros A makefile can define and use macros. Macros are usually referred to as
variables when they hold simple string definitions, like . Macros in makefiles may be overridden in the
command-line arguments passed to the Make utility.
Environment variables are also available as macros. For example, the macro is frequently used in makefiles to refer to the location of a
C compiler. If used consistently throughout the makefile, then the compiler used can be changed by changing the value of the macro rather than changing each rule command that invokes the compiler. Macros are commonly named in
all-caps: MACRO = definition A macro value can consist of other macro values. The value of macro is expanded on each use
lazily. A macro is used by expanding either via $
NAME or $(
NAME). The latter is safer since omitting the parentheses leads to Make interpreting the next letter after the as the entire variable name. An equivalent form uses curly braces rather than parentheses, i.e. {{code|${} }}, which is the style used in
BSD. NEW_MACRO = $(MACRO)-$(MACRO2) Macros can be composed of shell commands by using the
command substitution operator !=. YYYYMMDD != date The command-line syntax for overriding a macro is: make MACRO="value" [MACRO="value" ...] TARGET [TARGET ...] Makefiles can access predefined
internal macros, with and being common. target: component1 component2 # echo components YOUNGER than TARGET echo $? # echo TARGET name echo $@ A common syntax when defining macros, which works on BSD and GNU Make, is to use , , and instead of the equal sign ().
Suffix rules Suffix rules have "targets" with names in the form and are used to launch actions based on file extension. In the command lines of suffix rules, POSIX specifies If they have any, they are treated as normal files with unusual names, not as suffix rules. GNU Make supports suffix rules for compatibility with old makefiles but otherwise encourages usage of
pattern rules. A pattern rule looks like an ordinary rule, except that its target contains exactly one character within the string. The target is considered a pattern for matching file names: the can match any substring of zero or more characters, while other characters match only themselves. The prerequisites likewise use to show how their names relate to the target name. The example above of a suffix rule would look like the following pattern rule: • From %.html to %.txt %.txt : %.html lynx -dump $ $@
Comment Single-line
comments are started with the
hash symbol (#).
Directive A directive specifies special behavior such as
including another makefile.
Line continuation Line continuation is indicated with a backslash character at the end of a line. target: component \ component command ; \ another-command | \ piped-command ==Examples==