summaryrefslogtreecommitdiff
path: root/static/freebsd/man1/bmake.1
diff options
context:
space:
mode:
Diffstat (limited to 'static/freebsd/man1/bmake.1')
-rw-r--r--static/freebsd/man1/bmake.12927
1 files changed, 2927 insertions, 0 deletions
diff --git a/static/freebsd/man1/bmake.1 b/static/freebsd/man1/bmake.1
new file mode 100644
index 00000000..1e0de219
--- /dev/null
+++ b/static/freebsd/man1/bmake.1
@@ -0,0 +1,2927 @@
+.\" $NetBSD: make.1,v 1.390 2026/02/08 11:02:03 rillig Exp $
+.\"
+.\" Copyright (c) 1990, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" from: @(#)make.1 8.4 (Berkeley) 3/19/94
+.\"
+.Dd February 8, 2026
+.Dt BMAKE 1
+.Os
+.Sh NAME
+.Nm bmake
+.Nd maintain program dependencies
+.Sh SYNOPSIS
+.Nm
+.Op Fl BeikNnqrSstWwX
+.Op Fl C Ar directory
+.Op Fl D Ar variable
+.Op Fl d Ar flags
+.Op Fl f Ar makefile
+.Op Fl I Ar directory
+.Op Fl J Ar private
+.Op Fl j Ar max_jobs
+.Op Fl m Ar directory
+.Op Fl T Ar file
+.Op Fl V Ar variable
+.Op Fl v Ar variable
+.Op Ar variable\| Ns Cm \&= Ns Ar value No ...
+.Op Ar target No ...
+.Sh DESCRIPTION
+.Nm
+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
+.Fl f Ar makefile
+option is given,
+.Nm
+looks for the makefiles listed in
+.Va .MAKE.MAKEFILE_PREFERENCE
+(default
+.Sq Pa makefile ,
+.Sq Pa Makefile )
+in order to find the specifications.
+If the file
+.Sq Pa .depend
+exists, it is read, see
+.Xr mkdep 1 .
+.Pp
+This manual page is intended as a reference document only.
+For a more thorough description of
+.Nm
+and makefiles, please refer to
+.%T "PMake \- A Tutorial"
+(from 1993).
+.Pp
+.Nm
+prepends the contents of the
+.Ev MAKEFLAGS
+environment variable to the command line arguments before parsing them.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl B
+Try to be backwards compatible by executing a single shell per command and
+by making the sources of a dependency line in sequence.
+.It Fl C Ar directory
+Change to
+.Ar directory
+before reading the makefiles or doing anything else.
+If multiple
+.Fl C
+options are specified, each is interpreted relative to the previous one:
+.Fl C Pa / Fl C Pa etc
+is equivalent to
+.Fl C Pa /etc .
+.It Fl D Ar variable
+Define
+.Ar variable
+to be 1, in the global scope.
+.It Fl d Oo Cm \- Oc Ns Ar flags
+Turn on debugging, and specify which portions of
+.Nm
+are to print debugging information.
+Unless the flags are preceded by
+.Ql \- ,
+they are added to the
+.Ev 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
+.Cm 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
+.Ar flags
+are:
+.Bl -tag -width Ds
+.It Cm A
+Print all possible debugging information;
+equivalent to specifying all of the debugging flags.
+.It Cm a
+Print debugging information about archive searching and caching.
+.It Cm C
+Print debugging information about the current working directory.
+.It Cm c
+Print debugging information about conditional evaluation.
+.It Cm d
+Print debugging information about directory searching and caching.
+.It Cm e
+Print debugging information about failed commands and targets.
+.It Cm F Ns Oo Cm \&+ Oc Ns Ar filename
+Specify where debugging output is written.
+This must be the last flag, because it consumes the remainder of
+the argument.
+If the character immediately after the
+.Cm F
+flag is
+.Ql \&+ ,
+the file is opened in append mode;
+otherwise the file is overwritten.
+If the file name is
+.Ql stdout
+or
+.Ql stderr ,
+debugging output is written to the standard output or standard error output
+respectively (and the
+.Ql \&+
+option has no effect).
+Otherwise, the output is written to the named file.
+If the file name ends with
+.Ql .%d ,
+the
+.Ql %d
+is replaced by the pid.
+.It Cm f
+Print debugging information about loop evaluation.
+.It Cm g1
+Print the input graph before making anything.
+.It Cm g2
+Print the input graph after making everything, or before exiting
+on error.
+.It Cm g3
+Print the input graph before exiting on error.
+.It Cm h
+Print debugging information about hash table operations.
+.It Cm j
+Print debugging information about running multiple shells.
+.It Cm L
+Turn on lint checks.
+This throws errors for variable assignments that do not parse correctly,
+at the time of assignment, so the file and line number are available.
+.It Cm l
+Print commands in Makefiles regardless of whether or not they are prefixed by
+.Ql @
+or other
+.Dq quiet
+flags.
+Also known as
+.Dq loud
+behavior.
+.It Cm M
+Print debugging information about
+.Dq meta
+mode decisions about targets.
+.It Cm m
+Print debugging information about making targets, including modification
+dates.
+.It Cm n
+Don't delete the temporary command scripts created when running commands.
+These temporary scripts are created in the directory
+referred to by the
+.Ev TMPDIR
+environment variable, or in
+.Pa /tmp
+if
+.Ev TMPDIR
+is unset or set to the empty string.
+The temporary scripts are created by
+.Xr mkstemp 3 ,
+and have names of the form
+.Pa makeXXXXXX .
+.Em NOTE :
+This can create many files in
+.Ev TMPDIR
+or
+.Pa /tmp ,
+so use with care.
+.It Cm p
+Print debugging information about makefile parsing.
+.It Cm s
+Print debugging information about suffix-transformation rules.
+.It Cm t
+Print debugging information about target list maintenance.
+.It Cm V
+Force the
+.Fl V
+option to print raw values of variables,
+overriding the default behavior set via
+.Va .MAKE.EXPAND_VARIABLES .
+.It Cm v
+Print debugging information about variable assignment and expansion.
+.It Cm x
+Run shell commands with
+.Fl x
+so the actual commands are printed as they are executed.
+.El
+.It Fl e
+Let environment variables override global variables within makefiles.
+.It Fl f Ar makefile
+Specify a makefile to read instead of one of the defaults listed in
+.Va .MAKE.MAKEFILE_PREFERENCE .
+If
+.Ar makefile
+is
+.Ql \&- ,
+standard input is read.
+If
+.Ar makefile
+starts with the string
+.Ql \&.../ ,
+.Nm
+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.
+.It Fl I Ar directory
+Specify a directory in which to search for makefiles and included makefiles.
+The system makefile directory (or directories, see the
+.Fl m
+option) is automatically included as part of this list.
+.It Fl i
+Ignore non-zero exit of shell commands in the makefile.
+Equivalent to specifying
+.Ql \&-
+before each command line in the makefile.
+.It Fl J Ar private
+This option should
+.Em not
+be specified by the user.
+.Pp
+When the
+.Fl 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.
+.It Fl j Ar max_jobs
+Specify the maximum number of jobs that
+.Nm
+may have running at any one time.
+If
+.Ar max_jobs
+is a floating point number, or ends with
+.Ql C ,
+then the value is multiplied by the number of CPUs reported online by
+.Xr sysconf 3 .
+The value of
+.Ar max_jobs
+is saved in
+.Va .MAKE.JOBS .
+Turns compatibility mode off, unless the
+.Fl 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.
+.Pp
+A job token pool with
+.Ar max_jobs
+tokens is used to control the total number of jobs running.
+Each instance of
+.Nm
+will wait for a token from the pool before running a new job.
+.It Fl k
+Continue processing after errors are encountered, but only on those targets
+that do not depend on the target whose creation caused the error.
+.It Fl m Ar directory
+Specify a directory in which to search for
+.Pa sys.mk
+and makefiles included via the
+.Li \&< Ns Ar file Ns Li \&> Ns -style
+include statement.
+The
+.Fl m
+option can be used multiple times to form a search path.
+This path overrides the default system include path
+.Pa /usr/share/mk .
+Furthermore, the system include path is appended to the search path used for
+.Li \*q Ns Ar file Ns Li \*q Ns -style
+include statements (see the
+.Fl I
+option).
+The system include path can be referenced via the read-only variable
+.Va .SYSPATH .
+.Pp
+If a directory name in the
+.Fl m
+argument (or the
+.Ev MAKESYSPATH
+environment variable) starts with the string
+.Ql \&.../ ,
+.Nm
+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
+.Ql \&.../
+specification in the
+.Fl m
+argument.
+This feature allows
+.Nm
+to easily search in the current source tree for customized
+.Pa sys.mk
+files (e.g., by using
+.Ql \&.../mk/sys.mk
+as an argument).
+.It Fl n
+Display the commands that would have been executed, but do not
+actually execute them unless the target depends on the
+.Va .MAKE
+special source (see below) or the command is prefixed with
+.Sq Cm + .
+.It Fl N
+Display the commands that would have been executed,
+but do not actually execute any of them;
+useful for debugging top-level makefiles
+without descending into subdirectories.
+.It Fl q
+Do not execute any commands,
+instead exit 0 if the specified targets are up to date, and 1 otherwise.
+.It Fl r
+Do not use the built-in rules specified in the system makefile.
+.It Fl S
+Stop processing if an error is encountered.
+This is the default behavior and the opposite of
+.Fl k .
+.It Fl s
+Do not echo any commands as they are executed.
+Equivalent to specifying
+.Sq Ic @
+before each command line in the makefile.
+.It Fl T Ar tracefile
+When used with the
+.Fl j
+flag,
+append a trace record to
+.Ar tracefile
+for each job started and completed.
+.It Fl t
+Rather than re-building a target as specified in the makefile, create it
+or update its modification time to make it appear up-to-date.
+.It Fl V Ar variable
+Print the value of
+.Ar variable .
+Do not build any targets.
+Multiple instances of this option may be specified;
+the variables are printed one per line,
+with a blank line for each null or undefined variable.
+The value printed is extracted from the global scope after all
+makefiles have been read.
+.Pp
+By default, the raw variable contents (which may
+include additional unexpanded variable references) are shown.
+If
+.Ar variable
+contains a
+.Ql \&$ ,
+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
+.Va .MAKE.EXPAND_VARIABLES
+is set to true and the
+.Fl dV
+option has not been used to override it.
+.Pp
+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
+.Fl dv
+debug mode can be used to see these at the cost of generating
+substantial extraneous output.
+.It Fl v Ar variable
+Like
+.Fl V ,
+but all printed variables are always expanded to their complete value.
+The last occurrence of
+.Fl V
+or
+.Fl v
+decides whether all variables are expanded or not.
+.It Fl W
+Treat any warnings during makefile parsing as errors.
+.It Fl w
+Print entering and leaving directory messages, pre and post processing.
+.It Fl X
+Don't export variables passed on the command line to the environment
+individually.
+Variables passed on the command line are still exported via the
+.Ev MAKEFLAGS
+environment variable.
+This option may be useful on systems which have a small limit on the
+size of command arguments.
+.It Ar variable\| Ns Cm \&= Ns Ar value
+Set the value of the variable
+.Ar variable
+to
+.Ar value .
+Normally, all values passed on the command line are also exported to
+sub-makes in the environment.
+The
+.Fl X
+flag disables this behavior.
+Variable assignments should follow options for POSIX compatibility
+but no ordering is enforced.
+.El
+.Pp
+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.
+.Pp
+Lines may be continued from one line to the next
+by ending them with a backslash
+.Pq Ql \e .
+The trailing newline character and initial whitespace on the following
+line are compressed into a single space.
+.Sh FILE DEPENDENCY SPECIFICATIONS
+Dependency lines consist of one or more targets, an operator, and zero
+or more sources.
+This creates a relationship where the targets
+.Dq 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:
+.Bl -tag -width flag
+.It Ic \&:
+Many dependency lines may name this target but only one may have
+attached shell commands.
+All sources named in all dependency lines are considered together,
+and if needed the attached shell commands are run to create or
+re-create the target.
+If
+.Nm
+is interrupted, the target is removed.
+.It Ic \&!
+The same, but the target is always re-created whether or not it is out
+of date.
+.It Ic \&::
+Any dependency line may have attached shell commands, but each one
+is handled independently: its sources are considered and the attached
+shell commands are run if the target is out of date with respect to
+(only) those sources.
+Thus, different groups of the attached shell commands may be run
+depending on the circumstances.
+Furthermore, unlike
+.Ic \&: ,
+for dependency lines with no sources, the attached shell
+commands are always run.
+Also unlike
+.Ic \&: ,
+the target is not removed if
+.Nm
+is interrupted.
+.El
+.Pp
+All dependency lines mentioning a particular target must use the same
+operator.
+.Pp
+Targets and sources may contain the shell wildcard values
+.Ql \&? ,
+.Ql * ,
+.Ql [] ,
+and
+.Ql {} .
+The values
+.Ql \&? ,
+.Ql * ,
+and
+.Ql []
+may only be used as part of the final component of the target or source,
+and only match existing files.
+The value
+.Ql {}
+need not necessarily be used to describe existing files.
+Expansion is in directory order, not alphabetically as done in the shell.
+.Sh SHELL COMMANDS
+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
+.Em 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
+.Sq Ic \&::
+operator is used, however, all rules may include scripts,
+and the respective scripts are executed in the order found.
+.Pp
+Each line is treated as a separate shell command,
+unless the end of line is escaped with a backslash
+.Ql \e ,
+in which case that line and the next are combined.
+If the first characters of the command are any combination of
+.Sq Ic @ ,
+.Sq Ic + ,
+or
+.Sq Ic \- ,
+the command is treated specially.
+.Bl -tag -offset indent -width indent
+.It Ic @
+causes the command not to be echoed before it is executed.
+.It Ic +
+causes the command to be executed even when
+.Fl n
+is given.
+This is similar to the effect of the
+.Va .MAKE
+special source,
+except that the effect can be limited to a single line of a script.
+.It Ic \-
+in compatibility mode
+causes any non-zero exit status of the command line to be ignored.
+.El
+.Pp
+When
+.Nm
+is run in jobs mode with
+.Fl j Ar 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
+.Pq Ql #=|^(){};&<>*?[]:$`\e\en ,
+it is passed to the shell; otherwise
+.Nm
+attempts direct execution.
+If a line starts with
+.Sq Ic \-
+and the shell has ErrCtl enabled,
+failure of the command line is ignored as in compatibility mode.
+Otherwise
+.Sq Ic \-
+affects the entire job;
+the script stops at the first command line that fails,
+but the target is not deemed to have failed.
+.Pp
+Makefiles should be written so that the mode of
+.Nm
+operation does not change their behavior.
+For example, any command which uses
+.Dq cd
+or
+.Dq 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:
+.Bd -literal -offset indent
+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)"; \e
+ (cd ${.CURDIR} && ${MAKE} $@); \e
+ echo "Back in $$(pwd)"
+.Ed
+.Pp
+Since
+.Nm
+changes the current working directory to
+.Sq Va .OBJDIR
+before executing any targets,
+each child process starts with that as its current working directory.
+.Sh VARIABLE ASSIGNMENTS
+Variables in make behave much like macros in the C preprocessor.
+.Pp
+Variable assignments have the form
+.Sq Ar NAME Ar op Ar value ,
+where:
+.Bl -tag -offset Ds -width Ds
+.It Ar NAME
+is a single-word variable name,
+consisting, by tradition, of all upper-case letters,
+.It Ar op
+is one of the variable assignment operators described below, and
+.It Ar value
+is interpreted according to the variable assignment operator.
+.El
+.Pp
+Whitespace around
+.Ar NAME ,
+.Ar op
+and
+.Ar value
+is discarded.
+.Ss Variable assignment operators
+The five operators that assign values to variables are:
+.Bl -tag -width Ds
+.It Ic \&=
+Assign the value to the variable.
+Any previous value is overwritten.
+.It Ic \&+=
+Append the value to the current value of the variable,
+separating them by a single space.
+.It Ic \&?=
+Assign the value to the variable if it is not already defined.
+.It Ic \&:=
+Expand the value, then assign it to the variable.
+.Pp
+.Em NOTE :
+References to undefined variables are
+.Em not
+expanded.
+This can cause problems when variable modifiers are used.
+.\" See var-op-expand.mk, the section with LATER and INDIRECT.
+.It Ic \&!=
+Expand the value and pass it to the shell for execution,
+then assign the output from the child's standard output to the variable.
+Any newlines in the result are replaced with spaces.
+.El
+.Ss Expansion of variables
+In most contexts where variables are expanded,
+.Ql \&$$
+expands to a single dollar sign.
+In other contexts (most variable modifiers, string literals in conditions),
+.Ql \&\e$
+expands to a single dollar sign.
+.Pp
+References to variables have the form
+.Cm \&${ Ns Ar name Ns Oo Ns Cm \&: Ns Ar modifiers Oc Ns Cm \&}
+or
+.Cm \&$( Ns Ar name Ns Oo Ns Cm \&: Ns Ar modifiers Oc Ns Cm \&) .
+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.
+.Pp
+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.
+.Pp
+If the result of expanding a nested variable expression contains a dollar sign
+.Pq Ql \&$ ,
+the result is subject to further expansion.
+.Pp
+Variable substitution occurs at four distinct times, depending on where
+the variable is being used.
+.Bl -enum
+.It
+Variables in dependency lines are expanded as the line is read.
+.It
+Variables in conditionals are expanded individually,
+but only as far as necessary to determine the result of the conditional.
+.It
+Variables in shell commands are expanded when the shell command is
+executed.
+.It
+.Ic .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:
+.Bd -literal -offset indent
+\&.for i in 1 2 3
+a+= ${i}
+j= ${i}
+b+= ${j}
+\&.endfor
+
+all:
+ @echo ${a}
+ @echo ${b}
+.Ed
+.Pp
+prints:
+.Bd -literal -offset indent
+1 2 3
+3 3 3
+.Ed
+.Pp
+After the loop is executed:
+.Bl -tag -offset indent -width indent
+.It Va a
+contains
+.Ql ${:U1} ${:U2} ${:U3} ,
+which expands to
+.Ql 1 2 3 .
+.It Va j
+contains
+.Ql ${:U3} ,
+which expands to
+.Ql 3 .
+.It Va b
+contains
+.Ql ${j} ${j} ${j} ,
+which expands to
+.Ql ${:U3} ${:U3} ${:U3}
+and further to
+.Ql 3 3 3 .
+.El
+.El
+.Ss Variable classes
+The four different classes of variables (in order of increasing precedence)
+are:
+.Bl -tag -width Ds
+.It Environment variables
+Variables defined as part of
+.Nm Ns 's
+environment.
+.It Global variables
+Variables defined in the makefile or in included makefiles.
+.It Command line variables
+Variables defined as part of the command line.
+.It Local variables
+Variables that are defined specific to a certain target.
+.El
+.Pp
+Local variables can be set on a dependency line, unless
+.Va .MAKE.TARGET_LOCAL_VARIABLES
+is set to
+.Ql false .
+The rest of the line
+(which already has had global variables expanded)
+is the variable value.
+For example:
+.Bd -literal -offset indent
+COMPILER_WRAPPERS= ccache distcc icecc
+
+${OBJS}: .MAKE.META.CMP_FILTER=${COMPILER_WRAPPERS:S,^,N,}
+.Ed
+.Pp
+Only the targets
+.Ql ${OBJS}
+are impacted by that filter (in
+.Dq meta
+mode) and
+simply enabling/disabling any of the compiler wrappers does not render all
+of those targets out-of-date.
+.Pp
+.Em NOTE :
+target-local variable assignments behave differently in that;
+.Bl -tag -width Ds -offset indent
+.It Ic \&+=
+Only appends to a previous local assignment
+for the same target and variable.
+.It Ic \&:=
+Is redundant with respect to global variables,
+which have already been expanded.
+.El
+.Pp
+The built-in local variables are:
+.Bl -tag -width ".Va .ARCHIVE" -offset indent
+.It Va .ALLSRC
+The list of all sources for this target; also known as
+.Sq Va \&>
+or
+.Sq Va \&^ .
+.It Va .ARCHIVE
+The name of the archive file; also known as
+.Sq Va \&! .
+.It Va .IMPSRC
+In suffix-transformation rules, the name/path of the source from which the
+target is to be transformed (the
+.Dq implied
+source); also known as
+.Sq Va \&< .
+It is not defined in explicit rules.
+.It Va .MEMBER
+The name of the archive member; also known as
+.Sq Va % .
+.It Va .OODATE
+The list of sources for this target that were deemed out-of-date; also
+known as
+.Sq Va \&? .
+.It Va .PREFIX
+The name of the target with suffix (if declared in
+.Ic .SUFFIXES )
+removed; also known as
+.Sq Va * .
+.It Va .TARGET
+The name of the target; also known as
+.Sq Va @ .
+For compatibility with other makes this is an alias for
+.Va .ARCHIVE
+in archive member rules.
+.El
+.Pp
+The shorter forms
+.Po
+.Sq Va \&> ,
+.Sq Va \&^ ,
+.Sq Va \&! ,
+.Sq Va \&< ,
+.Sq Va \&% ,
+.Sq Va \&? ,
+.Sq Va \&* ,
+and
+.Sq Va \&@
+.Pc
+are permitted for backward
+compatibility with historical makefiles and legacy POSIX make and are
+not recommended.
+.Pp
+Variants of these variables with the punctuation followed immediately by
+.Ql D
+or
+.Ql F ,
+e.g.\&
+.Ql $(@D) ,
+are legacy forms equivalent to using the
+.Ql :H
+and
+.Ql :T
+modifiers.
+These forms are accepted for compatibility with
+.At V
+makefiles and POSIX but are not recommended.
+.Pp
+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
+.Sq Va .TARGET ,
+.Sq Va .PREFIX ,
+.Sq Va .ARCHIVE ,
+and
+.Sq Va .MEMBER .
+.Ss Additional built-in variables
+In addition,
+.Nm
+sets or knows about the following variables:
+.Bl -tag
+.\" NB: This list is sorted case-insensitive, ignoring punctuation.
+.\" NB: To find all built-in variables in make's source code,
+.\" NB: search for Var_*, Global_*, SetVarObjdir, GetBooleanExpr,
+.\" NB: and the implementation of Var_SetWithFlags.
+.\" NB: Last synced on 2023-01-01.
+.It Va .ALLTARGETS
+The list of all targets encountered in the makefiles.
+If evaluated during makefile parsing,
+lists only those targets encountered thus far.
+.It Va .CURDIR
+A path to the directory where
+.Nm
+was executed.
+Refer to the description of
+.Sq Va PWD
+for more details.
+.It Va .ERROR_CMD
+Is used in error handling, see
+.Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .ERROR_CWD
+Is used in error handling, see
+.Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .ERROR_EXIT
+Is used in error handling, see
+.Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .ERROR_META_FILE
+Is used in error handling in
+.Dq meta
+mode, see
+.Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .ERROR_TARGET
+Is used in error handling, see
+.Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .INCLUDEDFROMDIR
+The directory of the file this makefile was included from.
+.It Va .INCLUDEDFROMFILE
+The filename of the file this makefile was included from.
+.\" .INCLUDES is intentionally undocumented, as it is obsolete.
+.\" .LIBS is intentionally undocumented, as it is obsolete.
+.It Va MACHINE
+The machine hardware name, see
+.Xr uname 1 .
+.It Va MACHINE_ARCH
+The machine processor architecture name, see
+.Xr uname 1 .
+.It Va MAKE
+The name that
+.Nm
+was executed with
+.Pq Va argv[0] .
+.It Va .MAKE
+The same as
+.Va MAKE ,
+for compatibility.
+The preferred variable to use is the environment variable
+.Ev MAKE
+because it is more compatible with other make variants
+and cannot be confused with the special target with the same name.
+.\" '.MAKE.cmd_filtered' is intentionally undocumented,
+.\" as it is an internal implementation detail.
+.It Va .MAKE.DEPENDFILE
+Names the makefile (default
+.Sq Pa .depend )
+from which generated dependencies are read.
+.It Va .MAKE.DIE_QUIETLY
+If set to
+.Ql true ,
+do not print error information at the end.
+.It Va .MAKE.EXPAND_VARIABLES
+A boolean that controls the default behavior of the
+.Fl V
+option.
+If true, variable values printed with
+.Fl V
+are fully expanded; if false, the raw variable contents (which may
+include additional unexpanded variable references) are shown.
+.It Va .MAKE.EXPORTED
+The list of variables exported by
+.Nm .
+.It Va MAKE_VERSION
+This variable indicates the version of
+.Nm .
+It is typically the date of last import from NetBSD.
+It is useful for checking whether certain features are available.
+.It Va MAKEFILE
+The top-level makefile that is currently read,
+as given in the command line.
+.It Va .MAKEFLAGS
+The environment variable
+.Sq Ev MAKEFLAGS
+may contain anything that
+may be specified on
+.Nm Ns 's
+command line.
+Anything specified on
+.Nm Ns 's
+command line is appended to the
+.Va .MAKEFLAGS
+variable, which is then added to the environment for all programs that
+.Nm
+executes.
+.It Va .MAKE.GID
+The numeric group ID of the user running
+.Nm .
+It is read-only.
+.It Va .MAKE.JOB.PREFIX
+If
+.Nm
+is run with
+.Fl j ,
+the output for each target is prefixed with a token
+.Dl --- Ar target Li ---
+the first part of which can be controlled via
+.Va .MAKE.JOB.PREFIX .
+If
+.Va .MAKE.JOB.PREFIX
+is empty, no token is printed.
+For example, setting
+.Va .MAKE.JOB.PREFIX
+to
+.Ql ${.newline}---${.MAKE:T}[${.MAKE.PID}]
+would produce tokens like
+.Dl ---make[1234] Ar target Li ---
+making it easier to track the degree of parallelism being achieved.
+.It Va .MAKE.JOBS
+The argument to the
+.Fl j
+option.
+.It Va .MAKE.JOBS.C
+A read-only boolean that indicates whether the
+.Fl j
+option supports use of
+.Ql C .
+.It Va .MAKE.LEVEL
+The recursion depth of
+.Nm .
+The top-level instance of
+.Nm
+has level 0, and each child make has its parent level plus 1.
+This allows tests like:
+.Li .if ${.MAKE.LEVEL} == 0
+to protect things which should only be evaluated in the top-level instance of
+.Nm .
+.It Va .MAKE.LEVEL.ENV
+The name of the environment variable that stores the level of nested calls to
+.Nm .
+.It Va .MAKE.MAKEFILE_PREFERENCE
+The ordered list of makefile names
+(default
+.Sq Pa makefile ,
+.Sq Pa Makefile )
+that
+.Nm
+looks for.
+.It Va .MAKE.MAKEFILES
+The list of makefiles read by
+.Nm ,
+which is useful for tracking dependencies.
+Each makefile is recorded only once, regardless of the number of times read.
+.It Va .MAKE.META.BAILIWICK
+In
+.Dq meta
+mode, provides a list of prefixes which
+match the directories controlled by
+.Nm .
+If a file that was generated outside of
+.Va .OBJDIR
+but within said bailiwick is missing,
+the current target is considered out-of-date.
+.It Va .MAKE.META.CMP_FILTER
+In
+.Dq meta
+mode, it can (very rarely!) be useful to filter command
+lines before comparison.
+This variable can be set to a set of modifiers that are applied to
+each line of the old and new command that differ, if the filtered
+commands still differ, the target is considered out-of-date.
+.It Va .MAKE.META.CREATED
+In
+.Dq meta
+mode, this variable contains a list of all the meta files
+updated.
+If not empty, it can be used to trigger processing of
+.Va .MAKE.META.FILES .
+.It Va .MAKE.META.FILES
+In
+.Dq meta
+mode, this variable contains a list of all the meta files
+used (updated or not).
+This list can be used to process the meta files to extract dependency
+information.
+.It Va .MAKE.META.IGNORE_FILTER
+Provides a list of variable modifiers to apply to each pathname.
+Ignore if the expansion is an empty string.
+.It Va .MAKE.META.IGNORE_PATHS
+Provides a list of path prefixes that should be ignored;
+because the contents are expected to change over time.
+The default list includes:
+.Sq Pa /dev /etc /proc /tmp /var/run /var/tmp
+.It Va .MAKE.META.IGNORE_PATTERNS
+Provides a list of patterns to match against pathnames.
+Ignore any that match.
+.It Va .MAKE.META.PREFIX
+Defines the message printed for each meta file updated in
+.Dq meta verbose
+mode.
+The default value is:
+.Dl Building ${.TARGET:H:tA}/${.TARGET:T}
+.It Va .MAKE.MODE
+Processed after reading all makefiles.
+Affects the mode that
+.Nm
+runs in.
+It can contain these keywords:
+.Bl -tag -width indent
+.It Cm compat
+Like
+.Fl B ,
+puts
+.Nm
+into
+.Dq compat
+mode.
+.It Cm meta
+Puts
+.Nm
+into
+.Dq meta
+mode, where meta files are created for each target
+to capture the commands run, the output generated, and if
+.Xr filemon 4
+is available, the system calls which are of interest to
+.Nm .
+The captured output can be useful when diagnosing errors.
+.Pp
+.Nm
+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.
+.Pp
+First,
+the commands to be executed,
+will be compared to those captured previously,
+if any differ,
+the target is out-of-date.
+.Pp
+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
+.Va .MAKE.META.CMP_FILTER
+and
+.Ic .NOMETA_CMP ,
+allow limiting or disabling that comparison on a per target basis.
+A reference to the variable
+.Va .OODATE
+can be leveraged to block comparison of certain commands.
+For example:
+.Ql ${.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
+.Ql ${.OODATE:MNOMETA_CMP}
+is useful.
+.Pp
+If necessary,
+.Nm
+will then use the information captured by
+.Xr 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.
+.Pp
+Such deep inspection can easily lead to cases where a target is
+.Em always
+considered out-of-date, which is why
+.Va .MAKE.META.IGNORE_FILTER ,
+.Va .MAKE.META.IGNORE_PATHS
+and
+.Va .MAKE.META.IGNORE_PATTERNS ,
+are provided to limit that inspection when necessary.
+.It Cm curdirOk= Ns Ar bf
+By default,
+.Nm
+does not create
+.Pa .meta
+files in
+.Sq Va .CURDIR .
+This can be overridden by setting
+.Ar bf
+to a value which represents true.
+.It Cm missing-meta= Ns Ar bf
+If
+.Ar bf
+is true, a missing
+.Pa .meta
+file makes the target out-of-date.
+.It Cm missing-filemon= Ns Ar bf
+If
+.Ar bf
+is true, missing filemon data makes the target out-of-date.
+.It Cm nofilemon
+Do not use
+.Xr filemon 4 .
+.It Cm env
+For debugging, it can be useful to include the environment
+in the
+.Pa .meta
+file.
+.It Cm verbose
+If in
+.Dq meta
+mode, print a clue about the target being built.
+This is useful if the build is otherwise running silently.
+The message printed is the expanded value of
+.Va .MAKE.META.PREFIX .
+.It Cm ignore-cmd
+Some makefiles have commands which are simply not stable.
+This keyword causes them to be ignored for
+determining whether a target is out of date in
+.Dq meta
+mode.
+See also
+.Ic .NOMETA_CMP .
+.It Cm silent= Ns Ar bf
+If
+.Ar bf
+is true, when a .meta file is created, mark the target
+.Ic .SILENT .
+.It Cm randomize-targets
+In both compat and parallel mode, do not make the targets in the usual order,
+but instead randomize their order.
+This mode can be used to detect undeclared dependencies between files.
+.El
+.It Va MAKEOBJDIR
+Used to create files in a separate directory, see
+.Va .OBJDIR .
+.It Va MAKE_OBJDIR_CHECK_WRITABLE
+When true,
+.Nm
+will check that
+.Va .OBJDIR
+is writable, and issue a warning if not.
+.It Va MAKE_DEBUG_OBJDIR_CHECK_WRITABLE
+When true and
+.Nm
+is warning about an unwritable
+.Va .OBJDIR ,
+report the variables listed in
+.Va MAKE_PRINT_VAR_ON_ERROR
+to help debug.
+.It Va MAKEOBJDIRPREFIX
+Used to create files in a separate directory, see
+.Va .OBJDIR .
+It should be an absolute path.
+.It Va .MAKE.OS
+The name of the operating system, see
+.Xr uname 1 .
+It is read-only.
+.It Va .MAKEOVERRIDES
+This variable is used to record the names of variables assigned to
+on the command line, so that they may be exported as part of
+.Sq Ev MAKEFLAGS .
+This behavior can be disabled by assigning an empty value to
+.Sq Va .MAKEOVERRIDES
+within a makefile.
+Extra variables can be exported from a makefile
+by appending their names to
+.Sq Va .MAKEOVERRIDES .
+.Sq Ev MAKEFLAGS
+is re-exported whenever
+.Sq Va .MAKEOVERRIDES
+is modified.
+.It Va .MAKE.PATH_FILEMON
+If
+.Nm
+was built with
+.Xr filemon 4
+support, this is set to the path of the device node.
+This allows makefiles to test for this support.
+.It Va .MAKE.PID
+The process ID of
+.Nm .
+It is read-only.
+.It Va .MAKE.PPID
+The parent process ID of
+.Nm .
+It is read-only.
+.It Va MAKE_PRINT_VAR_ON_ERROR
+When
+.Nm
+stops due to an error, it sets
+.Sq Va .ERROR_TARGET
+to the name of the target that failed,
+.Sq Va .ERROR_EXIT
+to the exit status of the failed target,
+.Sq Va .ERROR_CMD
+to the commands of the failed target,
+and in
+.Dq meta
+mode, it also sets
+.Sq Va .ERROR_CWD
+to the
+.Xr getcwd 3 ,
+and
+.Sq Va .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
+.Sq Va .CURDIR
+as well as the value of any variables named in
+.Sq Va MAKE_PRINT_VAR_ON_ERROR .
+.It Va .MAKE.SAVE_DOLLARS
+If true,
+.Ql $$
+are preserved when doing
+.Ql :=
+assignments.
+The default is false, for backwards compatibility.
+Set to true for compatability with other makes.
+If set to false,
+.Ql $$
+becomes
+.Ql $
+per normal evaluation rules.
+.It Va .MAKE.TARGET_LOCAL_VARIABLES
+If set to
+.Ql false ,
+apparent variable assignments in dependency lines are
+treated as normal sources.
+.It Va .MAKE.UID
+The numeric ID of the user running
+.Nm .
+It is read-only.
+.\" 'MAKE_VERSION' is intentionally undocumented
+.\" since it is only defined in the bmake distribution,
+.\" but not in NetBSD's native make.
+.\" '.meta.%d.lcwd' is intentionally undocumented
+.\" since it is an internal implementation detail.
+.\" '.meta.%d.ldir' is intentionally undocumented
+.\" since it is an internal implementation detail.
+.\" 'MFLAGS' is intentionally undocumented
+.\" since it is obsolete.
+.It Va .newline
+This variable is simply assigned a newline character as its value.
+It is read-only.
+This allows expansions using the
+.Cm \&:@
+modifier to put a newline between
+iterations of the loop rather than a space.
+For example, in case of an error,
+.Nm
+prints the variable names and their values using:
+.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+.It Va .OBJDIR
+A path to the directory where the targets are built.
+Its value is determined by trying to
+.Xr chdir 2
+to the following directories in order and using the first match:
+.Bl -enum
+.It
+.Cm ${MAKEOBJDIRPREFIX} Ns Cm ${.CURDIR}
+.Pp
+(Only if
+.Sq Ev MAKEOBJDIRPREFIX
+is set in the environment or on the command line.)
+.It
+.Cm ${MAKEOBJDIR}
+.Pp
+(Only if
+.Sq Ev MAKEOBJDIR
+is set in the environment or on the command line.)
+.It
+.Cm ${.CURDIR} Ns Pa /obj. Ns Cm ${MACHINE}
+.It
+.Cm ${.CURDIR} Ns Pa /obj
+.It
+.Pa /usr/obj/ Ns Cm ${.CURDIR}
+.It
+.Cm ${.CURDIR}
+.El
+.Pp
+Variable expansion is performed on the value before it is used,
+so expressions such as
+.Cm ${.CURDIR:S,^/usr/src,/var/obj,}
+may be used.
+This is especially useful with
+.Sq Ev MAKEOBJDIR .
+.Pp
+.Sq Va .OBJDIR
+may be modified in the makefile via the special target
+.Sq Ic .OBJDIR .
+In all cases,
+.Nm
+changes to the specified directory if it exists, and sets
+.Sq Va .OBJDIR
+and
+.Sq Va PWD
+to that directory before executing any targets.
+.Pp
+Except in the case of an explicit
+.Sq Ic .OBJDIR
+target,
+.Nm
+checks that the specified directory is writable and ignores it if not.
+This check can be skipped by setting the environment variable
+.Sq Ev MAKE_OBJDIR_CHECK_WRITABLE
+to
+.Dq no .
+.It Va .PARSEDIR
+The directory name of the current makefile being parsed.
+.It Va .PARSEFILE
+The basename of the current makefile being parsed.
+This variable and
+.Sq Va .PARSEDIR
+are both set only while the makefiles are being parsed.
+To retain their current values,
+assign them to a variable using assignment with expansion
+.Sq Cm \&:= .
+.It Va .PATH
+The space-separated list of directories that
+.Nm
+searches for files.
+To update this search list, use the special target
+.Sq Ic .PATH
+rather than modifying the variable directly.
+.It Va %POSIX
+Is set in POSIX mode, see the special
+.Ql Va .POSIX
+target.
+.\" XXX: There is no make variable named 'PWD',
+.\" XXX: make only reads and writes the environment variable 'PWD'.
+.It Va PWD
+Alternate path to the current directory.
+.Nm
+normally sets
+.Sq Va .CURDIR
+to the canonical path given by
+.Xr getcwd 3 .
+However, if the environment variable
+.Sq Ev PWD
+is set and gives a path to the current directory,
+.Nm
+sets
+.Sq Va .CURDIR
+to the value of
+.Sq Ev PWD
+instead.
+This behavior is disabled if
+.Sq Ev MAKEOBJDIRPREFIX
+is set or
+.Sq Ev MAKEOBJDIR
+contains a variable transform.
+.Sq Va PWD
+is set to the value of
+.Sq Va .OBJDIR
+for all programs which
+.Nm
+executes.
+.It Va .SHELL
+The pathname of the shell used to run target scripts.
+It is read-only.
+.It Va .SUFFIXES
+The list of known suffixes.
+It is read-only.
+.It Va .SYSPATH
+The space-separated list of directories that
+.Nm
+searches for makefiles, referred to as the system include path.
+To update this search list, use the special target
+.Sq Ic .SYSPATH
+rather than modifying the variable which is read-only.
+.It Va .TARGETS
+The list of targets explicitly specified on the command line, if any.
+.It Va VPATH
+The colon-separated
+.Pq Dq \&:
+list of directories that
+.Nm
+searches for files.
+This variable is supported for compatibility with old make programs only, use
+.Sq Va .PATH
+instead.
+.El
+.Ss Variable modifiers
+The general format of a variable expansion is:
+.Pp
+.Sm off
+.D1 Ic \&${ Ar variable\| Oo Ic \&: Ar modifier\| Oo Ic \&: No ... Oc Oc Ic \&}
+.Sm on
+.Pp
+Each modifier begins with a colon.
+To escape a colon, precede it with a backslash
+.Ql \e .
+.Pp
+A list of indirect modifiers can be specified via a variable, as follows:
+.Pp
+.Bd -literal -offset indent
+.Ar modifier_variable\^ Li \&= Ar modifier Ns Oo Ic \&: Ns No ... Oc
+
+.Sm off
+.Ic \&${ Ar variable Ic \&:${ Ar modifier_variable Ic \&} Oo Ic \&: No ... Oc Ic \&}
+.Sm on
+.Ed
+.Pp
+In this case, the first modifier in the
+.Ar modifier_variable
+does not start with a colon,
+since that colon already occurs in the referencing variable.
+If any of the modifiers in the
+.Ar modifier_variable
+contains a dollar sign
+.Pq Ql $ ,
+these must be doubled to avoid early expansion.
+.Pp
+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.
+.Pp
+The supported modifiers are:
+.Bl -tag -width EEE
+.It Cm \&:E
+Replaces each word with its suffix.
+.It Cm \&:H
+Replaces each word with its dirname.
+.It Cm \&:M\| Ns Ar pattern
+Selects only those words that match
+.Ar pattern .
+The standard shell wildcard characters
+.Pf ( Ql * ,
+.Ql \&? ,
+and
+.Ql \&[] )
+may
+be used.
+The wildcard characters may be escaped with a backslash
+.Pq Ql \e .
+As a consequence of the way values are split into words, matched,
+and then joined, the construct
+.Ql ${VAR:M*}
+removes all leading and trailing whitespace
+and normalizes the inter-word spacing to a single space.
+.It Cm \&:N\| Ns Ar pattern
+This is the opposite of
+.Sq Cm \&:M ,
+selecting all words which do
+.Em not
+match
+.Ar pattern .
+.It Cm \&:O
+Orders the words lexicographically.
+.It Cm \&:On
+Orders the words numerically.
+A number followed by one of
+.Ql k ,
+.Ql M
+or
+.Ql G
+is multiplied by the appropriate factor, which is 1024 for
+.Ql k ,
+1048576 for
+.Ql M ,
+or 1073741824 for
+.Ql G .
+Both upper- and lower-case letters are accepted.
+.It Cm \&:Or
+Orders the words in reverse lexicographical order.
+.It Cm \&:Orn
+Orders the words in reverse numerical order.
+.It Cm \&:Ox
+Shuffles the words.
+The results are different each time you are referring to the
+modified variable; use the assignment with expansion
+.Sq Cm \&:=
+to prevent such behavior.
+For example,
+.Bd -literal -offset indent
+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}"
+.Ed
+may produce output similar to:
+.Bd -literal -offset indent
+quattro due tre uno
+tre due quattro uno
+due uno quattro tre
+due uno quattro tre
+.Ed
+.It Cm \&:Q
+Quotes every shell meta-character in the value, so that it can be passed
+safely to the shell.
+.It Cm \&:q
+Quotes every shell meta-character in the value, and also doubles
+.Sq $
+characters so that it can be passed
+safely through recursive invocations of
+.Nm .
+This is equivalent to
+.Sq Cm \&:S/\e\&$/&&/g:Q .
+.It Cm \&:R
+Replaces each word with everything but its suffix.
+.It Cm \&:range Ns Oo Cm = Ns Ar count Oc
+The value is an integer sequence representing the words of the original
+value, or the supplied
+.Ar count .
+.It Cm \&:gmtime Ns Oo Cm = Ns Ar timestamp Oc
+The value is interpreted as a format string for
+.Xr strftime 3 ,
+using
+.Xr gmtime 3 ,
+producing the formatted timestamp.
+Note: the
+.Ql %s
+format should only be used with
+.Sq Cm \&:localtime .
+If a
+.Ar timestamp
+value is not provided or is 0, the current time is used.
+.It Cm \&:hash
+Computes a 32-bit hash of the value and encodes it as 8 hex digits.
+.It Cm \&:localtime Ns Oo Cm = Ns Ar timestamp Oc
+The value is interpreted as a format string for
+.Xr strftime 3 ,
+using
+.Xr localtime 3 ,
+producing the formatted timestamp.
+If a
+.Ar timestamp
+value is not provided or is 0, the current time is used.
+.It Cm \&:mtime Ns Oo Cm = Ns Ar timestamp Oc
+Call
+.Xr stat 2
+with each word as pathname;
+use
+.Ql st_mtime
+as the new value.
+If
+.Xr stat 2
+fails; use
+.Ar timestamp
+or current time.
+If
+.Ar timestamp
+is set to
+.Ql error ,
+then
+.Xr stat 2
+failure will cause an error.
+.It Cm \&:tA
+Attempts to convert the value to an absolute path using
+.Xr realpath 3 .
+If that fails, the value is unchanged.
+.It Cm \&:tl
+Converts the value to lower-case letters.
+.It Cm \&:ts Ns Ar c
+When joining the words after a modifier that treats the value as words,
+the words are normally separated by a space.
+This modifier changes the separator to the character
+.Ar c .
+If
+.Ar c
+is omitted, no separator is used.
+The common escapes (including octal numeric codes) work as expected.
+.It Cm \&:tt
+Converts the first character of each word to upper-case,
+and the rest to lower-case letters.
+.It Cm \&:tu
+Converts the value to upper-case letters.
+.It Cm \&:tW
+Causes subsequent modifiers to treat the value as a single word
+(possibly containing embedded whitespace).
+See also
+.Sq Cm \&:[*] .
+.It Cm \&:tw
+Causes the value to be treated as a list of words.
+See also
+.Sq Cm \&:[@] .
+.Sm off
+.It Cm \&:S\| No \&/ Oo Cm \&^ Oc Ar old_string\| No Oo Cm \&$ Oc \&/ Ar new_string\| No \&/ Op Cm 1gW
+.Sm on
+Modifies the first occurrence of
+.Ar old_string
+in each word of the value, replacing it with
+.Ar new_string .
+.Pp
+If
+.Ar old_string
+is preceded by a caret
+.Pq Ql ^ ,
+.Ar old_string
+is anchored at the beginning of each word.
+If
+.Ar old_string
+is followed by a dollar sign
+.Pq Ql \&$ ,
+it is anchored at the end of each word.
+Inside
+.Ar new_string ,
+an ampersand
+.Pq Ql &
+is replaced by
+.Ar old_string .
+Both
+.Ar old_string
+and
+.Ar new_string
+may contain nested expressions.
+.Pp
+Further options:
+.Bl -tag
+.It Cm 1
+Only the word of the first occurrence is affected.
+.It Cm g
+All occurrences in each affected word are replaced.
+.It Cm W
+The expression value is treated as a single word.
+.El
+.Pp
+Any character may be used as the delimiter for the parts of the modifier
+string.
+The anchoring, ampersand, dollar and delimiter characters
+can be escaped with a backslash
+.Pq Ql \e .
+.Sm off
+.It Cm \&:C\| No \&/ Ar pattern\| No \&/ Ar replacement\| No \&/ Op Cm 1gW
+.Sm on
+Modifies the first occurrence of the extended regular expression
+.Ar pattern
+(see
+.Xr regex 3 )
+in each word of the value, replacing it with
+an
+.Xr ed 1 Ns \-style
+.Ar replacement .
+.Pp
+Both
+.Ar pattern
+and
+.Ar replacement
+may contain nested expressions.
+.Pp
+Further options:
+.Bl -tag
+.It Cm 1
+Only the word of the first occurrence is affected.
+.It Cm g
+All occurrences in each affected word are replaced.
+.It Cm W
+The expression value is treated as a single word.
+.El
+.Pp
+Any character may be used as the delimiter for the parts of the modifier
+string.
+The anchoring, ampersand, dollar and delimiter characters
+can be escaped with a backslash
+.Pq Ql \e .
+.It Cm \&:T
+Replaces each word with its last path component (basename).
+.It Cm \&:u
+Removes adjacent duplicate words (like
+.Xr uniq 1 ) .
+.Sm off
+.It Cm \&:\&?\| Ar true_string\| Cm \&: Ar false_string
+.Sm on
+If the variable name (not its value), when parsed as a
+.Cm .if
+conditional expression, evaluates to true, return as its value the
+.Ar true_string ,
+otherwise return the
+.Ar false_string .
+Since the variable name is used as the expression,
+\&:\&? must be the first modifier after the variable name
+.No itself Ns \^\(em\^ Ns
+which, of course, usually contains variable expansions.
+A common error is trying to use expressions like
+.Dl ${NUMBERS:M42:?match:no}
+which actually tests defined(NUMBERS).
+To determine if any words match
+.Dq 42 ,
+you need to use something like:
+.Dl ${"${NUMBERS:M42}" != \&"\&":?match:no} .
+.It Cm :\| Ns Ar old_string\| Ns Cm = Ns Ar new_string
+This is the
+.At V
+style substitution.
+It can only be the last modifier specified,
+as a
+.Ql \&:
+in either
+.Ar old_string
+or
+.Ar new_string
+is treated as a regular character, not as the end of the modifier.
+.Pp
+If
+.Ar old_string
+does not contain the pattern matching character
+.Ql % ,
+and the word ends with
+.Ar old_string
+or equals it,
+that suffix is replaced with
+.Ar new_string .
+.Pp
+Otherwise, the first
+.Ql %
+in
+.Ar 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
+.Ar new_string ,
+and the first occurrence of
+.Ql %
+in
+.Ar new_string
+(if any) is replaced with the substring matched by the
+.Ql % .
+.Pp
+Both
+.Ar old_string
+and
+.Ar new_string
+may contain nested expressions.
+To prevent a dollar sign from starting a nested expression,
+escape it with a backslash.
+.Sm off
+.It Cm \&:@ Ar varname\| Cm @ Ar string\| Cm @
+.Sm on
+This is the loop expansion mechanism from the OSF Development
+Environment (ODE) make.
+Unlike
+.Cm \&.for
+loops, expansion occurs at the time of reference.
+For each word in the value, assign the word to the variable named
+.Ar varname
+and evaluate
+.Ar string .
+The ODE convention is that
+.Ar varname
+should start and end with a period, for example:
+.Dl ${LINKS:@.LINK.@${LN} ${TARGET} ${.LINK.}@}
+.Pp
+However, a single-letter variable is often more readable:
+.Dl ${MAKE_PRINT_VAR_ON_ERROR:@v@$v='${$v}'${.newline}@}
+.It Cm \&:_ Ns Oo Cm = Ns Ar var Oc
+Saves the current variable value in
+.Ql $_
+or the named
+.Ar var
+for later reference.
+Example usage:
+.Bd -literal -offset indent
+M_cmpv.units = 1 1000 1000000
+M_cmpv = S,., ,g:_:range:@i@+ $${_:[-$$i]} \&\\
+\\* $${M_cmpv.units:[$$i]}@:S,^,expr 0 ,1:sh
+
+.Dv .if ${VERSION:${M_cmpv}} < ${3.1.12:L:${M_cmpv}}
+
+.Ed
+Here
+.Ql $_
+is used to save the result of the
+.Ql :S
+modifier which is later referenced using the index values from
+.Ql :range .
+.It Cm \&:U\| Ns Ar newval
+If the variable is undefined,
+the optional
+.Ar newval
+(which may be empty) is the value.
+If the variable is defined, the existing value is returned.
+This is another ODE make feature.
+It is handy for setting per-target CFLAGS for instance:
+.Dl ${_${.TARGET:T}_CFLAGS:U${DEF_CFLAGS}}
+If a value is only required if the variable is undefined, use:
+.Dl ${VAR:D:Unewval}
+.It Cm \&:D\| Ns Ar newval
+If the variable is defined,
+.Ar newval
+(which may be empty) is the value.
+.It Cm \&:L
+The name of the variable is the value.
+.It Cm \&:P
+The path of the node which has the same name as the variable is the value.
+If no such node exists or its path is null, the name of the variable is used.
+In order for this modifier to work, the name (node) must at least have
+appeared on the right-hand side of a dependency.
+.Sm off
+.It Cm \&:\&! Ar cmd\| Cm \&!
+.Sm on
+The output of running
+.Ar cmd
+is the value.
+.It Cm \&:sh
+The value is run as a command, and the output becomes the new value.
+.It Cm \&:sh1
+The value is run as a command, for the first reference only, and
+the output is cached for subsequent references.
+This modifier is useful when the result is not expected to change.
+.It Cm \&::= Ns Ar str
+The variable is assigned the value
+.Ar str
+after substitution.
+This modifier and its variations are useful in obscure situations
+such as wanting to set a variable
+at a point where a target's shell commands are being parsed.
+These assignment modifiers always expand to nothing.
+.Pp
+The
+.Sq Cm \&::
+helps avoid false matches with the
+.At V
+style
+.Ql \&:=
+modifier and since substitution always occurs, the
+.Ql \&::=
+form is vaguely appropriate.
+.It Cm \&::?= Ns Ar str
+As for
+.Cm \&::=
+but only if the variable does not already have a value.
+.It Cm \&::+= Ns Ar str
+Append
+.Ar str
+to the variable.
+.It Cm \&::!= Ns Ar cmd
+Assign the output of
+.Ar cmd
+to the variable.
+.It Cm \&:\&[ Ns Ar range Ns Cm \&]
+Selects one or more words from the value,
+or performs other operations related to the way in which the
+value is split into words.
+.Pp
+An empty value, or a value that consists entirely of white-space,
+is treated as a single word.
+For the purposes of the
+.Sq Cm \&:[]
+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).
+.Pp
+The
+.Ar range
+is subjected to variable expansion, and the expanded result is
+then interpreted as follows:
+.Bl -tag -width index
+.\" :[n]
+.It Ar index
+Selects a single word from the value.
+.\" :[start..end]
+.It Ar start Ns Cm \&.. Ns Ar end
+Selects all words from
+.Ar start
+to
+.Ar end ,
+inclusive.
+For example,
+.Sq Cm \&:[2..-1]
+selects all words from the second word to the last word.
+If
+.Ar start
+is greater than
+.Ar end ,
+the words are output in reverse order.
+For example,
+.Sq Cm \&:[-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
+.Sq Cm \&:Or
+instead of
+.Sq Cm \&:O:[-1..1] .
+.\" :[*]
+.It Cm \&*
+Causes subsequent modifiers to treat the value as a single word
+(possibly containing embedded whitespace).
+Analogous to the effect of
+.Li \&$*
+in Bourne shell.
+.\" :[0]
+.It 0
+Means the same as
+.Sq Cm \&:[*] .
+.\" :[*]
+.It Cm \&@
+Causes subsequent modifiers to treat the value as a sequence of words
+delimited by whitespace.
+Analogous to the effect of
+.Li \&$@
+in Bourne shell.
+.\" :[#]
+.It Cm \&#
+Returns the number of words in the value.
+.El \" :[range]
+.El
+.Sh DIRECTIVES
+.Nm
+offers directives for including makefiles, conditionals and for loops.
+All these directives are identified by a line beginning with a single dot
+.Pq Ql \&.
+character, followed by the keyword of the directive, such as
+.Cm include
+or
+.Cm if .
+.Ss File inclusion
+Files are included with either
+.Cm \&.include \&< Ns Ar file Ns Cm \&>
+or
+.Cm \&.include \&\*q Ns Ar file Ns Cm \&\*q .
+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
+.Fl I
+option are searched before the system makefile directory.
+.Pp
+For compatibility with other make variants,
+.Sq Cm include Ar file No ...
+(without leading dot)
+is also accepted.
+.Pp
+If the include statement is written as
+.Cm .-include
+or as
+.Cm .sinclude ,
+errors locating and/or opening include files are ignored.
+.Pp
+If the include statement is written as
+.Cm .dinclude ,
+not only are errors locating and/or opening include files ignored,
+but stale dependencies within the included file are ignored just like in
+.Va .MAKE.DEPENDFILE .
+.Ss Exporting variables
+The directives for exporting and unexporting variables are:
+.Bl -tag -width Ds
+.It Ic .export Ar variable No ...
+Export the specified global variable.
+.Pp
+For compatibility with other make programs,
+.Cm export Ar variable\| Ns Cm \&= Ns Ar value
+(without leading dot) is also accepted.
+.Pp
+Appending a variable name to
+.Va .MAKE.EXPORTED
+is equivalent to exporting a variable.
+.It Ic .export-all
+Export all globals except for internal variables (those that start with
+.Ql \&. ) .
+This is not affected by the
+.Fl X
+flag, so should be used with caution.
+.It Ic .export-env Ar variable No ...
+The same as
+.Ql .export ,
+except that the variable is not appended to
+.Va .MAKE.EXPORTED .
+This allows exporting a value to the environment which is different from that
+used by
+.Nm
+internally.
+.It Ic .export-literal Ar variable No ...
+The same as
+.Ql .export-env ,
+except that variables in the value are not expanded.
+.It Ic .unexport Ar variable No ...
+The opposite of
+.Ql .export .
+The specified global
+.Ar variable
+is removed from
+.Va .MAKE.EXPORTED .
+If no variable list is provided, all globals are unexported,
+and
+.Va .MAKE.EXPORTED
+deleted.
+.It Ic .unexport-env
+Unexport all globals previously exported and
+clear the environment inherited from the parent.
+This operation causes a memory leak of the original environment,
+so should be used sparingly.
+Testing for
+.Va .MAKE.LEVEL
+being 0 would make sense.
+Also note that any variables which originated in the parent environment
+should be explicitly preserved if desired.
+For example:
+.Bd -literal -offset indent
+.Li .if ${.MAKE.LEVEL} == 0
+PATH := ${PATH}
+.Li .unexport-env
+.Li .export PATH
+.Li .endif
+.Pp
+.Ed
+Would result in an environment containing only
+.Sq Ev PATH ,
+which is the minimal useful environment.
+.\" TODO: Check the below sentence, environment variables don't start with '.'.
+Actually
+.Sq Va .MAKE.LEVEL
+is also pushed into the new environment.
+.El
+.Ss Messages
+The directives for printing messages to the output are:
+.Bl -tag -width Ds
+.It Ic .info Ar message
+The message is printed along with the name of the makefile and line number.
+.It Ic .warning Ar message
+The message prefixed by
+.Sq Li warning:
+is printed along with the name of the makefile and line number.
+.It Ic .error Ar message
+The message is printed along with the name of the makefile and line number,
+.Nm
+exits immediately.
+.El
+.Ss Conditionals
+The directives for conditionals are:
+.ds maybenot Oo Ic \&! Oc Ns
+.Bl -tag
+.It Ic .if \*[maybenot] Ar expression Op Ar operator expression No ...
+Test the value of an expression.
+.It Ic .ifdef \*[maybenot] Ar variable Op Ar operator variable No ...
+Test whether a variable is defined.
+.It Ic .ifndef \*[maybenot] Ar variable Op Ar operator variable No ...
+Test whether a variable is not defined.
+.It Ic .ifmake \*[maybenot] Ar target Op Ar operator target No ...
+Test the target being requested.
+.It Ic .ifnmake \*[maybenot] Ar target Op Ar operator target No ...
+Test the target being requested.
+.It Ic .else
+Reverse the sense of the last conditional.
+.It Ic .elif \*[maybenot] Ar expression Op Ar operator expression No ...
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .if .
+.It Ic .elifdef \*[maybenot] Ar variable Op Ar operator variable No ...
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .ifdef .
+.It Ic .elifndef \*[maybenot] Ar variable Op Ar operator variable No ...
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .ifndef .
+.It Ic .elifmake \*[maybenot] Ar target Op Ar operator target No ...
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .ifmake .
+.It Ic .elifnmake \*[maybenot] Ar target Op Ar operator target No ...
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .ifnmake .
+.It Ic .endif
+End the body of the conditional.
+.El
+.Pp
+The
+.Ar operator
+may be any one of the following:
+.Bl -tag
+.It Ic \&|\&|
+Logical OR.
+.It Ic \&&&
+Logical AND; of higher precedence than
+.Sq Ic \&|\&| .
+.El
+.Pp
+.Nm
+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
+.Sq Ic \&!
+may be used to logically negate an expression, typically a function call.
+It is of higher precedence than
+.Sq Ic \&&& .
+.Pp
+The value of
+.Ar expression
+may be any of the following function call expressions:
+.Bl -tag
+.Sm off
+.It Ic defined Li \&( Ar varname Li \&)
+.Sm on
+Evaluates to true if the variable
+.Ar varname
+has been defined.
+.Sm off
+.It Ic make Li \&( Ar target Li \&)
+.Sm on
+Evaluates to true if the target was specified as part of
+.Nm Ns 's
+command line or was declared the default target (either implicitly or
+explicitly, see
+.Va .MAIN )
+before the line containing the conditional.
+.Sm off
+.It Ic empty Li \&( Ar varname Oo Li : Ar modifiers Oc Li \&)
+.Sm on
+Evaluates to true if the expansion of the variable,
+after applying the modifiers, results in an empty string.
+.Sm off
+.It Ic exists Li \&( Ar pathname Li \&)
+.Sm on
+Evaluates to true if the given pathname exists.
+If relative, the pathname is searched for on the system search path (see
+.Va .PATH ) .
+.Sm off
+.It Ic target Li \&( Ar target Li \&)
+.Sm on
+Evaluates to true if the target has been defined.
+.Sm off
+.It Ic commands Li \&( Ar target Li \&)
+.Sm on
+Evaluates to true if the target has been defined
+and has commands associated with it.
+.El
+.Pp
+.Ar 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
+.Li 0x ,
+otherwise it is interpreted as a decimal floating-point number;
+octal numbers are not supported.
+.Pp
+All comparisons may use the operators
+.Sq Ic \&==
+and
+.Sq Ic \&!= .
+Numeric comparisons may also use the operators
+.Sq Ic \&< ,
+.Sq Ic \&<= ,
+.Sq Ic \&>
+and
+.Sq Ic \&>= .
+.Pp
+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.
+.Pp
+When
+.Nm
+is evaluating one of these conditional expressions, and it encounters
+a (whitespace-separated) word it doesn't recognize, either the
+.Dq make
+or
+.Dq defined
+function is applied to it, depending on the form of the conditional.
+If the form is
+.Sq Ic .ifdef ,
+.Sq Ic .ifndef
+or
+.Sq Ic .if ,
+the
+.Dq defined
+function is applied.
+Similarly, if the form is
+.Sq Ic .ifmake
+or
+.Sq Ic .ifnmake ,
+the
+.Dq make
+function is applied.
+.Pp
+If the conditional evaluates to true,
+parsing of the makefile continues as before.
+If it evaluates to false, the following lines until the corresponding
+.Sq Ic .elif
+variant,
+.Sq Ic .else
+or
+.Sq Ic .endif
+are skipped.
+.Ss For loops
+For loops are typically used to apply a set of rules to a list of files.
+The syntax of a for loop is:
+.Pp
+.Bl -tag -compact -width Ds
+.It Ic \&.for Ar variable Oo Ar variable No ... Oc Ic in Ar expression
+.It Aq Ar make-lines
+.It Ic \&.endfor
+.El
+.Pp
+The
+.Ar expression
+is expanded and then split into words.
+On each iteration of the loop, one word is taken and assigned to each
+.Ar variable ,
+in order, and these
+.Ar variables
+are substituted into the
+.Ar 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.
+.Pp
+If
+.Sq Ic .break
+is encountered within a
+.Cm \&.for
+loop, it causes early termination of the loop, otherwise a parse error.
+.\" TODO: Describe limitations with defined/empty.
+.Ss Other directives
+.Bl -tag -width Ds
+.It Ic .undef Ar variable No ...
+Un-define the specified global variables.
+Only global variables can be un-defined.
+.El
+.Sh COMMENTS
+Comments begin with a hash
+.Pq Ql \&#
+character, anywhere but in a shell
+command line, and continue to the end of an unescaped new line.
+.Sh SPECIAL SOURCES (ATTRIBUTES)
+.Bl -tag -width .IGNOREx
+.It Ic .EXEC
+Target is never out of date, but always execute commands anyway.
+.It Ic .IGNORE
+Ignore any errors from the commands associated with this target, exactly
+as if they all were preceded by a dash
+.Pq Ql \- .
+.\" .It Ic .INVISIBLE
+.\" XXX
+.\" .It Ic .JOIN
+.\" XXX
+.It Ic .MADE
+Mark all sources of this target as being up to date.
+.It Ic .MAKE
+Execute the commands associated with this target even if the
+.Fl n
+or
+.Fl t
+options were specified.
+Normally used to mark recursive
+.Nm Ns s .
+.It Ic .META
+Create a meta file for the target, even if it is flagged as
+.Ic .PHONY ,
+.Ic .MAKE ,
+or
+.Ic .SPECIAL .
+Usage in conjunction with
+.Ic .MAKE
+is the most likely case.
+In
+.Dq meta
+mode, the target is out-of-date if the meta file is missing.
+.It Ic .NOMETA
+Do not create a meta file for the target.
+Meta files are also not created for
+.Ic .PHONY ,
+.Ic .MAKE ,
+or
+.Ic .SPECIAL
+targets.
+.It Ic .NOMETA_CMP
+Ignore differences in commands when deciding if target is out of date.
+This is useful if the command contains a value which always changes.
+If the number of commands change, though,
+the target is still considered out of date.
+The same effect applies to any command line that uses the variable
+.Va .OODATE ,
+which can be used for that purpose even when not otherwise needed or desired:
+.Bd -literal -offset indent
+
+skip-compare-for-some:
+ @echo this is compared
+ @echo this is not ${.OODATE:M.NOMETA_CMP}
+ @echo this is also compared
+
+.Ed
+The
+.Cm \&:M
+pattern suppresses any expansion of the unwanted variable.
+.It Ic .NOPATH
+Do not search for the target in the directories specified by
+.Va .PATH .
+.It Ic .NOTMAIN
+Normally
+.Nm
+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.
+.It Ic .OPTIONAL
+If a target is marked with this attribute and
+.Nm
+can't figure out how to create it, it ignores this fact and assumes
+the file isn't needed or already exists.
+.It Ic .PHONY
+The target does not correspond to an actual file;
+it is always considered to be out of date,
+and is not created with the
+.Fl t
+option.
+Suffix-transformation rules are not applied to
+.Ic .PHONY
+targets.
+.It Ic .PRECIOUS
+When
+.Nm
+is interrupted, it normally removes any partially made targets.
+This source prevents the target from being removed.
+.It Ic .RECURSIVE
+Synonym for
+.Ic .MAKE .
+.It Ic .SILENT
+Do not echo any of the commands associated with this target, exactly
+as if they all were preceded by an at sign
+.Pq Ql @ .
+.It Ic .USE
+Turn the target into
+.Nm Ns '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
+.Ic .USE )
+of the
+source.
+If the target already has commands, the
+.Ic .USE
+target's commands are appended
+to them.
+.It Ic .USEBEFORE
+Like
+.Ic .USE ,
+but instead of appending, prepend the
+.Ic .USEBEFORE
+target commands to the target.
+.It Ic .WAIT
+If
+.Ic .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:
+.Bd -literal
+x: a .WAIT b
+ echo x
+a:
+ echo a
+b: b1
+ echo b
+b1:
+ echo b1
+
+.Ed
+the output is always
+.Ql a ,
+.Ql b1 ,
+.Ql b ,
+.Ql x .
+.Pp
+The ordering imposed by
+.Ic .WAIT
+is only relevant for parallel makes.
+.El
+.Sh SPECIAL TARGETS
+Special targets may not be included with other targets, i.e. they must be
+the only target specified.
+.Bl -tag -width .BEGINx
+.It Ic .BEGIN
+Any command lines attached to this target are executed before anything
+else is done.
+.It Ic .DEFAULT
+This is sort of a
+.Ic .USE
+rule for any target (that was used only as a source) that
+.Nm
+can't figure out any other way to create.
+Only the shell script is used.
+The
+.Va .IMPSRC
+variable of a target that inherits
+.Ic .DEFAULT Ns 's
+commands is set to the target's own name.
+.It Ic .DELETE_ON_ERROR
+If this target is present in the makefile, it globally causes make to
+delete targets whose commands fail.
+(By default, only targets whose commands are interrupted during
+execution are deleted.
+This is the historical behavior.)
+This setting can be used to help prevent half-finished or malformed
+targets from being left around and corrupting future rebuilds.
+.It Ic .END
+Any command lines attached to this target are executed after everything
+else is done successfully.
+.It Ic .ERROR
+Any command lines attached to this target are executed when another target fails.
+See
+.Va MAKE_PRINT_VAR_ON_ERROR
+for the variables that will be set.
+.It Ic .IGNORE
+Mark each of the sources with the
+.Ic .IGNORE
+attribute.
+If no sources are specified, this is the equivalent of specifying the
+.Fl i
+option.
+.It Ic .INTERRUPT
+If
+.Nm
+is interrupted, the commands for this target are executed.
+.It Ic .MAIN
+If no target is specified when
+.Nm
+is invoked, this target is built.
+.It Ic .MAKEFLAGS
+This target provides a way to specify flags for
+.Nm
+at the time when the makefiles are read.
+The flags are as if typed to the shell, though the
+.Fl f
+option has
+no effect.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .NOTPARALLEL
+.\" The named targets are executed in non parallel mode.
+.\" If no targets are
+.\" specified, all targets are executed in non parallel mode.
+.It Ic .NOPATH
+Apply the
+.Ic .NOPATH
+attribute to any specified sources.
+.It Ic .NOTPARALLEL
+Disable parallel mode.
+.It Ic .NO_PARALLEL
+Synonym for
+.Ic .NOTPARALLEL ,
+for compatibility with other pmake variants.
+.It Ic .NOREADONLY
+clear the read-only attribute from the global variables specified as sources.
+.It Ic .OBJDIR
+The source is a new value for
+.Sq Va .OBJDIR .
+If it exists,
+.Nm
+changes the current working directory to it and updates the value of
+.Sq Va .OBJDIR .
+.It Ic .ORDER
+In parallel mode, the named targets are made in sequence.
+This ordering does not add targets to the list of targets to be made.
+.Pp
+Since the dependents of a target do not get built until the target itself
+could be built, unless
+.Ql a
+is built by another part of the dependency graph,
+the following is a dependency loop:
+.Bd -literal
+\&.ORDER: b a
+b: a
+.Ed
+.Pp
+.\" XXX: NOT YET!!!!
+.\" .It Ic .PARALLEL
+.\" The named targets are executed in parallel mode.
+.\" If no targets are
+.\" specified, all targets are executed in parallel mode.
+.It Ic .PATH
+The sources are directories which are to be searched for files not
+found in the current directory.
+If no sources are specified,
+any previously specified directories are removed from the search path.
+If the source is the special
+.Ic .DOTLAST
+target, the current working directory is searched last.
+.It Ic .PATH. Ns Ar suffix
+Like
+.Ic .PATH
+but applies only to files with a particular suffix.
+The suffix must have been previously declared with
+.Ic .SUFFIXES .
+.It Ic .PHONY
+Apply the
+.Ic .PHONY
+attribute to any specified sources.
+.It Ic .POSIX
+If this is the first non-comment line in the main makefile,
+the variable
+.Va %POSIX
+is set to the value
+.Ql 1003.2
+and the makefile
+.Ql <posix.mk>
+is included if it exists,
+to provide POSIX-compatible default rules.
+If
+.Nm
+is run with the
+.Fl r
+flag, only
+.Ql 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.
+.It Ic .PRECIOUS
+Apply the
+.Ic .PRECIOUS
+attribute to any specified sources.
+If no sources are specified, the
+.Ic .PRECIOUS
+attribute is applied to every target in the file.
+.It Ic .READONLY
+set the read-only attribute on the global variables specified as sources.
+.It Ic .SHELL
+Sets the shell that
+.Nm
+uses to execute commands.
+The sources are a set of
+.Ar field\| Ns Cm \&= Ns Ar value
+pairs.
+.Bl -tag -width ".Li hasErrCtls"
+.It Li name
+This is the minimal specification, used to select one of the built-in
+shell specs;
+.Li sh ,
+.Li ksh ,
+and
+.Li csh .
+.It Li path
+Specifies the absolute path to the shell.
+.It Li hasErrCtl
+Indicates whether the shell supports exit on error.
+.It Li check
+The command to turn on error checking.
+.It Li ignore
+The command to disable error checking.
+.It Li echo
+The command to turn on echoing of commands executed.
+.It Li quiet
+The command to turn off echoing of commands executed.
+.It Li filter
+The output to filter after issuing the
+.Li quiet
+command.
+It is typically identical to
+.Li quiet .
+.It Li errFlag
+The flag to pass the shell to enable error checking.
+.It Li echoFlag
+The flag to pass the shell to enable command echoing.
+.It Li newline
+The string literal to pass the shell that results in a single newline
+character when used outside of any quoting characters.
+.El
+Example:
+.Bd -literal
+\&.SHELL: name=ksh path=/bin/ksh hasErrCtl=true \e
+ check="set \-e" ignore="set +e" \e
+ echo="set \-v" quiet="set +v" filter="set +v" \e
+ echoFlag=v errFlag=e newline="'\en'"
+.Ed
+.It Ic .SILENT
+Apply the
+.Ic .SILENT
+attribute to any specified sources.
+If no sources are specified, the
+.Ic .SILENT
+attribute is applied to every
+command in the file.
+.It Ic .STALE
+This target gets run when a dependency file contains stale entries, having
+.Va .ALLSRC
+set to the name of that dependency file.
+.It Ic .SUFFIXES
+Each source specifies a suffix to
+.Nm .
+If no sources are specified, any previously specified suffixes are deleted.
+It allows the creation of suffix-transformation rules.
+.Pp
+Example:
+.Bd -literal
+\&.SUFFIXES: .c .o
+\&.c.o:
+ cc \-o ${.TARGET} \-c ${.IMPSRC}
+.Ed
+.It Ic .SYSPATH
+The sources are directories which are to be added to the system
+include path which
+.Nm
+searches for makefiles.
+If no sources are specified,
+any previously specified directories are removed from the system
+include path.
+.El
+.Sh ENVIRONMENT
+.Nm
+uses the following environment variables, if they exist:
+.Ev MACHINE ,
+.Ev MACHINE_ARCH ,
+.Ev MAKE ,
+.Ev MAKEFLAGS ,
+.Ev MAKEOBJDIR ,
+.Ev MAKEOBJDIRPREFIX ,
+.Ev MAKESYSPATH ,
+.Ev MAKE_STACK_TRACE ,
+.Ev PWD ,
+and
+.Ev TMPDIR .
+.Pp
+.Ev MAKEOBJDIRPREFIX
+and
+.Ev MAKEOBJDIR
+should be set in the environment or on the command line to
+.Nm
+and not as makefile variables;
+see the description of
+.Sq Va .OBJDIR
+for more details.
+It is possible to set these via makefile variables but unless done
+very early and the
+.Sq Ic .OBJDIR
+target is used to reset
+.Sq Va .OBJDIR ,
+there may be unexpected side effects.
+.Pp
+If the
+.Ev MAKE_STACK_TRACE
+environment variable is set to
+.Dq yes ,
+any stack traces include the call chain of the parent processes.
+.\" .Sh EXIT STATUS
+.\" .Sh ENVIRONMENT
+.Sh FILES
+.Bl -tag -width /usr/share/mk -compact
+.It .depend
+list of dependencies
+.It makefile
+first default makefile if no makefile is specified on the command line
+.It Makefile
+second default makefile if no makefile is specified on the command line
+.It sys.mk
+system makefile
+.It /usr/share/mk
+system makefile directory
+.El
+.\" .Sh EXAMPLES
+.Sh DIAGNOSTICS
+.Bl -tag
+.It Dv Invalid internal option \(dq-J\(dq in \(dq Ns Ar directory Ns Dv \(dq
+The internal
+.Fl J
+option coordinates the main
+.Nm
+process with the sub-make processes to limit
+the number of jobs that run in parallel.
+The option is passed to all child processes via the
+.Ev MAKEFLAGS
+environment variable.
+To become valid,
+this option requires that the target running the sub-make is marked with the
+.Dv .MAKE
+special source,
+or that one of the target's commands directly contains the word
+.Dq make
+or one of the expressions
+.Dq ${MAKE} ,
+.Dq ${.MAKE} ,
+.Dq $(MAKE) ,
+.Dq $(.MAKE) .
+If that's not the case,
+make issues the above warning and falls back to compat mode.
+.Pp
+To see the chain of sub-makes that leads to the invalid option, set the
+.Ev MAKE_STACK_TRACE
+environment variable to
+.Dq yes .
+.Pp
+To run the sub-make in parallel mode, even in dry-run mode (see the
+.Fl n
+option), add the
+.Dv .MAKE
+pseudo source to the target.
+This is appropriate when the sub-make runs the same target in a subdirectory.
+.Pp
+To run the sub-make in parallel mode but not in dry-mode,
+add a
+.Dq ${:D make}
+marker to one of the target's commands.
+This marker expands to an empty string
+and thus does not affect the executed commands.
+.\" The marker can even be added before any of the "@+-" modifiers,
+.\" so no need to mention this explicitly.
+.Pp
+To run the sub-make in compat mode, add the
+.Fl B
+option to its invocation.
+This is appropriate when the sub-make is only used to print a variable's
+value using the
+.Fl v
+or
+.Fl V
+options.
+.Pp
+To make the sub-make independent from the parent make, unset the
+.Ev MAKEFLAGS
+environment variable in the target's commands.
+.El
+.Sh COMPATIBILITY
+The basic make syntax is compatible between different make variants;
+however the special variables, variable modifiers and conditionals are not.
+.Ss Older versions
+An incomplete list of changes in older versions of
+.Nm :
+.Pp
+The way that .for loop variables are substituted changed after
+.Nx 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.
+.Pp
+The way that parallel makes are scheduled changed in
+.Nx 4.0
+so that .ORDER and .WAIT apply recursively to the dependent nodes.
+The algorithms used may change again in the future.
+.Ss Other make dialects
+Other make dialects (GNU make, SVR4 make, POSIX make, etc.) do not
+support most of the features of
+.Nm
+as described in this manual.
+Most notably:
+.Bl -bullet -offset indent
+.It
+The
+.Ic .WAIT
+and
+.Ic .ORDER
+declarations and most functionality pertaining to parallelization.
+(GNU make supports parallelization but lacks the features needed to
+control it effectively.)
+.It
+Directives, including for loops and conditionals and most of the
+forms of include files.
+(GNU make has its own incompatible and less powerful syntax for
+conditionals.)
+.\" The "less powerful" above means that GNU make does not have the
+.\" make(target), target(target) and commands(target) functions.
+.It
+All built-in variables that begin with a dot.
+.It
+Most of the special sources and targets that begin with a dot,
+with the notable exception of
+.Ic .PHONY ,
+.Ic .PRECIOUS ,
+and
+.Ic .SUFFIXES .
+.It
+Variable modifiers, except for the
+.Ql :old=new
+string substitution, which does not portably support globbing with
+.Ql %
+and historically only works on declared suffixes.
+.It
+The
+.Ic $>
+variable even in its short form; most makes support this functionality
+but its name varies.
+.El
+.Pp
+Some features are somewhat more portable, such as assignment with
+.Ic += ,
+.Ic ?= ,
+and
+.Ic != .
+The
+.Va .PATH
+functionality is based on an older feature
+.Ic 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.
+.Pp
+The
+.Ic $@
+and
+.Ic $<
+variables are more or less universally portable, as is the
+.Ic $(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.
+.Sh SEE ALSO
+.Xr mkdep 1
+.\" .Sh STANDARDS
+.Sh HISTORY
+.Nm
+is derived from NetBSD
+.Xr make 1 .
+It uses autoconf to facilitate portability to other platforms.
+.Pp
+A
+make
+command appeared in
+.At v7 .
+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
+.Dq customs .
+.Pp
+Historically the target/dependency
+.Ic FRC
+has been used to FoRCe rebuilding (since the target/dependency
+does not exist ... unless someone creates an
+.Pa FRC
+file).
+.\" .Sh AUTHORS
+.\" .Sh CAVEATS
+.Sh BUGS
+The
+.Nm
+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
+.Nm
+just counts {} and () in order to find the end of a variable expansion.
+.Pp
+There is no way of escaping a space character in a filename.
+.Pp
+In jobs mode, when a target fails;
+.Nm
+will put an error token into the job token pool.
+This will cause all other instances of
+.Nm
+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
+.Ql *** Error code 6
+.\" .Sh SECURITY CONSIDERATIONS