summaryrefslogtreecommitdiff
path: root/static/openbsd/man1/make.1
diff options
context:
space:
mode:
authorJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-25 19:54:44 -0400
committerJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-25 19:54:44 -0400
commita9157ce950dfe2fc30795d43b9d79b9d1bffc48b (patch)
tree9df484304b560466d145e662c1c254ff0e9ae0ba /static/openbsd/man1/make.1
parent160aa82b2d39c46ad33723d7d909cb4972efbb03 (diff)
docs: Added All OpenBSD Manuals
Diffstat (limited to 'static/openbsd/man1/make.1')
-rw-r--r--static/openbsd/man1/make.11736
1 files changed, 1736 insertions, 0 deletions
diff --git a/static/openbsd/man1/make.1 b/static/openbsd/man1/make.1
new file mode 100644
index 00000000..74424f22
--- /dev/null
+++ b/static/openbsd/man1/make.1
@@ -0,0 +1,1736 @@
+.\" $OpenBSD: make.1,v 1.142 2025/11/27 09:08:49 tb Exp $
+.\" $NetBSD: make.1,v 1.18 1997/03/10 21:19:53 christos 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 $Mdocdate: November 27 2025 $
+.Dt MAKE 1
+.Os
+.Sh NAME
+.Nm make
+.Nd maintain program dependencies
+.Sh SYNOPSIS
+.Nm make
+.Op Fl BeiknpqrSst
+.Op Fl C Ar directory
+.Op Fl D Ar variable
+.Op Fl d Ar flags
+.Op Fl f Ar mk
+.Op Fl I Ar directory
+.Op Fl j Ar max_jobs
+.Op Fl m Ar directory
+.Op Fl V Ar variable
+.Op Ar NAME Ns = Ns Ar value ...
+.Bk -words
+.Op Ar target ...
+.Ek
+.Sh DESCRIPTION
+.Nm
+is a program designed to simplify the maintenance of other programs.
+Its input is a
+.Em makefile :
+a list of specifications (target rules) describing build
+relationships between programs and other files.
+By default, the file
+.Pa makefile
+is used;
+if no such file is found, it tries
+.Pa Makefile .
+If neither of these exist,
+.Nm
+can still rely on a set of built-in system rules.
+.Pp
+If the file
+.Sq Pa .depend
+exists, it will also be read after the main
+.Ar makefile
+(see
+.Xr mkdep 1 ) .
+.Pp
+The handling of
+.Sq Pa .depend
+is a
+.Bx
+extension.
+.Pp
+If a list of
+.Ar target ...
+is specified,
+.Nm
+will build those targets.
+Otherwise a default target will be built:
+either a target explicitly marked with
+.Ic .MAIN
+or the first target encountered in the
+.Em makefile .
+.Pp
+Standard options are as follows:
+.Bl -tag -width Ds
+.It Fl e
+Environment variables override macro assignments within
+makefiles.
+.It Fl f Ar mk
+Read file
+.Ar mk
+instead of the default makefile.
+If
+.Ar mk
+is
+.Ql \- ,
+standard input is used.
+Multiple makefiles may be specified, and are read in the order specified.
+.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 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 n
+Display the commands that would have been executed, but do not actually
+execute them.
+.It Fl p
+Print a dump of the target rules and variables on stdout.
+Do not build anything.
+.It Fl q
+Do not execute any commands, but exit with status 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,
+.Pa <sys.mk> .
+.It Fl S
+Stop processing when an error is encountered.
+This is the default behavior.
+This is needed to negate the
+.Fl k
+option during recursive builds.
+.It Fl s
+Do not echo commands as they are executed.
+Equivalent to specifying
+.Sq Ic @
+before each command line in the makefile.
+.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, a bit like
+.Xr touch 1 .
+.It Ar NAME Ns = Ns Ar value
+Set the value of the variable
+.Ar NAME
+to
+.Ar value .
+.El
+.Pp
+Extended options are as follows:
+.Bl -tag -width Ds
+.It Fl B
+Try to be backwards compatible by executing the commands to make
+the prerequisites in a target rule in sequence.
+This is the default, in the absence of
+.Fl j Ar max_jobs .
+.It Fl C Ar directory
+Enter
+.Ar directory
+before doing anything.
+.It Fl D Ar variable
+Define
+.Ar variable
+to be 1.
+.It Fl d Ar flags
+Turn on debugging, and specify which portions of
+.Nm
+are to print debugging information.
+.Ar flags
+is one or more of the following:
+.Bl -tag -width Ds
+.It Ar A
+Print all possible debugging information;
+equivalent to specifying all of the debugging flags.
+.It Ar a
+Print debugging information about archive searching and caching.
+.It Ar c
+Print debugging information about conditional evaluation.
+.It Ar d
+Print debugging information about directory searching and caching.
+.It Ar D
+Print warning messages about multiply defined command lists.
+.It Ar e
+Print debugging information about expensive command heuristics.
+.It Ar f
+Print debugging information about the expansion of for loops.
+.It Ar "g1"
+Print the input graph before making anything.
+.It Ar "g2"
+Print the input graph after making everything, or before exiting
+on error.
+.It Ar h
+Print information about jobs being held back because of sibling/target
+groups races.
+.It Ar j
+Print debugging information about forking processes to run commands.
+.It Ar k
+Print debugging information about manually killing processes.
+.It Ar l
+Print commands in Makefile targets regardless of whether or not they are
+prefixed by @.
+Also known as loud behavior.
+.It Ar m
+Print debugging information about making targets, including modification
+dates.
+.It Ar n
+Print debugging information about target names equivalence computations.
+.It Ar p
+Help finding concurrency issues for parallel make by adding some
+randomization.
+If
+.Va RANDOM_ORDER
+is defined,
+targets will be shuffled before being built.
+If
+.Va RANDOM_DELAY
+is defined,
+.Nm
+will wait between 0 and ${RANDOM_DELAY} seconds before starting a command.
+A given random seed can be forced by setting
+.Va RANDOM_SEED ,
+but this does not guarantee reproducibility.
+.It Ar q
+.Sq quick death
+option: after a fatal error, instead of waiting for other jobs to die,
+kill them right away.
+.It Ar s
+Print debugging information about inference (suffix) transformation rules.
+.It Ar t
+Print debugging information about target list maintenance.
+.It Ar T
+Print debugging information about target group determination.
+.It Ar v
+Print debugging information about variable assignment.
+.El
+.It Fl I Ar directory
+Specify a directory in which to search for makefiles and
+for "..."-style inclusions.
+Multiple directories can be added to form a search path.
+Furthermore, the system include path (see the
+.Fl m
+option) will be used after this search path.
+.It Fl j Ar max_jobs
+Specify the maximum number of jobs that
+.Nm
+may have running at any one time.
+See the discussion about recursive invocations under
+.Sx BUGS .
+.It Fl m Ar directory
+Specify a directory in which to search for system include files:
+.Pa sys.mk
+and <...>-style inclusions.
+Multiple directories can be added to form the system search path.
+Using
+.Fl m
+will override the default system include directory
+.Pa /usr/share/mk .
+.It Fl V Ar variable
+Print
+.Nm make Ns 's
+idea of the value of
+.Ar variable .
+Do not build any targets.
+Multiple instances of this option may be specified;
+the variables will be printed one per line,
+with a blank line for each null or undefined variable.
+.El
+.Pp
+There are seven different types of lines in a makefile: dependency
+lines, shell commands, variable assignments, include statements,
+conditional directives, for loops, and comments.
+Of these, include statements, conditional directives and for loops are
+extensions.
+.Pp
+A complete target rule is composed of a dependency line,
+followed by a list of shell commands.
+.Pp
+In general, 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 DEPENDENCY LINES
+Dependency lines consist of one or more targets, an operator, and zero
+or more prerequisites:
+.Bd -ragged -offset indent
+.Ar target ... : Ns Op Ar prerequisite ...
+.Ed
+.Pp
+This creates a relationship where the targets
+.Dq depend
+on the prerequisites and are usually built from them.
+The exact relationship between targets and prerequisites is determined
+by the operator that separates them.
+.Pp
+It is an error to use different dependency operators for the same target.
+.Pp
+The operators are as follows:
+.Bl -tag -width flag
+.It Ic \&:
+A target is considered out of date if any of its prerequisites has
+been modified more recently than the target (that is, its modification time
+is less than that of any of its prerequisites).
+Thus, targets with no prerequisites are always out of date.
+.Pp
+.Nm
+will then execute the list of shell commands associated with that target.
+.Pp
+Additional prerequisites may be specified over additional dependency lines:
+.Nm
+will consider all prerequisites for determining out-of-date status.
+The target is removed if
+.Nm
+is interrupted.
+.It Ic \&!
+.Nm
+first examines all prerequisites and re-creates them as necessary.
+.Pp
+It will then always execute the list of shell commands associated with
+that target (as if the target always was out of date).
+.Pp
+Like
+.Ic \&: ,
+additional prerequisites may be specified over additional dependency lines,
+and the target is still removed if
+.Nm
+is interrupted.
+.It Ic \&::
+Each dependency line for a target is considered independently.
+A target is considered out of date for this target rule if any of its
+prerequisites in this dependency has been modified more recently than
+the target.
+.Pp
+.Nm
+will then execute the list of shell commands associated with that target.
+Target rules that specify no prerequisites are always executed.
+.Pp
+The target will not be removed if
+.Nm
+is interrupted.
+.El
+.Pp
+The
+.Ic \&:
+operator is the only standard operator.
+The
+.Ic \&::
+operator is a fairly standard extension,
+popularized by
+.Sy imake .
+The
+.Ic !\&
+operator is a
+.Bx
+extension.
+.Pp
+As an extension, targets and prerequisites may contain the shell wildcard
+expressions
+.Ql \&? ,
+.Ql * ,
+.Ql []
+and
+.Ql {} .
+The expressions
+.Ql \&? ,
+.Ql *
+and
+.Ql []
+may only be used as part of the final
+component of the target or prerequisite, and must be used to describe existing
+files.
+The expression
+.Ql {}
+need not necessarily be used to describe existing files.
+Expansion is in directory order, not alphabetically as done in the shell.
+.Pp
+For maximum portability, target names should only consist of periods,
+underscores, digits and alphabetic characters.
+.Pp
+The use of several targets can be a shorthand for duplicate rules.
+Specifically,
+.Bd -literal -offset indent
+target1 target2: reqa reqa
+ cmd1
+ cmd2
+.Ed
+.Pp
+may be replaced with
+.Bd -literal -offset indent
+target1: reqa reqa
+ cmd1
+ cmd2
+target2: reqa reqa
+ cmd1
+ cmd2
+.Ed
+.Pp
+in general.
+But
+.Nm
+is aware of parallel issues, and will not build those targets concurrently,
+if not appropriate.
+.Sh SHELL COMMANDS
+Each target may have associated with it a series of shell commands, normally
+used to build the target.
+While several dependency lines may name the same target, only one of
+these dependency lines should be followed by shell commands, and thus
+define a complete target rule (unless the
+.Sq Ic ::
+operator is used).
+Each of the shell commands in the target rule
+.Em must
+be preceded by a tab.
+.Pp
+If a command line begins with a combination of the characters,
+.Sq Ic @ ,
+.Sq Ic \-
+and/or
+.Sq Ic + ,
+the command is treated specially:
+.Bl -tag -width `@'
+.It Sq Ic @
+causes the command not to be echoed before it is executed.
+.It Sq Ic \-
+causes any non-zero exit status of the command line to be ignored.
+.It Sq Ic +
+causes the command to be executed even if
+.Fl n
+has been specified.
+(This can be useful to debug recursive Makefiles.)
+.El
+.Pp
+Commands are executed using
+.Pa /bin/sh
+in
+.Qq set -e
+mode, unless
+.Sq Ic \-
+is specified.
+.Pp
+As an optimization,
+.Nm
+may execute very simple commands without going through an extra shell
+process, as long as this does not change observable behavior.
+.Sh INFERENCE RULES
+.Nm
+also maintains a list of valid suffixes through the use of the
+.Ic .SUFFIXES
+special target.
+.Pp
+These suffixes can be used to write generic transformation rules called
+inference rules.
+.Pp
+If a target has the form
+.Sq \&.s1.s2 ,
+where .s1 and .s2 are currently valid suffixes, then it defines a
+transformation from *.s1 to *.s2 (double suffix inference).
+If a target has the form
+.Sq \&.s1 ,
+where .s1 is a currently valid suffix, then it defines a
+transformation from *.s1 to * (single suffix inference).
+.Pp
+A complete inference rule is a dependency line with such a target, the
+normal dependency operator, no prerequisites and a list of shell commands.
+.Pp
+When
+.Nm
+requires a target for which it has no complete target rule, it will try
+to apply a single active inference rule to create the target.
+.Pp
+For instance, with the following Makefile, describing a C program compiled
+from sources a.c and b.c, with header file a.h:
+.Bd -literal -offset indent
+\&.SUFFIXES: .c .o
+\&.c.o:
+ ${CC} ${CFLAGS} -c $<
+
+prog: a.o b.o
+ ${CC} ${CFLAGS} -o $@ a.o b.o
+
+a.o b.o: a.h
+
+b.o: b.c
+ ${CC} -DFOO ${CFLAGS} -o $@ $<
+.Ed
+.Pp
+Consider b.o:
+there is a complete target rule re-creating it from b.c, so
+it will be compiled using ${CC} -DFOO.
+.Pp
+Consider a.o:
+there is no explicit target rule, so
+.Nm
+will consider valid transforms.
+Fortunately, there is an inference rule that can create a.o from a.c,
+so it will be compiled using ${CC}.
+.Pp
+Note that extra prerequisites are still taken into account, so both a.o
+and b.o depend on a.h for re-creation.
+.Pp
+Valid suffixes accumulate over
+.Ic .SUFFIXES
+lines.
+An empty
+.Ic .SUFFIXES
+can be used to reset the currently valid list of suffixes,
+but inference rules already read are still known by
+.Nm ,
+and they are marked as inactive.
+Redefining the corresponding suffix (or suffixes) will reactivate the rule.
+.Pp
+In case of duplicate inference rules with the same suffix combination,
+the new rule overrides the old one.
+.Pp
+For maximal portability, suffixes should start with a dot.
+.Sh VARIABLE ASSIGNMENTS
+Variables in
+.Nm
+are much like variables in the shell and, by tradition,
+consist of all upper-case letters.
+They are also called
+.Sq macros
+in various texts.
+For portability, only periods, underscores, digits and letters should be
+used for variable names.
+The following operators can be used to assign values to variables:
+.Bl -tag -width Ds
+.It Ic \&=
+Assign the value to the variable.
+Any previous value is overridden.
+.It Ic \&:=
+Assign with expansion, i.e., expand the value before assigning it
+to the variable (extension).
+.It Ic \&+=
+Append the value to the current value of the variable (extension).
+.It Ic \&?=
+Assign the value to the variable if it is not already defined
+.Po
+.Bx
+extension
+.Pc .
+Normally, expansion is not done until the variable is referenced.
+.It Ic \&!=
+Perform variable expansion and pass the result to the shell for
+execution on the spot, assigning the result to the variable.
+Any newlines in the result are also replaced with spaces
+.Po
+.Bx
+extension
+.Pc .
+.It Ic \&!!=
+Perform variable expansion on the spot and pass the result to the shell
+for execution only when the value is needed, assigning the result to
+the variable.
+.Pp
+This is almost identical to
+.Ic \&!=
+except that a shell is only run when the variable value is needed.
+Any newlines in the result are also replaced with spaces
+.Po
+.Ox
+extension
+.Pc .
+.El
+.Pp
+Any whitespace before the assigned
+.Ar value
+is removed; if the value is being appended, a single space is inserted
+between the previous contents of the variable and the appended value.
+.Pp
+Several extended assignment operators may be combined together.
+For instance,
+.Bd -literal -offset indent
+A ?!= cmd
+.Ed
+.Pp
+will only run
+.Qq cmd
+and put its output into
+.Va A
+if
+.Va A
+is not yet defined.
+.Pp
+Combinations that do not make sense, such as
+.Bd -literal -offset indent
+A +!!= cmd
+.Ed
+.Pp
+will not work.
+.Pp
+Variables are expanded by surrounding the variable name with either
+curly braces
+.Pq Ql {}
+or parentheses
+.Pq Ql ()
+and preceding it with
+a dollar sign
+.Pq Ql \&$ .
+If the variable name contains only a single letter, the surrounding
+braces or parentheses are not required.
+This shorter form is not recommended.
+.Pp
+Variable substitution occurs at distinct times, depending on the type of line.
+Variables in dependency lines, conditional directives and include statements
+are expanded as the line is read.
+Variables in shell commands are expanded when the shell command is
+executed.
+.Pp
+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 make 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.
+Standard local variables are as follows:
+.Bl -tag -width ".ARCHIVE"
+.It Va @
+The name of the target.
+.It Va \&%
+The name of the archive member (only valid for library rules).
+.It Va \&!
+The name of the archive file (only valid for library rules).
+.It Va \&?
+The list of prerequisites for this target that were deemed out of date.
+.It Va \&<
+The name of the prerequisite from which this target is to be built, if a valid
+inference rule (suffix rule) is in scope.
+.It Va *
+The file prefix of the file, containing only the file portion,
+no suffix or preceding directory components.
+.El
+.Pp
+Those variables
+.Po
+and
+.Va \&>
+.Pc
+may be suffixed with a
+.Sq D
+or a
+.Sq F ,
+to yield the filename or directory part of the corresponding variables, e.g.,
+.Sq ${ Ns Va @F Ns }
+is equivalent
+to
+.Sq ${@:T}
+and
+.Sq ${ Ns Va @D Ns }
+is equivalent to
+.Sq ${@:H} .
+.Pp
+For maximum compatibility,
+.Sq Va \&<
+should only be used for actual inference rules.
+It is also set for normal target rules when there is an inference rule
+that matches the current target and prerequisite in scope.
+That is, in
+.Bd -literal -offset indent
+\&.SUFFIXES: .c .o
+file.o: file.c
+ cmd1 $<
+
+\&.c.o:
+ cmd2
+.Ed
+.Pp
+building
+.Pa file.o
+will execute
+.Qq cmd1 file.c .
+.Pp
+As an extension,
+.Nm
+supports the following local variables:
+.Bl -tag -width ".ARCHIVE"
+.It Va \&>
+The list of all prerequisites for this target.
+.It Va .ALLSRC
+Synonym for
+.Sq Va \&> .
+.It Va .ARCHIVE
+Synonym for
+.Sq Va \&! .
+.It Va .IMPSRC
+Synonym for
+.Sq Va \&< .
+.It Va .MEMBER
+Synonym for
+.Sq Va \&% .
+.It Va .OODATE
+Synonym for
+.Sq Va \&? .
+.It Va .PREFIX
+Synonym for
+.Sq Va * .
+.It Va .TARGET
+Synonym for
+.Sq Va @ .
+.El
+.Pp
+These variables may be used on the dependency half of dependency
+lines, when they make sense.
+.El
+.Pp
+In addition,
+.Nm
+sets or knows about the following internal variables, or environment
+variables:
+.Bl -tag -width MAKEFLAGS
+.It Va \&$
+A single dollar sign
+.Ql \&$ ,
+i.e.,
+.Ql \&$$
+expands to a single dollar
+sign.
+.It Va .MAKE
+The name that
+.Nm
+was executed with
+.Pq Va argv Ns Op 0 .
+.It Va .CURDIR
+A path to the directory where
+.Nm
+was executed.
+.It Va .OBJDIR
+Path to the directory where targets are built.
+At startup,
+.Nm
+searches for an alternate directory to place target files.
+.Nm
+tries to
+.Xr chdir 2
+into
+.Ev MAKEOBJDIR
+(or
+.Pa obj
+if
+.Ev MAKEOBJDIR
+is not defined),
+and sets
+.Va .OBJDIR
+accordingly.
+Should that fail,
+.Va .OBJDIR
+is set to
+.Va .CURDIR .
+.It Va MAKEFILE_LIST
+The list of files read by
+.Nm .
+.It Va .MAKEFLAGS
+The environment variable
+.Ev MAKEFLAGS
+may contain anything that
+may be specified on
+.Nm make Ns 's
+command line.
+Its contents are stored in
+.Nm make Ns 's
+.Va .MAKEFLAGS
+variable.
+Anything specified on
+.Nm make Ns 's
+command line is appended to the
+.Va .MAKEFLAGS
+variable which is then
+entered into the environment as
+.Ev MAKEFLAGS
+for all programs which
+.Nm
+executes.
+.It Va MFLAGS
+A shorter synonym for
+.Va .MAKEFLAGS .
+.It Ev 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
+.Ev PWD
+is set and gives a path to the current directory, then
+.Nm
+sets
+.Sq Va .CURDIR
+to the value of
+.Ev PWD
+instead.
+.Ev PWD
+is always set to the value of
+.Sq Va .OBJDIR
+for all programs which
+.Nm
+executes.
+.It Va .TARGETS
+List of targets
+.Nm
+is currently building.
+.It Va MACHINE
+Name of the machine architecture
+.Nm
+is running on, obtained from the
+.Ev MACHINE
+environment variable, or through
+.Xr uname 3
+if not defined.
+.It Va MACHINE_ARCH
+Name of the machine architecture
+.Nm
+was compiled for, obtained from the
+.Ev MACHINE_ARCH
+environment variable, or defined at compilation time.
+.It Va MACHINE_CPU
+Name of the machine processor
+.Nm
+was compiled for, obtained from the
+.Ev MACHINE_CPU
+environment variable, or defined at compilation time.
+On processors where only one endianness is possible, the value of this
+variable is always the same as
+.Ev MACHINE_ARCH .
+.It Va MAKEFILE
+Possibly the file name of the last makefile that has been read.
+It should not be used; see the
+.Sx BUGS
+section below.
+.It Va .VARIABLES
+List of all the names of global variables that have been set.
+.El
+.Pp
+Variable expansion may be modified to select or modify each word of the
+variable (where
+.Dq word
+is a whitespace delimited sequence of characters).
+The general format of a variable expansion is as follows:
+.Pp
+.Dl {variable[:modifier[:...]]}
+.Pp
+Each modifier begins with a colon and one of the following
+special characters.
+The colon may be escaped with a backslash
+.Pq Ql \e .
+.Bl -tag -width Ds
+.It Cm :E
+Replaces each word in the variable with its suffix.
+.It Cm :H
+Replaces each word in the variable with everything but the last component.
+.It Cm :L
+Replaces each word in the variable with its lower case equivalent.
+.It Cm :U
+Replaces each word in the variable with its upper case equivalent.
+.It Cm :M Ns Ar pattern
+Select only those words that match the rest of the modifier.
+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 .
+.It Cm :N Ns Ar pattern
+This is identical to
+.Cm :M ,
+but selects all words which do not match
+the rest of the modifier.
+.It Cm :Q
+Quotes every shell meta-character in the variable, so that it can be passed
+safely through recursive invocations of
+.Nm make .
+.It Cm :QL
+Quote list: quotes every shell meta-character in the variable, except
+whitespace, so that it can be passed to a shell's
+.Sq for
+loops.
+.It Cm :R
+Replaces each word in the variable with everything but its suffix.
+.Sm off
+.It Cm :S No \&/ Ar old_string Xo
+.No \&/ Ar new_string
+.No \&/ Op Cm 1g
+.Xc
+.Sm on
+Modify the first occurrence of
+.Ar old_string
+in the variable's value, replacing it with
+.Ar new_string .
+If a
+.Ql g
+is appended to the last slash of the pattern, all occurrences
+in each word are replaced.
+If a
+.Ql 1
+is appended to the last slash of the pattern, only the first word
+is affected.
+If
+.Ar old_string
+begins with a caret
+.Pq Ql ^ ,
+.Ar old_string
+is anchored at the beginning of each word.
+If
+.Ar old_string
+ends with 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
+(without any
+.Ql ^
+or
+.Ql \&$ ) .
+Any character may be used as a delimiter for the parts of the modifier
+string.
+The anchoring, ampersand and delimiter characters may be escaped with a
+backslash
+.Pq Ql \e .
+.Pp
+Variable expansion occurs in the normal fashion inside both
+.Ar old_string
+and
+.Ar new_string
+with the single exception that a backslash is used to prevent the expansion
+of a dollar sign
+.Pq Ql \&$ ,
+not a preceding dollar sign as is usual.
+.Sm off
+.It Cm :C No \&/ Ar pattern Xo
+.No \&/ Ar replacement
+.No \&/ Op Cm 1g
+.Xc
+.Sm on
+The
+.Cm :C
+modifier is just like the
+.Cm :S
+modifier except that the old and new strings, instead of being
+simple strings, are an extended regular expression (see
+.Xr re_format 7 )
+and an
+.Xr ed 1 Ns \-style
+replacement string.
+Normally, the first occurrence of the pattern in
+each word of the value is changed.
+The
+.Ql 1
+modifier causes the substitution to apply to at most one word; the
+.Ql g
+modifier causes the substitution to apply to as many instances of the
+search pattern as occur in the word or words it is found in.
+Note that
+.Ql 1
+and
+.Ql g
+are orthogonal; the former specifies whether multiple words are
+potentially affected, the latter whether multiple substitutions can
+potentially occur within each affected word.
+.It Cm :T
+Replaces each word in the variable with its last component.
+.It Ar :old_string Ns = Ns Ar new_string
+This is the
+.At V
+style variable substitution.
+It must be the last modifier specified.
+If
+.Ar old_string
+or
+.Ar new_string
+do not contain the pattern matching character
+.Sq %
+then it is assumed that they are
+anchored at the end of each word, so only suffixes or entire
+words may be replaced.
+Otherwise
+.Sq %
+is the substring of
+.Ar old_string
+to be replaced in
+.Ar new_string .
+The right hand side
+.Pq Ar new_string
+may contain variable values, which will be expanded.
+To put an actual single dollar, just double it.
+.El
+.Pp
+All modifiers are
+.Bx
+extensions, except for the standard
+.At V
+style variable substitution.
+.Pp
+The interpretation of
+.Sq %
+and
+.Sq $
+in
+.At V
+variable substitutions is not mandated by POSIX, though it is
+fairly common.
+.Sh INCLUDE STATEMENTS, CONDITIONALS AND FOR LOOPS
+Makefile inclusion, conditional structures and for loops reminiscent
+of the C programming language are provided in
+.Nm make .
+All such structures are identified by a line beginning with a single
+dot
+.Pq Ql \&.
+character.
+Whitespace characters may follow this dot, e.g.,
+.Bd -literal -offset indent
+\&.include <file>
+.Ed
+and
+.Bd -literal -offset indent -compact
+\&. include <file>
+.Ed
+.Pp
+are identical constructs.
+Files are included with either
+.Ql .include <file>
+or
+.Ql .include Qq 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
+.Fl I
+option are searched before the system
+makefile directory.
+.Pp
+Conditional expressions are also preceded by a single dot as the first
+character of a line.
+The possible conditionals are as follows:
+.Bl -tag -width Ds
+.It Ic .undef Ar variable
+Un-define the specified global variable.
+Only global variables may be un-defined.
+.It Ic .poison Ar variable
+Poison the specified global variable.
+Any further reference to
+.Ar variable
+will be flagged as an error.
+.It Ic .poison !defined Pq Ar variable
+It is an error to try to use the value of
+.Ar variable
+in a context where it is not defined.
+.It Ic .poison empty Pq Ar variable
+It is an error to try to use the value of
+.Ar variable
+in a context where it is not defined or is empty.
+.It Xo
+.Ic \&.if
+.Oo \&! Oc Ns Ar expression
+.Op Ar operator expression ...
+.Xc
+Test the value of an expression.
+.It Xo
+.Ic .ifdef
+.Oo \&! Oc Ns Ar variable
+.Op Ar operator variable ...
+.Xc
+Test the value of a variable.
+.It Xo
+.Ic .ifndef
+.Oo \&! Oc Ns Ar variable
+.Op Ar operator variable ...
+.Xc
+Test the value of a variable.
+.It Xo
+.Ic .ifmake
+.Oo \&! Oc Ns Ar target
+.Op Ar operator target ...
+.Xc
+Test the target being built.
+.It Xo
+.Ic .ifnmake
+.Oo \&! Oc Ns Ar target
+.Op Ar operator target ...
+.Xc
+Test the target being built.
+.It Ic .else
+Reverse the sense of the last conditional.
+.It Xo
+.Ic .elif
+.Oo \&! Oc Ns Ar expression
+.Op Ar operator expression ...
+.Xc
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .if .
+.It Xo
+.Ic .elifdef
+.Oo \&! Oc Ns Ar variable
+.Op Ar operator variable ...
+.Xc
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .ifdef .
+.It Xo
+.Ic .elifndef
+.Oo \&! Oc Ns Ar variable
+.Op Ar operator variable ...
+.Xc
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .ifndef .
+.It Xo
+.Ic .elifmake
+.Oo \&! Oc Ns Ar target
+.Op Ar operator target ...
+.Xc
+A combination of
+.Sq Ic .else
+followed by
+.Sq Ic .ifmake .
+.It Xo
+.Ic .elifnmake
+.Oo \&! Oc Ns Ar target
+.Op Ar operator target ...
+.Xc
+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 -width "Cm XX"
+.It Cm ||
+logical OR
+.It Cm \&&&
+Logical AND; of higher precedence than
+.Cm || .
+.El
+.Pp
+As in C,
+.Nm
+will only evaluate a conditional as far as is necessary to determine
+its value.
+Parentheses may be used to change the order of evaluation.
+The boolean operator
+.Sq Ic \&!
+may be used to logically negate an entire
+conditional.
+It is of higher precedence than
+.Sq Ic \&&& .
+.Pp
+The value of
+.Ar expression
+may be any of the following:
+.Bl -tag -width commands
+.It Ic commands
+Takes a target name as an argument and evaluates to true if the target
+has been defined and has shell commands associated with it.
+.It Ic defined
+Takes a variable name as an argument and evaluates to true if the variable
+has been defined.
+.It Ic make
+Takes a target name as an argument and evaluates to true if the target
+was specified as part of
+.Nm make Ns 's
+command line or was declared the default target (either implicitly or
+explicitly, see
+.Va .MAIN )
+before the line containing the conditional.
+.It Ic empty
+Takes a variable, with possible modifiers, and evaluates to true if
+the expansion of the variable would result in an empty string.
+.It Ic exists
+Takes a file name as an argument and evaluates to true if the file exists.
+The file is searched for on the system search path (see
+.Va .PATH ) .
+.It Ic target
+Takes a target name as an argument and evaluates to true if the target
+has been defined.
+.El
+.Pp
+.Ar expression
+may also be an arithmetic or string comparison.
+Variable expansion is
+performed on both sides of the comparison, after which the integral
+values are compared.
+A value is interpreted as hexadecimal if it is
+preceded by 0x, otherwise it is decimal; octal numbers are not supported.
+The standard C relational operators are all supported.
+If after
+variable expansion, either the left or right hand side of a
+.Sq Ic ==
+or
+.Sq Ic "!="
+operator is not an integral value, then
+string comparison is performed between the expanded
+variables.
+If no relational operator is given, it is assumed that the expanded
+variable is being compared against 0.
+.Pp
+When
+.Nm
+is evaluating one of these conditional expressions, and it encounters
+a word it doesn't recognize, either the
+.Dq make
+or
+.Dq defined
+expression is applied to it, depending on the form of the conditional.
+If the form is
+.Sq Ic .ifdef
+or
+.Sq Ic .ifndef ,
+the
+.Dq defined
+expression is applied.
+Similarly, if the form is
+.Sq Ic .ifmake
+or
+.Sq Ic .ifnmake ,
+the
+.Dq make
+expression is applied.
+.Pp
+If the conditional evaluates to true, the parsing of the makefile continues
+as before.
+If it evaluates to false, the following lines are skipped.
+In both cases this continues until a
+.Sq Ic .else
+or
+.Sq Ic .endif
+is found.
+.Pp
+For loops are typically used to apply a set of rules to a list of files.
+The syntax of a for loop is:
+.Bd -unfilled -offset indent
+.Ic .for Ar variable Oo Ar variable ... Oc Ic in Ar expression
+ <make-rules>
+.Ic .endfor
+.Ed
+.Pp
+After the for
+.Ar expression
+is evaluated, it is split into words.
+On each iteration of the loop, one word is assigned to each
+.Ar variable ,
+in order,
+and these
+.Ar variables
+are substituted in the
+.Ic make-rules
+inside the body of the for loop.
+The number of words must match the number of iteration variables;
+that is, if there are three iteration variables, the number of words
+must be a multiple of three.
+.Pp
+Loops and conditional expressions may nest arbitrarily, but
+they may not cross include file boundaries.
+.Pp
+.Nm
+also supports
+.Ic sinclude
+and
+.Ic -include
+for compatibility with other implementations.
+Both use the same syntax:
+.Bd -unfilled -offset indent
+.Ic sinclude Pa file
+.Ic -include Pa file
+.Ed
+.Pp
+.Po
+note no quotes around
+.Pa file
+.Pc
+and will include
+.Pa file ,
+but without any error if it does not exist.
+.Sh COMMENTS
+Comments begin with a hash
+.Pq Ql \&#
+character, anywhere but in a shell
+command line, and continue to the end of the line
+(but a
+.Pq Ql \&#
+character in a shell command line will be interpreted as a comment by
+the shell).
+.Sh TARGET ATTRIBUTES
+Some targets may be tagged with some specific attributes by one
+of the
+.Sx SPECIAL TARGETS
+or
+.Sx SPECIAL PREREQUISITES
+described below.
+.Bl -tag -width "Ignoring errors"
+.It Dq Always build
+Run the commands associated with this target even if the
+.Fl n
+or
+.Fl t
+options were specified.
+Can be used to mark recursive
+.Nm make Ns 's ,
+but prefer standard
+.Sq Ic + Ns Ar cmd .
+.It Dq Cheap
+In parallel mode, don't scan the commands for occurrences of
+.Nm ,
+thus letting normal recursive
+.Fl j
+behavior apply.
+.It Dq Expensive
+In parallel mode, assume commands will invoke recursive commands.
+Once
+.Nm
+starts building an expensive target, it won't start building anything else
+until that target has finished building.
+.It Dq Ignoring errors
+Ignore any errors generating by running shell commands, exactly
+as if they were all preceded by a dash
+.Pq Ql \- .
+.It Dq Phony
+A phony target is a target that does not correspond to any object in the
+file system (more like a placeholder for a list of commands).
+.Pp
+Phony targets are always out of date at the start of a run, but
+.Nm
+still keeps track of when they are built (that is, when the associated
+command list finishes running).
+.It Dq Precious
+Don't remove the target if
+.Nm
+is interrupted in the middle of building it.
+.It Dq Silent
+Do not display shell commands before running them, exactly as
+if they were all preceded by a
+.Sq @ .
+.El
+.Sh SPECIAL TARGETS
+.Nm
+recognizes standard special targets:
+.Bl -tag -width ".NOTPARALLEL"
+.It Ic .DEFAULT
+If there is a
+.Ic .DEFAULT
+target rule, with commands but no prerequisites, and
+.Nm
+can't figure out another way to build a target, it will use that
+list of commands, setting
+.Va \&<
+and
+.Va @
+appropriately.
+.It Ic .IGNORE
+Mark its prerequisites as
+.Dq Ignoring errors .
+.Pp
+If the list of prerequisites is empty, apply that to all targets, exactly
+like the
+.Fl i
+command-line option.
+.It Ic .PRECIOUS
+Mark its prerequisites as
+.Dq Precious .
+.Pp
+If the list of prerequisites is empty, apply that to all targets.
+.It Ic .SILENT
+Mark its prerequisites as
+.Dq Silent .
+.Pp
+If the list of prerequisites is empty, apply that to all targets, exactly
+like the
+.Fl s
+command-line option.
+.It Ic .SUFFIXES
+See
+.Sx INFERENCE RULES .
+.El
+.Pp
+and also some other special targets as an extension:
+.Bl -tag -width ".NOTPARALLEL"
+.It Ic .BEGIN
+Command lines attached to this target are executed before anything
+else is done.
+.It Ic .CHEAP
+Mark its prerequisites as
+.Dq Cheap .
+.It Ic .END
+Command lines attached to this target are executed at the end of a successful
+run.
+.It Ic .EXPENSIVE
+Mark its prerequisites as
+.Dq Expensive .
+.It Ic .INTERRUPT
+Command lines attached to this target are executed if
+.Nm
+is interrupted by a SIGINT.
+.It Ic .MAKE
+Mark its prerequisites as
+.Dq Always build .
+Prefer standard
+.Sq Ic + Ns Ar cmd .
+.It Ic .MAIN
+If no target is specified when
+.Nm
+is invoked, this target will be built.
+This is always set, either
+explicitly, or implicitly when
+.Nm
+selects the default target, to give the user a way to refer to the default
+target on the command line.
+.It Ic .MAKEFLAGS
+This target provides a way to specify flags for
+.Nm
+when the makefile is used.
+The flags are as if typed to the shell, though the
+.Fl f
+option will have
+no effect.
+.It Ic .NOTPARALLEL
+Disable parallel mode for the current makefile.
+The
+.Fl j
+option is still passed to submakes.
+.It Ic .NO_PARALLEL
+Same as above, for compatibility with other pmake variants.
+.It Ic .ORDER
+The list of prerequisites should be built in sequence.
+.It Ic .PATH
+The prerequisites define a search path: directories that will be searched
+for files not found in the current directory.
+If no prerequisites are specified, any previously specified directories are
+deleted.
+.It Ic .PATH\fI.suffix\fR
+This target is only valid if .suffix is a currently valid suffix.
+The prerequisites defines a search path for files ending in that suffix.
+For files not found in the current directory,
+.Nm
+will first look in that path, before reverting to the default search path.
+.It Ic .PHONY
+Mark its prerequisites as
+.Dq Phony
+targets.
+.El
+.Pp
+It is an error to use several special targets, or a special target and
+normal targets, in a single dependency line.
+.Sh SPECIAL PREREQUISITES
+Of the special targets described in the previous
+section, the ones that tag prerequisites can also be used as prerequisites,
+in which case the corresponding targets will be tagged accordingly.
+.Pp
+This is an extension, even for standard special targets.
+.Pp
+.Nm
+also recognizes some other prerequisites:
+.Bl -tag -width ".PRECIOUS"
+.It Ic .NOTMAIN
+Normally
+.Nm
+selects the first target it encounters as the default target to be built
+if no target was specified.
+This prerequisite 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 will ignore this fact and assume
+the file isn't needed or already exists.
+.It Ic .USE
+Turn the target into
+.Nm make Ns 's
+version of a macro.
+When the target is used as a prerequisite for another target, the other target
+acquires the commands, prerequisites, and attributes (except for
+.Ic .USE )
+of the
+prerequisite.
+If the target already has commands, the
+.Ic .USE
+target's commands are appended
+to them.
+.It Ic .WAIT
+If
+.Ic .WAIT
+appears in a dependency line, the prerequisites that precede it are
+made before the prerequisites that follow it in the line.
+Loops are not
+detected and targets that form loops will be silently ignored.
+.El
+.Sh ENVIRONMENT
+.Nm
+uses the following environment variables, if they exist:
+.Ev MACHINE ,
+.Ev MACHINE_ARCH ,
+.Ev MACHINE_CPU ,
+.Ev MAKEFLAGS ,
+.Ev MAKEOBJDIR
+and
+.Ev PWD .
+.Nm
+also ignores and unsets
+.Ev CDPATH .
+.Sh FILES
+.Bl -tag -width /usr/share/mk -compact
+.It Pa .depend
+list of dependencies
+.It Pa makefile
+default makefile
+.It Pa Makefile
+default makefile if
+.Pa makefile
+does not exist
+.It Pa sys.mk
+system makefile
+.It Pa /usr/share/mk
+system makefile directory
+.El
+.Sh EXIT STATUS
+If
+.Fl q
+was specified, the
+.Nm
+utility exits with one of the following values:
+.Pp
+.Bl -tag -width Ds -offset indent -compact
+.It 0
+Normal behavior.
+.It 1
+The target was not up to date.
+.It >1
+An error occurred.
+.El
+.Pp
+Otherwise, the
+.Nm
+utility exits with a value of 0 on success, and >0 if an error occurred.
+.Sh SEE ALSO
+.Xr ed 1 ,
+.Xr mkdep 1 ,
+.Xr sh 1 ,
+.Xr getcwd 3 ,
+.Xr uname 3 ,
+.Xr re_format 7
+.Rs
+.%A S. I. Feldman
+.%T Make \(em A Program for Maintaining Computer Programs
+.\".%R Computing Science Technical Report
+.\".%N 57
+.%J Software \(em Practice and Experience
+.%V 9:4
+.%P pp. 255-265
+.%D April 1979
+.Re
+.Rs
+.\" 4.4BSD PSD:12
+.%A Adam de Boor
+.%T PMake \(em A Tutorial
+.%B 4.4BSD Programmer's Supplementary Documents (PSD)
+.Re
+.Sh STANDARDS
+The
+.Nm
+utility is mostly compliant with the
+.St -p1003.1-2008
+specification,
+though its presence is optional.
+.Pp
+The flags
+.Op Fl BCDdIjmV
+are extensions to that specification.
+.Pp
+Older versions of
+.Nm
+used
+.Ev MAKE
+instead of
+.Ev MAKEFLAGS .
+This was removed for POSIX compatibility.
+The internal variable
+.Va MAKE
+is set to the same value as
+.Va .MAKE .
+Support for this may be removed in the future.
+.Pp
+Most of the more esoteric features of
+.Nm
+should probably be avoided for greater compatibility.
+.Sh HISTORY
+A
+.Nm
+command first appeared outside of Bell Labs in PWB/UNIX 1.0.
+It was replaced in
+.Bx 4.3 Reno .
+.Sh AUTHORS
+.An Stuart Feldman
+wrote the original implementation at the
+Bell Labs Computing Science Research Center.
+.Pp
+This implementation is a distant derivative of
+.Nm pmake ,
+originally written by Adam de Boor for the Sprite operating system.
+.Sh BUGS
+If the same target is specified several times in complete target rules,
+.Nm
+silently ignores all commands after the first non empty set of commands,
+e.g., in
+.Bd -literal -offset indent
+a:
+ @echo "Executed"
+a:
+ @echo "Bad luck"
+.Ed
+.Pp
+@echo "Bad luck" will be ignored.
+.Pp
+.Va .TARGETS
+is not set to the default target when
+.Nm
+is invoked without a target name and no
+.Ic MAIN
+special target exists.
+.Pp
+The evaluation of
+.Ar expression
+in a test is somewhat simplistic.
+Variables don't need to be quoted, but strings do:
+Tests like
+.Ql .if ${VAR} == "string" ,
+.Ql .if ${VAR} >= 5 ,
+.Ql .if 5 <= 10 ,
+and
+.Ql .if "string" == ${VAR}
+do work, but
+.Ql .if string = ${VAR}
+doesn't.
+.Pp
+For loops are expanded before tests, so a fragment such as:
+.Bd -literal -offset indent
+\&.for TMACHINE in ${SHARED_ARCHS}
+\&.if "${TMACHINE}" == ${MACHINE}
+ ...
+\&.endif
+\&.endfor
+.Ed
+.Pp
+requires the quotes.
+.Pp
+When handling
+.Pf pre- Bx 4.4
+archives,
+.Nm
+may erroneously mark archive members as out of date if the archive name
+was truncated.
+.Pp
+The handling of
+.Sq ;\&
+and other special characters in tests may be utterly bogus.
+For instance, in
+.Bd -literal -offset indent
+\&A=abcd;c.c
+\&.if ${A:R} == "abcd;c"
+.Ed
+.Pp
+the test will never match, even though the value is correct.
+.Pp
+In a .for loop, only the variable value is used; assignments will be
+evaluated later, e.g., in
+.Bd -literal -offset indent
+\&.for I in a b c d
+I:=${I:S/a/z/}
+A+=$I
+\&.endfor
+.Ed
+.Pp
+.Sq A
+will evaluate to a b c d after the loop, not z b c d.
+.Pp
+.Ic ORDER
+is currently only used in parallel mode, so
+keep prerequisites ordered for sequential mode!
+.Pp
+Distinct target names are treated separately, even though they might
+correspond to the same file in the file system.
+This can cause excessive rebuilds of some targets, and bogus
+races in parallel mode.
+This can also prevent
+.Nm
+from finding a rule to solve a dependency if the target name is not
+exactly the same as the dependency.
+.Pp
+In parallel mode,
+.Fl j Ar n
+only limits the number of direct children of
+.Nm .
+During recursive invocations, each level may multiply the total number
+of processes by
+.Ar n .
+However,
+.Nm
+includes some heuristics to try to prevent catastrophic behavior:
+if a command is marked as expensive, or preceded by
+.Sq + ,
+or seems to
+invoke a program that looks sufficiently like
+.Sq make ,
+.Nm
+will assume recursive invocation, and not start any new process until
+said command has finished running.
+Thus the number of processes run directly or indirectly by
+.Nm
+will increase linearly with each level of recursion instead of exponentially.
+.Pp
+The
+.Va MAKEFILE
+variable cannot be used reliably.
+It is a compatibility feature and may get set to the last makefile
+specified, as it is set by System V make.