MAKE(1) | General Commands Manual | MAKE(1) |
make
— maintain
program dependencies
make |
[-BeikNnqrSstWwX ] [-C
directory] [-D
variable] [-d
flags] [-f
makefile] [-I
directory] [-J
private] [-j
max_jobs] [-m
directory] [-T
file] [-V
variable] [-v
variable]
[variable= value]
[target ...] |
make
is a program designed to simplify the
maintenance of other programs. Its input is a list of specifications as to
the files upon which programs and other files depend. If no
-f
makefile option is given,
make
looks for the makefiles listed in
.MAKE.MAKEFILE_PREFERENCE (default
‘makefile’,
‘Makefile’) in order to find the
specifications. If the file ‘.depend’
exists, it is read, see
mkdep(1).
This manual page is intended as a reference document only. For a
more thorough description of make
and makefiles,
please refer to PMake - A Tutorial (from 1993).
make
prepends the contents of the
MAKEFLAGS
environment variable to the command line
arguments before parsing them.
The options are as follows:
-B
-C
directory-C
options are
specified, each is interpreted relative to the previous one:
-C
/
-C
etc is equivalent to
-C
/etc.-D
variable-d
[-
]flagsmake
are to print debugging information. Unless
the flags are preceded by ‘-
’, they
are added to the MAKEFLAGS
environment variable
and are passed on to any child make processes. By default, debugging
information is printed to standard error, but this can be changed using
the F
debugging flag. The debugging output is
always unbuffered; in addition, if debugging is enabled but debugging
output is not directed to standard output, the standard output is line
buffered. The available flags are:
A
a
C
c
d
e
F
[+
]filenameF
flag is
‘+
’, the file is opened in
append mode; otherwise the file is overwritten. If the file name is
‘stdout
’ or
‘stderr
’, debugging output is
written to the standard output or standard error output respectively
(and the ‘+
’ option has no
effect). Otherwise, the output is written to the named file. If the
file name ends with ‘.%d
’, the
‘%d
’ is replaced by the
pid.f
g1
g2
g3
h
j
L
l
@
’ or other
“quiet” flags. Also known as “loud”
behavior.M
m
n
TMPDIR
environment
variable, or in /tmp if
TMPDIR
is unset or set to the empty string.
The temporary scripts are created by
mkstemp(3), and have
names of the form makeXXXXXX.
NOTE: This can create many files in
TMPDIR
or /tmp, so use
with care.p
s
t
V
-V
option to print raw values of
variables, overriding the default behavior set via
.MAKE.EXPAND_VARIABLES.v
x
-x
so the actual
commands are printed as they are executed.-e
-f
makefile-
’, standard input is read. If
makefile starts with the string
‘.../
’, make
searches for the specified path in the rest of the argument in the current
directory and its parents. Multiple makefiles may be specified, and are
read in the order specified.-I
directory-m
option) is automatically included as part of
this list.-i
-
’ before each command
line in the makefile.-J
privateWhen the -j
option is in use in a
recursive build, this option is passed by a make to child makes to allow
all the make processes in the build to cooperate to avoid overloading
the system.
-j
max_jobsmake
may
have running at any one time. If max_jobs is a
floating point number, or ends with
‘C
’, then the value is multiplied by
the number of CPUs reported online by
sysconf(3). The value of
max_jobs is saved in
.MAKE.JOBS. Turns compatibility mode off, unless the
-B
option is also specified. When compatibility
mode is off, all commands associated with a target are executed in a
single shell invocation as opposed to the traditional one shell invocation
per line. This can break traditional scripts which change directories on
each command invocation and then expect to start with a fresh environment
on the next line. It is more efficient to correct the scripts rather than
turn backwards compatibility on.
A job token pool with max_jobs tokens is
used to control the total number of jobs running. Each instance of
make
will wait for a token from the pool before
running a new job.
-k
-m
directory<
file>
-style
include statement. The -m
option can be used
multiple times to form a search path. This path overrides the default
system include path /usr/share/mk. Furthermore,
the system include path is appended to the search path used for
"
file"
-style
include statements (see the -I
option). The system
include path can be referenced via the read-only variable
.SYSPATH.
If a directory name in the -m
argument
(or the MAKESYSPATH
environment variable) starts
with the string ‘.../
’,
make
searches for the specified file or
directory named in the remaining part of the argument string. The search
starts with the current directory and then works upward towards the root
of the file system. If the search is successful, the resulting directory
replaces the ‘.../
’ specification
in the -m
argument. This feature allows
make
to easily search in the current source tree
for customized sys.mk files (e.g., by using
‘.../mk/sys.mk
’ as an
argument).
-n
+
’.-N
-q
-r
-S
-k
.-s
@
’ before each command line in the
makefile.-T
tracefile-j
flag, append a trace record
to tracefile for each job started and
completed.-t
-V
variableBy default, the raw variable contents (which may include
additional unexpanded variable references) are shown. If
variable contains a
‘$
’, it is not interpreted as a
variable name but rather as an expression. Its value is expanded before
printing. The value is also expanded before printing if
.MAKE.EXPAND_VARIABLES is set to true and the
-dV
option has not been used to override it.
Note that loop-local and target-local variables, as well as
values taken temporarily by global variables during makefile processing,
are not accessible via this option. The -dv
debug mode can be used to see these at the cost of generating
substantial extraneous output.
-v
variable-V
, but all printed variables are always
expanded to their complete value. The last occurrence of
-V
or -v
decides whether
all variables are expanded or not.-W
-w
-X
MAKEFLAGS
environment variable. This option
may be useful on systems which have a small limit on the size of command
arguments.=
value-X
flag disables this behavior. Variable
assignments should follow options for POSIX compatibility but no ordering
is enforced.There are several different types of lines in a makefile: dependency specifications, shell commands, variable assignments, include statements, conditional directives, for loops, other directives, and comments.
Lines may be continued from one line to the next by ending them
with a backslash (‘\
’). The trailing
newline character and initial whitespace on the following line are
compressed into a single space.
Dependency lines consist of one or more targets, an operator, and zero or more sources. This creates a relationship where the targets “depend” on the sources and are customarily created from them. A target is considered out of date if it does not exist, or if its modification time is less than that of any of its sources. An out-of-date target is re-created, but not until all sources have been examined and themselves re-created as needed. Three operators may be used:
:
make
is interrupted, the
target is removed.!
::
:
, for dependency lines with no sources, the
attached shell commands are always run. Also unlike
:
, the target is not removed if
make
is interrupted.All dependency lines mentioning a particular target must use the same operator.
Targets and sources may contain the shell wildcard values
‘?
’,
‘*
’,
‘[]
’, and
‘{}
’. The values
‘?
’,
‘*
’, and
‘[]
’ may only be used as part of the
final component of the target or source, and only match existing files. The
value ‘{}
’ need not necessarily be
used to describe existing files. Expansion is in directory order, not
alphabetically as done in the shell.
Each target may have associated with it one or more lines of shell
commands, normally used to create the target. Each of the lines in this
script
must be
preceded by a tab. (For historical reasons, spaces are not accepted.) While
targets can occur in many dependency lines if desired, by default only one
of these rules may be followed by a creation script. If the
‘::
’ operator is used, however, all
rules may include scripts, and the respective scripts are executed in the
order found.
Each line is treated as a separate shell command, unless the end
of line is escaped with a backslash
‘\
’, in which case that line and the
next are combined. If the first characters of the command are any
combination of ‘@
’,
‘+
’, or
‘-
’, the command is treated
specially.
@
+
-n
is
given. This is similar to the effect of the .MAKE
special source, except that the effect can be limited to a single line of
a script.-
When make
is run in jobs mode with
-j
max_jobs, the entire script
for the target is fed to a single instance of the shell. In compatibility
(non-jobs) mode, each command is run in a separate process. If the command
contains any shell meta characters
(‘#=|^(){};&<>*?[]:$`\\n
’),
it is passed to the shell; otherwise make
attempts
direct execution. If a line starts with
‘-
’ and the shell has ErrCtl enabled,
failure of the command line is ignored as in compatibility mode. Otherwise
‘-
’ affects the entire job; the script
stops at the first command line that fails, but the target is not deemed to
have failed.
Makefiles should be written so that the mode of
make
operation does not change their behavior. For
example, any command which uses “cd” or “chdir”
without the intention of changing the directory for subsequent commands
should be put in parentheses so it executes in a subshell. To force the use
of a single shell, escape the line breaks so as to make the whole script one
command. For example:
avoid-chdir-side-effects: @echo "Building $@ in $$(pwd)" @(cd ${.CURDIR} && ${MAKE} $@) @echo "Back in $$(pwd)" ensure-one-shell-regardless-of-mode: @echo "Building $@ in $$(pwd)"; \ (cd ${.CURDIR} && ${MAKE} $@); \ echo "Back in $$(pwd)"
Since make
changes the current working
directory to ‘.OBJDIR’ before executing
any targets, each child process starts with that as its current working
directory.
Variables in make behave much like macros in the C preprocessor.
Variable assignments have the form ‘NAME op value’, where:
Whitespace around NAME, op and value is discarded.
The five operators that assign values to variables are:
=
+=
?=
:=
NOTE: References to undefined variables are not expanded. This can cause problems when variable modifiers are used.
!=
In most contexts where variables are expanded,
‘$$
’ expands to a single dollar sign.
In other contexts (most variable modifiers, string literals in conditions),
‘\$
’ expands to a single dollar
sign.
References to variables have the form
${
name[:
modifiers]}
or
$(
name[:
modifiers])
.
If the variable name consists of only a single character and the expression
contains no modifiers, the surrounding curly braces or parentheses are not
required. This shorter form is not recommended.
If the variable name contains a dollar, the name itself is expanded first. This allows almost arbitrary variable names, however names containing dollar, braces, parentheses or whitespace are really best avoided.
If the result of expanding a nested variable expression contains a
dollar sign (‘$
’), the result is
subject to further expansion.
Variable substitution occurs at four distinct times, depending on where the variable is being used.
.for
loop index variables are expanded on each loop iteration. Note that other
variables are not expanded when composing the body of a loop, so the
following example code:
.for i in 1 2 3 a+= ${i} j= ${i} b+= ${j} .endfor all: @echo ${a} @echo ${b}
prints:
1 2 3 3 3 3
After the loop is executed:
${:U1} ${:U2} ${:U3}
’,
which expands to ‘1 2 3
’.${:U3}
’, which expands
to ‘3
’.${j} ${j} ${j}
’, which
expands to ‘${:U3} ${:U3}
${:U3}
’ and further to ‘3 3
3
’.The four different classes of variables (in order of increasing precedence) are:
make
's
environment.Local variables can be set on a dependency line, unless
.MAKE.TARGET_LOCAL_VARIABLES is set to
‘false
’. The rest of the line (which
already has had global variables expanded) is the variable value. For
example:
COMPILER_WRAPPERS= ccache distcc icecc ${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
Only the targets ‘${OBJS}
’
are impacted by that filter (in “meta” mode) and simply
enabling/disabling any of the compiler wrappers does not render all of those
targets out-of-date.
NOTE: target-local variable assignments behave differently in that;
The seven built-in local variables are:
.SUFFIXES
) removed; also known as
‘*’.The shorter forms (‘>’, ‘!’, ‘<’, ‘%’, ‘?’, ‘*’, and ‘@’) are permitted for backward compatibility with historical makefiles and legacy POSIX make and are not recommended.
Variants of these variables with the punctuation followed
immediately by ‘D
’ or
‘F
’, e.g.
‘$(@D)
’, are legacy forms equivalent
to using the ‘:H
’ and
‘:T
’ modifiers. These forms are
accepted for compatibility with AT&T System V
UNIX makefiles and POSIX but are not recommended.
Four of the local variables may be used in sources on dependency lines because they expand to the proper value for each target on the line. These variables are ‘.TARGET’, ‘.PREFIX’, ‘.ARCHIVE’, and ‘.MEMBER’.
In addition, make
sets or knows about the
following variables:
make
was executed.
Refer to the description of ‘PWD’ for
more details.make
was executed with
(argv[0]).MAKE
because it is more compatible with other make variants and cannot be
confused with the special target with the same name.true
’, do not print error
information at the end.-V
option. If true, variable values printed with
-V
are fully expanded; if false, the raw variable
contents (which may include additional unexpanded variable references) are
shown.make
.MAKEFLAGS
’
may contain anything that may be specified on
make
's command line. Anything specified on
make
's command line is appended to the
.MAKEFLAGS variable, which is then added to the
environment for all programs that make
executes.make
. It
is read-only.make
is run with -j
,
the output for each target is prefixed with a token
--- target
---
${.newline}---${.MAKE:T}[${.MAKE.PID}]
’
would produce tokens like
---make[1234]
target ---
-j
option.-j
option supports use of ‘C
’.make
. The top-level
instance of make
has level 0, and each child make
has its parent level plus 1. This allows tests like: .if
${.MAKE.LEVEL} == 0
to protect things which should only be
evaluated in the top-level instance of make
.make
.make
looks for.make
, which is
useful for tracking dependencies. Each makefile is recorded only once,
regardless of the number of times read.make
. If a file that was
generated outside of .OBJDIR but within said
bailiwick is missing, the current target is considered out-of-date.Building
${.TARGET:H:tA}/${.TARGET:T}
make
runs in. It can contain these keywords:
compat
-B
, puts make
into “compat” mode.meta
make
into “meta” mode,
where meta files are created for each target to capture the commands
run, the output generated, and if
filemon(4) is
available, the system calls which are of interest to
make
. The captured output can be useful when
diagnosing errors.
make
will use the information in
the meta file to help determine if a target is out-of-date when the
normal dependency rules indicate it is not.
First, the commands to be executed, will be compared to those captured previously, if any differ, the target is out-of-date.
This allows for a huge improvement in the reliability and
efficiency of update builds. It is no longer necessary for targets
to depend on makefiles just in-case they set a variable that might
be relevant. Mechanisms such as
.MAKE.META.CMP_FILTER and
.NOMETA_CMP
, allow limiting or disabling
that comparison on a per target basis. A reference to the variable
.OODATE can be leveraged to block comparison
of certain commands. For example:
‘${.OODATE:M}
’ will expand to
nothing and have no impact on the target, its side-effect though,
will be to prevent comparison of any command line it appears on. For
documentation purposes
‘${.OODATE:MNOMETA_CMP}
’ is
useful.
If necessary, make
will then use
the information captured by
filemon(4), to check
the modification time of any file used in generating the target, if
any is newer, the target is out-of-date.
Such deep inspection can easily lead to cases where a target is always considered out-of-date, which is why .MAKE.META.IGNORE_FILTER, .MAKE.META.IGNORE_PATHS and .MAKE.META.IGNORE_PATTERNS, are provided to limit that inspection when necessary.
curdirOk=
bfmake
does not create
.meta files in
‘.CURDIR’. This can be overridden
by setting bf to a value which represents
true.missing-meta=
bfmissing-filemon=
bfnofilemon
env
verbose
ignore-cmd
.NOMETA_CMP
.silent=
bf.SILENT
.randomize-targets
make
will check that
.OBJDIR is writable, and issue a warning if
not.make
is warning about an unwritable
.OBJDIR, report the variables listed in
MAKE_PRINT_VAR_ON_ERROR to help debug.MAKEFLAGS
’. This behavior can be
disabled by assigning an empty value to
‘.MAKEOVERRIDES’ within a makefile.
Extra variables can be exported from a makefile by appending their names
to ‘.MAKEOVERRIDES’.
‘MAKEFLAGS
’ is re-exported whenever
‘.MAKEOVERRIDES’ is modified.make
was built with
filemon(4) support, this is
set to the path of the device node. This allows makefiles to test for this
support.make
. It is read-only.make
. It is
read-only.make
stops due to an error, it sets
‘.ERROR_TARGET’ to the name of the
target that failed, ‘.ERROR_EXIT’ to
the exit status of the failed target,
‘.ERROR_CMD’ to the commands of the
failed target, and in “meta” mode, it also sets
‘.ERROR_CWD’ to the
getcwd(3), and
‘.ERROR_META_FILE’ to the path of the
meta file (if any) describing the failed target. It then prints its name
and the value of ‘.CURDIR’ as well as
the value of any variables named in
‘MAKE_PRINT_VAR_ON_ERROR’.$$
’ are preserved when
doing ‘:=
’ assignments. The default
is true, for compatibility with other makes. If set to false,
‘$$
’ becomes
‘$
’ per normal evaluation
rules.false
’, apparent variable
assignments in dependency lines are treated as normal sources.make
. It is
read-only.:@
modifier to put a newline between iterations of the loop rather than a
space. For example, in case of an error, make
prints the variable names and their values using:
${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
${MAKEOBJDIRPREFIX}
${.CURDIR}
(Only if
‘MAKEOBJDIRPREFIX
’ is set in
the environment or on the command line.)
${MAKEOBJDIR}
(Only if
‘MAKEOBJDIR
’ is set in the
environment or on the command line.)
${.CURDIR}
/obj.${MACHINE}
${.CURDIR}
/obj${.CURDIR}
${.CURDIR}
Variable expansion is performed on the value before it is
used, so expressions such as
${.CURDIR:S,^/usr/src,/var/obj,}
may be used.
This is especially useful with
‘MAKEOBJDIR
’.
‘.OBJDIR’ may be modified
in the makefile via the special target
‘.OBJDIR
’. In all cases,
make
changes to the specified directory if it
exists, and sets ‘.OBJDIR’ and
‘PWD’ to that directory before
executing any targets.
Except in the case of an explicit
‘.OBJDIR
’ target,
make
checks that the specified directory is
writable and ignores it if not. This check can be skipped by setting the
environment variable
‘MAKE_OBJDIR_CHECK_WRITABLE
’ to
“no”.
:=
’.make
searches for files. To update this search list, use the special target
‘.PATH
’ rather than modifying the
variable directly..POSIX
’
target.make
normally sets ‘.CURDIR’ to the
canonical path given by
getcwd(3). However, if the
environment variable ‘PWD
’ is set
and gives a path to the current directory, make
sets ‘.CURDIR’ to the value of
‘PWD
’ instead. This behavior is
disabled if ‘MAKEOBJDIRPREFIX
’ is
set or ‘MAKEOBJDIR
’ contains a
variable transform. ‘PWD’ is set to
the value of ‘.OBJDIR’ for all
programs which make
executes.make
searches for makefiles, referred to as the system include path. To update
this search list, use the special target
‘.SYSPATH
’ rather than modifying the
variable which is read-only.make
searches for files. This variable is
supported for compatibility with old make programs only, use
‘.PATH’ instead.The general format of a variable expansion is:
${
variable[:
modifier[:
...]]}
Each modifier begins with a colon. To escape a colon, precede it
with a backslash ‘\
’.
A list of indirect modifiers can be specified via a variable, as follows:
modifier_variable=
modifier[:
...]${
variable:${
modifier_variable}
[:
...]}
In this case, the first modifier in the
modifier_variable does not start with a colon, since
that colon already occurs in the referencing variable. If any of the
modifiers in the modifier_variable contains a dollar
sign (‘$
’), these must be doubled to
avoid early expansion.
Some modifiers interpret the expression value as a single string, others treat the expression value as a whitespace-separated list of words. When splitting a string into words, whitespace can be escaped using double quotes, single quotes and backslashes, like in the shell. The quotes and backslashes are retained in the words.
The supported modifiers are:
:E
:H
:M
pattern*
’,
‘?
’, and
‘[]
’) may be used. The wildcard
characters may be escaped with a backslash
(‘\
’). As a consequence of the way
values are split into words, matched, and then joined, the construct
‘${VAR:M*}
’ removes all leading and
trailing whitespace and normalizes the inter-word spacing to a single
space.:N
pattern:M
’,
selecting all words which do not match
pattern.:O
:On
k
’,
‘M
’ or
‘G
’ is multiplied by the appropriate
factor, which is 1024 for ‘k
’,
1048576 for ‘M
’, or 1073741824 for
‘G
’. Both upper- and lower-case
letters are accepted.:Or
:Orn
:Ox
:=
’ to prevent such behavior. For
example,
LIST= uno due tre quattro RANDOM_LIST= ${LIST:Ox} STATIC_RANDOM_LIST:= ${LIST:Ox} all: @echo "${RANDOM_LIST}" @echo "${RANDOM_LIST}" @echo "${STATIC_RANDOM_LIST}" @echo "${STATIC_RANDOM_LIST}"
quattro due tre uno tre due quattro uno due uno quattro tre due uno quattro tre
:Q
:q
make
. This is equivalent
to ‘:S/\$/&&/g:Q
’.:R
:range
[=
count]:gmtime
[=
timestamp]%s
’
format should only be used with
‘:localtime
’. If a
timestamp value is not provided or is 0, the current
time is used.:hash
:localtime
[=
timestamp]:mtime
[=
timestamp]st_mtime
’ as the new
value. If stat(2) fails; use
timestamp or current time. If
timestamp is set to
‘error
’, then
stat(2) failure will cause an
error.:tA
:tl
:ts
c:tt
:tu
:tW
:[*]
’.:tw
:[@]
’.:S
/old_string/new_string/[1gW
]g
’ is appended to the last
delimiter of the pattern, all occurrences in each word are replaced. If a
‘1
’ is appended to the last
delimiter of the pattern, only the first occurrence is affected. If a
‘W
’ is appended to the last
delimiter of the pattern, the value is treated as a single word. If
old_string begins with a caret
(‘^
’),
old_string is anchored at the beginning of each
word. If old_string ends with a dollar sign
(‘$
’), it is anchored at the end of
each word. Inside new_string, an ampersand
(‘&
’) is replaced by
old_string (without the anchoring
‘^
’ or
‘$
’). Any character may be used as
the delimiter for the parts of the modifier string. The anchoring,
ampersand and delimiter characters can be escaped with a backslash
(‘\
’).
Both old_string and new_string may contain nested expressions. To prevent a dollar sign from starting a nested expression, escape it with a backslash.
:C
/pattern/replacement/[1gW
]:C
modifier works like the
:S
modifier except that the old and new strings,
instead of being simple strings, are an extended regular expression
pattern (see
regex(3)) and an
ed(1)-style
replacement. Normally, the first occurrence of the
pattern pattern in each word of the value is
substituted with replacement. The
‘1
’ modifier causes the substitution
to apply to at most one word; the
‘g
’ modifier causes the substitution
to apply to as many instances of the search pattern
pattern as occur in the word or words it is found
in; the ‘W
’ modifier causes the
value to be treated as a single word (possibly containing embedded
whitespace).
As for the :S
modifier, the
pattern and replacement are
subjected to variable expansion before being parsed as regular
expressions.
:T
:u
:?
true_string:
false_string.if
conditional expression, evaluates to true,
return as its value the true_string, otherwise
return the false_string. Since the variable name is
used as the expression, :? must be the first modifier after the variable
name itself—which, of course, usually
contains variable expansions. A common error is trying to use expressions
like
${NUMBERS:M42:?match:no}
${"${NUMBERS:M42}" !=
"":?match:no}
:
old_string=
new_string:
’ in either
old_string or new_string is
treated as a regular character, not as the end of the modifier.
If old_string does not contain the
pattern matching character ‘%
’,
and the word ends with old_string or equals it,
that suffix is replaced with new_string.
Otherwise, the first ‘%
’
in old_string matches a possibly empty substring
of arbitrary characters, and if the whole pattern is found in the word,
the matching part is replaced with new_string, and
the first occurrence of ‘%
’ in
new_string (if any) is replaced with the substring
matched by the ‘%
’.
Both old_string and new_string may contain nested expressions. To prevent a dollar sign from starting a nested expression, escape it with a backslash.
:@
varname@
string@
.for
loops, expansion occurs at
the time of reference. For each word in the value, assign the word to the
variable named varname and evaluate
string. The ODE convention is that
varname should start and end with a period, for
example:
${LINKS:@.LINK.@${LN} ${TARGET}
${.LINK.}@}
However, a single-letter variable is often more readable:
${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
:_
[=
var]$_
’ or the named
var for later reference. Example usage:
M_cmpv.units = 1 1000 1000000
M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \
\* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
.if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}}
$_
’ is used to save the result
of the ‘:S
’ modifier which is later
referenced using the index values from
‘:range
’.:U
newval${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}}
${VAR:D:Unewval}
:D
newval:L
:P
:!
cmd!
:sh
::=
strThe ‘::
’ helps avoid
false matches with the AT&T System V
UNIX style ‘:=
’ modifier
and since substitution always occurs, the
‘::=
’ form is vaguely
appropriate.
::?=
str::=
but only if the variable does not
already have a value.::+=
str::!=
cmd:[
range]
An empty value, or a value that consists entirely of
white-space, is treated as a single word. For the purposes of the
‘:[]
’ modifier, the words are
indexed both forwards using positive integers (where index 1 represents
the first word), and backwards using negative integers (where index -1
represents the last word).
The range is subjected to variable expansion, and the expanded result is then interpreted as follows:
..
end:[2..-1]
’ selects all words
from the second word to the last word. If start
is greater than end, the words are output in
reverse order. For example,
‘:[-1..1]
’ selects all the words
from last to first. If the list is already ordered, this effectively
reverses the list, but it is more efficient to use
‘:Or
’ instead of
‘:O:[-1..1]
’.*
$*
in Bourne shell.:[*]
’.@
$@
in Bourne shell.#
make
offers directives for including
makefiles, conditionals and for loops. All these directives are identified
by a line beginning with a single dot
(‘.
’) character, followed by the
keyword of the directive, such as include
or
if
.
Files are included with either .include
<
file>
or
.include
"
file"
.
Variables between the angle brackets or double quotes are expanded to form
the file name. If angle brackets are used, the included makefile is expected
to be in the system makefile directory. If double quotes are used, the
including makefile's directory and any directories specified using the
-I
option are searched before the system makefile
directory.
For compatibility with other make variants,
‘include
file
...’ (without leading dot) is also
accepted.
If the include statement is written as
.-include
or as .sinclude
,
errors locating and/or opening include files are ignored.
If the include statement is written as
.dinclude
, not only are errors locating and/or
opening include files ignored, but stale dependencies within the included
file are ignored just like in .MAKE.DEPENDFILE.
The directives for exporting and unexporting variables are:
.export
variable ...For compatibility with other make programs,
export
variable=
value
(without leading dot) is also accepted.
Appending a variable name to .MAKE.EXPORTED is equivalent to exporting a variable.
.export-all
.
’). This is not affected by the
-X
flag, so should be used with caution..export-env
variable ....export
’, except that
the variable is not appended to .MAKE.EXPORTED. This
allows exporting a value to the environment which is different from that
used by make
internally..export-literal
variable ....export-env
’, except
that variables in the value are not expanded..unexport
variable ....export
’. The
specified global variable is removed from
.MAKE.EXPORTED. If no variable list is provided, all
globals are unexported, and .MAKE.EXPORTED
deleted..unexport-env
.if ${.MAKE.LEVEL} == 0
PATH := ${PATH}.unexport-env
.export PATH
.endif
PATH
’, which is the minimal useful
environment. Actually ‘.MAKE.LEVEL’ is
also pushed into the new environment.The directives for printing messages to the output are:
.info
message.warning
messagewarning:
’
is printed along with the name of the makefile and line number..error
messagemake
exits immediately.The directives for conditionals are:
.if
[!
]expression
[operator expression ...].ifdef
[!
]variable
[operator variable ...].ifndef
[!
]variable
[operator variable ...].ifmake
[!
]target
[operator target ...].ifnmake
[!
]target
[operator target ...].else
.elif
[!
]expression
[operator expression ...].else
’ followed by
‘.if
’..elifdef
[!
]variable
[operator variable ...].else
’ followed by
‘.ifdef
’..elifndef
[!
]variable
[operator variable ...].else
’ followed by
‘.ifndef
’..elifmake
[!
]target
[operator target ...].else
’ followed by
‘.ifmake
’..elifnmake
[!
]target
[operator target ...].else
’ followed by
‘.ifnmake
’..endif
The operator may be any one of the following:
make
only evaluates a conditional as far
as is necessary to determine its value. Parentheses can be used to override
the operator precedence. The boolean operator
‘!
’ may be used to logically negate an
expression, typically a function call. It is of higher precedence than
‘&&
’.
The value of expression may be any of the following function call expressions:
defined
(
varname)
make
(
target)
make
's command line or was declared the default
target (either implicitly or explicitly, see .MAIN)
before the line containing the conditional.empty
(
varname[:modifiers])
exists
(
pathname)
target
(
target)
commands
(
target)
Expression may also be an arithmetic or
string comparison. Variable expansion is performed on both sides of the
comparison. If both sides are numeric and neither is enclosed in quotes, the
comparison is done numerically, otherwise lexicographically. A string is
interpreted as a hexadecimal integer if it is preceded by
0x
, otherwise it is interpreted as a decimal
floating-point number; octal numbers are not supported.
All comparisons may use the operators
‘==
’ and
‘!=
’. Numeric comparisons may also use
the operators ‘<
’,
‘<=
’,
‘>
’ and
‘>=
’.
If the comparison has neither a comparison operator nor a right side, the expression evaluates to true if it is nonempty and its numeric value (if any) is not zero.
When make
is evaluating one of these
conditional expressions, and it encounters a (whitespace-separated) word it
doesn't recognize, either the “make” or
“defined” function is applied to it, depending on the form of
the conditional. If the form is
‘.ifdef
’,
‘.ifndef
’ or
‘.if
’, the “defined”
function is applied. Similarly, if the form is
‘.ifmake
’ or
‘.ifnmake
’, the “make”
function is applied.
If the conditional evaluates to true, parsing of the makefile
continues as before. If it evaluates to false, the following lines until the
corresponding ‘.elif
’ variant,
‘.else
’ or
‘.endif
’ are skipped.
For loops are typically used to apply a set of rules to a list of files. The syntax of a for loop is:
The expression is expanded and then split into words. On each iteration of the loop, one word is taken and assigned to each variable, in order, and these variables are substituted into the make-lines inside the body of the for loop. The number of words must come out even; that is, if there are three iteration variables, the number of words provided must be a multiple of three.
If ‘.break
’ is encountered
within a .for
loop, it causes early termination of
the loop, otherwise a parse error.
.undef
variable ...Comments begin with a hash
(‘#
’) character, anywhere but in a
shell command line, and continue to the end of an unescaped new line.
.EXEC
.IGNORE
-
’)..MADE
.MAKE
-n
or -t
options were
specified. Normally used to mark recursive
make
s..META
.PHONY
, .MAKE
, or
.SPECIAL
. Usage in conjunction with
.MAKE
is the most likely case. In
“meta” mode, the target is out-of-date if the meta file is
missing..NOMETA
.PHONY
, .MAKE
, or
.SPECIAL
targets..NOMETA_CMP
skip-compare-for-some: @echo this is compared @echo this is not ${.OODATE:M.NOMETA_CMP} @echo this is also compared
:M
pattern suppresses any expansion of the
unwanted variable..NOPATH
.NOTMAIN
make
selects the first target it
encounters as the default target to be built if no target was specified.
This source prevents this target from being selected..OPTIONAL
make
can't figure out how to create it, it ignores this fact and assumes the
file isn't needed or already exists..PHONY
-t
option. Suffix-transformation rules are not applied to
.PHONY
targets..PRECIOUS
make
is interrupted, it normally removes any
partially made targets. This source prevents the target from being
removed..RECURSIVE
.MAKE
..SILENT
@
’)..USE
make
's version of a macro.
When the target is used as a source for another target, the other target
acquires the commands, sources, and attributes (except for
.USE
) of the source. If the target already has
commands, the .USE
target's commands are appended
to them..USEBEFORE
.USE
, but instead of appending, prepend the
.USEBEFORE
target commands to the target..WAIT
.WAIT
appears in a dependency line, the sources
that precede it are made before the sources that succeed it in the line.
Since the dependents of files are not made until the file itself could be
made, this also stops the dependents being built unless they are needed
for another branch of the dependency tree. So given:
x: a .WAIT b echo x a: echo a b: b1 echo b b1: echo b1
a
’,
‘b1
’,
‘b
’,
‘x
’.
The ordering imposed by .WAIT
is only
relevant for parallel makes.
Special targets may not be included with other targets, i.e. they must be the only target specified.
.BEGIN
.DEFAULT
.USE
rule for any target (that
was used only as a source) that make
can't figure
out any other way to create. Only the shell script is used. The
.IMPSRC variable of a target that inherits
.DEFAULT
's commands is set to the target's own
name..DELETE_ON_ERROR
.END
.ERROR
.IGNORE
.IGNORE
attribute. If no sources are specified, this is the equivalent of
specifying the -i
option..INTERRUPT
make
is interrupted, the commands for this
target are executed..MAIN
make
is invoked,
this target is built..MAKEFLAGS
make
at the time when the makefiles are read. The
flags are as if typed to the shell, though the -f
option has no effect..NOPATH
.NOPATH
attribute to any specified
sources..NOTPARALLEL
.NO_PARALLEL
.NOTPARALLEL
, for compatibility with
other pmake variants..NOREADONLY
.OBJDIR
make
changes the current working directory to it
and updates the value of
‘.OBJDIR’..ORDER
Since the dependents of a target do not get built until the
target itself could be built, unless
‘a
’ is built by another part of
the dependency graph, the following is a dependency loop:
.ORDER: b a b: a
.PATH
.DOTLAST
target, the current working
directory is searched last..PATH.
suffix.PATH
but applies only to files with a
particular suffix. The suffix must have been previously declared with
.SUFFIXES
..PHONY
.PHONY
attribute to any specified
sources..POSIX
1003.2
’ and the makefile
‘<posix.mk>
’ is included if it
exists, to provide POSIX-compatible default rules. If
make
is run with the -r
flag, only ‘posix.mk
’ contributes to
the default rules. In POSIX-compatible mode, the AT&T System V UNIX
style substitution modifier is checked first rather than as a
fallback..PRECIOUS
.PRECIOUS
attribute to any specified
sources. If no sources are specified, the
.PRECIOUS
attribute is applied to every target in
the file..READONLY
.SHELL
make
uses to execute commands.
The sources are a set of
field=
value
pairs.
name
sh
, ksh
,
and csh
.path
hasErrCtl
check
ignore
echo
quiet
filter
quiet
command. It is typically identical to
quiet
.errFlag
echoFlag
newline
.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \ check="set -e" ignore="set +e" \ echo="set -v" quiet="set +v" filter="set +v" \ echoFlag=v errFlag=e newline="'\n'"
.SILENT
.SILENT
attribute to any specified
sources. If no sources are specified, the .SILENT
attribute is applied to every command in the file..STALE
.SUFFIXES
make
. If no
sources are specified, any previously specified suffixes are deleted. It
allows the creation of suffix-transformation rules.
Example:
.SUFFIXES: .c .o .c.o: cc -o ${.TARGET} -c ${.IMPSRC}
.SYSPATH
make
searches for makefiles. If no
sources are specified, any previously specified directories are removed
from the system include path.make
uses the following environment
variables, if they exist: MACHINE
,
MACHINE_ARCH
, MAKE
,
MAKEFLAGS
, MAKEOBJDIR
,
MAKEOBJDIRPREFIX
,
MAKESYSPATH
, PWD
, and
TMPDIR
.
MAKEOBJDIRPREFIX
and
MAKEOBJDIR
should be set in the environment or on
the command line to make
and not as makefile
variables; see the description of
‘.OBJDIR’ for more details. It is
possible to set these via makefile variables but unless done very early and
the ‘.OBJDIR
’ target is used to reset
‘.OBJDIR’, there may be unexpected side
effects.
The basic make syntax is compatible between different make variants; however the special variables, variable modifiers and conditionals are not.
An incomplete list of changes in older versions of
make
:
The way that .for loop variables are substituted changed after NetBSD 5.0 so that they still appear to be variable expansions. In particular this stops them being treated as syntax, and removes some obscure problems using them in .if statements.
The way that parallel makes are scheduled changed in NetBSD 4.0 so that .ORDER and .WAIT apply recursively to the dependent nodes. The algorithms used may change again in the future.
Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not
support most of the features of make
as described in
this manual. Most notably:
.WAIT
and .ORDER
declarations and most functionality pertaining to parallelization. (GNU
make supports parallelization but lacks the features needed to control it
effectively.).PHONY
,
.PRECIOUS
, and
.SUFFIXES
.:old=new
’ string substitution,
which does not portably support globbing with
‘%
’ and historically only works on
declared suffixes.$>
variable even in its short form; most
makes support this functionality but its name varies.Some features are somewhat more portable, such as assignment with
+=
, ?=
, and
!=
. The .PATH functionality is
based on an older feature VPATH
found in GNU make
and many versions of SVR4 make; however, historically its behavior is too
ill-defined (and too buggy) to rely upon.
The $@
and $<
variables are more or less universally portable, as is the
$(MAKE)
variable. Basic use of suffix rules (for
files only in the current directory, not trying to chain transformations
together, etc.) is also reasonably portable.
A make
command appeared in
Version 7 AT&T UNIX. This
make
implementation is based on Adam de Boor's pmake
program, which was written for Sprite at Berkeley. It was designed to be a
parallel distributed make running jobs on different machines using a daemon
called “customs”.
Historically the target/dependency FRC
has
been used to FoRCe rebuilding (since the target/dependency does not exist
... unless someone creates an FRC file).
The make
syntax is difficult to parse. For
instance, finding the end of a variable's use should involve scanning each
of the modifiers, using the correct terminator for each field. In many
places make
just counts {} and () in order to find
the end of a variable expansion.
There is no way of escaping a space character in a filename.
In jobs mode, when a target fails; make
will put an error token into the job token pool. This will cause all other
instances of make
using that token pool to abort the
build and exit with error code 6. Sometimes the attempt to suppress a
cascade of unnecessary errors, can result in a seemingly unexplained
‘*** Error code 6
’
April 4, 2025 | NetBSD 10.99 |