aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/make/make.1
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/make/make.1')
-rw-r--r--usr.bin/make/make.11643
1 files changed, 1643 insertions, 0 deletions
diff --git a/usr.bin/make/make.1 b/usr.bin/make/make.1
new file mode 100644
index 000000000000..b226f83e7e26
--- /dev/null
+++ b/usr.bin/make/make.1
@@ -0,0 +1,1643 @@
+.\" 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. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. 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.
+.\"
+.\" @(#)make.1 8.8 (Berkeley) 6/13/95
+.\" $FreeBSD$
+.\"
+.Dd April 8, 2006
+.Dt MAKE 1
+.Os
+.Sh NAME
+.Nm make
+.Nd maintain program dependencies
+.Sh SYNOPSIS
+.Nm
+.Op Fl ABPSXeiknqrstv
+.Op Fl C Ar directory
+.Op Fl D Ar variable
+.Op Fl d Ar flags
+.Op Fl E Ar variable
+.Op Fl f Ar makefile
+.Op Fl I Ar directory
+.Bk -words
+.Op Fl j Ar max_jobs
+.Op Fl m Ar directory
+.Ek
+.Op Fl V Ar variable
+.Op Fl x Ar warning_options
+.Op Ar variable Ns No = Ns Ar value
+.Op Ar target ...
+.Sh DESCRIPTION
+The
+.Nm
+utility is a program designed to simplify the maintenance of other programs.
+Its input is a list of specifications
+describing dependency relationships between the generation of
+files and programs.
+.Pp
+First of all, the initial list of specifications will be read
+from the system makefile,
+.Pa sys.mk ,
+unless inhibited with the
+.Fl r
+option.
+The standard
+.Pa sys.mk
+as shipped with
+.Fx
+also handles
+.Xr make.conf 5 ,
+the default path to which
+can be altered via the
+.Nm
+variable
+.Va __MAKE_CONF .
+.Pp
+Then the first of
+.Pa BSDmakefile ,
+.Pa makefile ,
+and
+.Pa Makefile
+that can be found in the current directory, object directory (see
+.Va .OBJDIR ) ,
+or search path (see the
+.Fl I
+option)
+will be read for the main list of dependency specifications.
+A different makefile or list of them can be supplied via the
+.Fl f
+option(s).
+Finally, if the file
+.Pa .depend
+can be found in any of the aforesaid locations, it will also be read (see
+.Xr mkdep 1 ) .
+.Pp
+When
+.Nm
+searches for a makefile, its name takes precedence over its location.
+For instance,
+.Pa BSDmakefile
+in the object directory will be favored over
+.Pa Makefile
+in the current directory.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl A
+Make archive errors non-fatal, causing
+.Nm
+to just skip the remainder
+or all of the archive and continue after printing a message.
+.It Fl B
+Try to be backwards compatible by executing a single shell per command and
+by executing the commands to make the sources of a dependency line in sequence.
+This is turned on by default unless
+.Fl j
+is used.
+.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 context.
+.It Fl d Ar flags
+Turn on debugging, and specify which portions of
+.Nm
+are to print debugging information.
+Argument
+.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 f
+Print debugging information about the execution 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 j
+Print debugging information about running multiple shells.
+.It Ar l
+Print commands in Makefiles regardless of whether or not they are prefixed
+by @ or other "quiet" flags.
+Also known as "loud" behavior.
+.It Ar m
+Print debugging information about making targets, including modification
+dates.
+.It Ar s
+Print debugging information about suffix-transformation rules.
+.It Ar t
+Print debugging information about target list maintenance.
+.It Ar v
+Print debugging information about variable assignment.
+.El
+.It Fl E Ar variable
+Specify a variable whose environment value (if any) will override
+macro assignments within makefiles.
+.It Fl e
+Specify that environment values override macro assignments within
+makefiles for all variables.
+.It Fl f Ar makefile
+Specify a makefile to read instead of the default one.
+If
+.Ar makefile
+is not an absolute pathname,
+.Nm
+will search for it as described above.
+In case
+.Ar makefile
+is
+.Sq Fl ,
+standard input is read.
+Multiple
+.Fl f
+options can be supplied,
+and the makefiles will be read in that order.
+.It Fl I Ar directory
+Specify a directory in which to search for makefiles and included makefiles.
+Multiple
+.Fl I
+options can be specified to form a search path.
+The system makefile directory (or directories, see the
+.Fl m
+option) is automatically appended at the tail of this path.
+.It Fl i
+Ignore non-zero exit of shell commands in the makefile.
+Equivalent to specifying
+.Sq Ic \-
+before each command line in the makefile.
+.It Fl j Ar max_jobs
+Specify the maximum number of jobs that
+.Nm
+may have running at any one time.
+Turns compatibility mode off, unless the
+.Fl B
+flag is also specified.
+.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
+the system makefile and makefiles included via the <...> style.
+Multiple
+.Fl m
+options can be specified to form a search path.
+This path will override the default system include path,
+.Pa /usr/share/mk .
+The system include path will always be appended to the search path used
+for "..."-style inclusions and makefile searches (see the
+.Fl I
+option).
+.It Fl n
+Display the commands that would have been executed, but do not actually
+execute them.
+.It Fl P
+Collate the output of a given job and display it only when the job finishes,
+instead of mixing the output of parallel jobs together.
+This option has no effect unless
+.Fl j
+is used too.
+.It Fl q
+Do not execute any commands, but exit 0 if the specified targets are
+up-to-date and 1, otherwise.
+.It Fl r
+Do not process the system makefile.
+.It Fl S
+Stop processing when an error is encountered.
+Default behaviour.
+This is needed to negate the
+.Fl k
+option during recursive builds.
+.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
+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
+.Nm Ns 's
+idea of the value of
+.Ar variable ,
+in the global context.
+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.
+.It Fl v
+Be extra verbose.
+For multi-job makes, this will cause file banners to be generated.
+.It Fl X
+When using the
+.Fl V
+option to print the values of variables,
+do not recursively expand the values.
+.It Ar variable Ns No = Ns Ar value
+Set the value of the variable
+.Ar variable
+to
+.Ar value .
+.It Fl x Ar warning_options
+Specify extended warning options.
+This option may be specified several times.
+A
+.Ar warning_option
+can be prefixed with
+.Dq Li no
+in which case the warning is switched off.
+The currently available options are:
+.Bl -tag -width indent
+.It Li dirsyntax
+Warn if anything except blanks and comments follows an
+.Ic .endif
+or
+.Ic .else
+directive.
+.El
+.Pp
+See also the
+.Ic .WARN
+special target.
+.El
+.Pp
+There are seven different types of lines in a makefile: file dependency
+specifications, shell commands, variable assignments, include statements,
+conditional directives, for loops, and comments.
+.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 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 usually created from them.
+The exact relationship between the target and the source is determined
+by the operator that separates them.
+The three operators are as follows:
+.Bl -tag -width flag
+.It Ic \&:
+A target is considered out-of-date if its modification time is less than
+those of any of its sources.
+Sources for a target accumulate over dependency lines when this operator
+is used.
+The target is removed if
+.Nm
+is interrupted.
+.It Ic \&!
+Targets are always re-created, but not until all sources have been
+examined and re-created as necessary.
+Sources for a target accumulate over dependency lines when this operator
+is used.
+The target is removed if
+.Nm
+is interrupted.
+.It Ic ::
+If no sources are specified, the target is always re-created.
+Otherwise, a target is considered out-of-date if any of its sources has
+been modified more recently than the target.
+Sources for a target do not accumulate over dependency lines when this
+operator is used.
+The target will not be removed if
+.Nm
+is interrupted.
+.El
+.Pp
+Targets and sources 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 source, 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.
+.Sh SHELL COMMANDS
+Each target may have associated with it a series of shell commands, normally
+used to create the target.
+Each of the commands in this script
+.Em must
+be preceded by a tab.
+While any target may appear on a dependency line, only one of these
+dependencies may be followed by a creation script, unless the
+.Sq Ic ::
+operator is used.
+.Pp
+If the first characters of the command line are
+.Sq Ic @ ,
+.Sq Ic \- ,
+and/or
+.Sq Ic + ,
+the command is treated specially.
+A
+.Sq Ic @
+causes the command not to be echoed before it is executed.
+A
+.Sq Ic \-
+causes any non-zero exit status of the command line to be ignored.
+A
+.Sq Ic +
+causes the command to be executed even if
+.Fl n
+is specified on the command line.
+.Sh VARIABLE ASSIGNMENTS
+Variables in
+.Nm
+are much like variables in the shell, and, by tradition,
+consist of all upper-case letters.
+The five operators that can be used to assign values to variables are as
+follows:
+.Bl -tag -width Ds
+.It Ic =
+Assign the value to the variable.
+Any previous value is overridden.
+.It Ic +=
+Append the value to the current value of the variable.
+.It Ic ?=
+Assign the value to the variable if it is not already defined.
+.It Ic :=
+Assign with expansion, i.e., expand the value before assigning it
+to the variable.
+Normally, expansion is not done until the variable is referenced.
+.It Ic !=
+Expand the value and pass it to the shell for execution and assign
+the result to the variable.
+Any newlines in the result are replaced with spaces.
+.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
+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 two distinct times, depending on where
+the variable is being used.
+Variables in dependency lines 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 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 and variables
+obtained from the
+.Ev MAKEFLAGS
+environment variable or the
+.Ic .MAKEFLAGS
+target.
+.It Local variables
+Variables that are defined specific to a certain target.
+The seven local variables are as follows:
+.Bl -tag -width ".ARCHIVE"
+.It Va .ALLSRC
+The list of all sources for this target; also known as
+.Sq Va > .
+.It Va .ARCHIVE
+The name of the archive file; also known as
+.Sq Va \&! .
+.It Va .IMPSRC
+The name/path of the source from which the target is to be transformed
+(the
+.Dq implied
+source); also known as
+.Sq Va < .
+.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 file prefix of the file, containing only the file portion, no suffix
+or preceding directory components; also known as
+.Sq Va * .
+.It Va .TARGET
+The name of the target; also known as
+.Sq Va @ .
+.El
+.Pp
+The shorter forms
+.Sq Va @ ,
+.Sq Va \&! ,
+.Sq Va < ,
+.Sq Va % ,
+.Sq Va \&? ,
+.Sq Va > ,
+and
+.Sq Va *
+are permitted for backward
+compatibility and are not recommended.
+The six variables
+.Sq Va @F ,
+.Sq Va @D ,
+.Sq Va <F ,
+.Sq Va <D ,
+.Sq Va *F ,
+and
+.Sq Va *D
+are
+permitted for compatibility with
+.At V
+makefiles and 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
+.Va .TARGET ,
+.Va .PREFIX ,
+.Va .ARCHIVE ,
+and
+.Va .MEMBER .
+.El
+.Pp
+In addition,
+.Nm
+sets or knows about the following internal variables or environment
+variables:
+.Bl -tag -width ".Va .MAKEFILE_LIST"
+.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.
+The
+.Nm
+utility sets
+.Va .CURDIR
+to the canonical path given by
+.Xr getcwd 3 .
+.It Va .OBJDIR
+A path to the directory where the targets are built.
+At startup,
+.Nm
+searches for an alternate directory to place target files.
+It will attempt to change into this special directory
+and will search this directory for makefiles
+not found in the current directory.
+The following directories are tried in order:
+.Pp
+.Bl -enum -compact
+.It
+${MAKEOBJDIRPREFIX}/`pwd`
+.It
+${MAKEOBJDIR}
+.It
+obj.${MACHINE}
+.It
+obj
+.It
+/usr/obj/`pwd`
+.El
+.Pp
+The first directory that
+.Nm
+successfully changes into is used.
+If either
+.Ev MAKEOBJDIRPREFIX
+or
+.Ev MAKEOBJDIR
+is set in the environment but
+.Nm
+is unable to change into the corresponding directory,
+then the current directory is used
+without checking the remainder of the list.
+If they are undefined and
+.Nm
+is unable to change into any of the remaining three directories,
+then the current directory is used.
+Note, that
+.Ev MAKEOBJDIRPREFIX
+and
+.Ev MAKEOBJDIR
+must be environment variables and should not be set on
+.Nm Ns 's
+command line.
+.Pp
+The
+.Nm
+utility sets
+.Va .OBJDIR
+to the canonical path given by
+.Xr getcwd 3 .
+.It Va .MAKEFILE_LIST
+As
+.Nm
+reads various makefiles, including the default files and any
+obtained from the command line and
+.Ic .include
+and
+.Ic .sinclude
+directives, their names will be automatically appended to the
+.Va .MAKEFILE_LIST
+variable.
+They are added right before
+.Nm
+begins to parse them, so that the name of the current makefile is the
+last word in this variable.
+.It Va .MAKEFLAGS
+The environment variable
+.Ev MAKEFLAGS
+may contain anything that
+may be specified on
+.Nm Ns 's
+command line.
+Its contents are stored in
+.Nm Ns 's
+.Va .MAKEFLAGS
+variable.
+All options and variable assignments specified on
+.Nm Ns 's
+command line are appended to the
+.Va .MAKEFLAGS
+variable which is then
+entered into the environment as
+.Ev MAKEFLAGS
+for all programs which
+.Nm
+executes.
+By modifying the contents of the
+.Va .MAKEFLAGS
+variable, makefile can alter the contents of the
+.Va MAKEFLAGS
+environment variable made available for all programs which
+.Nm
+executes; compare with the
+.Ic .MAKEFLAGS
+special target below.
+.Pp
+When passing macro definitions and flag arguments in the
+.Ev MAKEFLAGS
+environment variable,
+space and tab characters are quoted by preceding them with a backslash.
+When reading the
+.Ev MAKEFLAGS
+variable from the environment,
+all sequences of a backslash and one of space or tab
+are replaced just with their second character
+without causing a word break.
+Any other occurrences of a backslash are retained.
+Groups of unquoted space, tab and newline characters cause word
+breaking.
+.It Va MFLAGS
+This variable is provided for backward compatibility and
+contains all the options from the
+.Ev MAKEFLAGS
+environment variable plus any options specified on
+.Nm Ns 's
+command line.
+.It Va .TARGETS
+List of targets
+.Nm
+is currently building.
+.It Va .INCLUDES
+See
+.Ic .INCLUDES
+special target.
+.It Va .LIBS
+See
+.Ic .LIBS
+special target.
+.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, defined at compilation time.
+.It Va VPATH
+Makefiles may assign a colon-delimited list of directories to
+.Va VPATH .
+These directories will be searched for source files by
+.Nm
+after it has finished parsing all input makefiles.
+.El
+.Pp
+Variable expansion may be modified to select or modify each word of the
+variable (where a
+.Dq word
+is 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 Cm
+.Sm off
+.It Cm C No / Ar pattern Xo
+.No / Ar replacement
+.No / Op Cm 1g
+.Xc
+.Sm on
+Modify each word of the value,
+substituting every match of the extended regular expression
+.Ar pattern
+(see
+.Xr re_format 7 )
+with the
+.Xr ed 1 Ns \-style
+.Ar 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 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
+Converts variable to lower-case letters.
+.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 O
+Order every word in the variable alphabetically.
+.It Cm Q
+Quotes every shell meta-character in the variable, so that it can be passed
+safely through recursive invocations of
+.Nm .
+.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 g
+.Xc
+.Sm on
+Modify the first occurrence of
+.Ar old_string
+in each word of 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
+.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 .
+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.
+.It Ar old_string=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
+.Ar %
+then it is assumed that they are
+anchored at the end of each word, so only suffixes or entire
+words may be replaced.
+Otherwise
+.Ar %
+is the substring of
+.Ar old_string
+to be replaced in
+.Ar new_string
+.It Cm T
+Replaces each word in the variable with its last component.
+.It Cm U
+Converts variable to upper-case letters.
+.It Cm u
+Remove adjacent duplicate words (like
+.Xr uniq 1 ) .
+.El
+.Sh DIRECTIVES, CONDITIONALS, AND FOR LOOPS
+Directives, conditionals, and for loops reminiscent
+of the C programming language are provided in
+.Nm .
+All such structures are identified by a line beginning with a single
+dot
+.Pq Ql \&.
+character.
+The following directives are supported:
+.Bl -tag -width Ds
+.It Ic .include Ar <file>
+.It Ic .include Ar \*qfile\*q
+Include the specified makefile.
+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.
+.It Ic .sinclude Ar <file>
+.It Ic .sinclude Ar \*qfile\*q
+Like
+.Ic .include ,
+but silently ignored if the file cannot be found and opened.
+.It Ic .undef Ar variable
+Un-define the specified global variable.
+Only global variables may be un-defined.
+.It Ic .error Ar message
+Terminate processing of the makefile immediately.
+The filename of the
+makefile, the line on which the error was encountered and the specified
+message are printed to the standard error output and
+.Nm
+terminates with exit code 1.
+Variables in the message are expanded.
+.It Ic .warning Ar message
+Emit a warning message.
+The filename of the makefile,
+the line on which the warning was encountered,
+and the specified message are printed to the standard error output.
+Variables in the message are expanded.
+.El
+.Pp
+Conditionals are used to determine which parts of the Makefile
+to process.
+They are used similarly to the conditionals supported
+by the C pre-processor.
+The following conditionals are supported:
+.Bl -tag -width Ds
+.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
+.Ic .else
+followed by
+.Ic .if .
+.It Xo
+.Ic .elifdef
+.Oo \&! Oc Ns Ar variable
+.Op Ar operator variable ...
+.Xc
+A combination of
+.Ic .else
+followed by
+.Ic .ifdef .
+.It Xo
+.Ic .elifndef
+.Oo \&! Oc Ns Ar variable
+.Op Ar operator variable ...
+.Xc
+A combination of
+.Ic .else
+followed by
+.Ic .ifndef .
+.It Xo
+.Ic .elifmake
+.Oo \&! Oc Ns Ar target
+.Op Ar operator target ...
+.Xc
+A combination of
+.Ic .else
+followed by
+.Ic .ifmake .
+.It Xo
+.Ic .elifnmake
+.Oo \&! Oc Ns Ar target
+.Op Ar operator target ...
+.Xc
+A combination of
+.Ic .else
+followed by
+.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
+.Tn OR
+.It Cm &&
+Logical
+.Tn AND ;
+of higher precedence than
+.Sq Ic || .
+.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 Ic
+.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 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
+An
+.Ar expression
+may also be an arithmetic or string comparison, with the left-hand side
+being a variable expansion.
+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 does not recognize, either the
+.Dq make
+or
+.Dq defined
+expression is applied to it, depending on the form of the conditional.
+If the form is
+.Ic .if ,
+.Ic .ifdef
+or
+.Ic .ifndef ,
+the
+.Dq defined
+expression is applied.
+Similarly, if the form is
+.Ic .ifmake
+or
+.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
+.Ic .else
+or
+.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:
+.Pp
+.Bl -tag -width indent -compact
+.It Ic .for Ar variable Ic in Ar expression
+.It <make-rules>
+.It Ic .endfor
+.El
+.Pp
+After the for
+.Ar expression
+is evaluated, it is split into words.
+The
+iteration
+.Ar variable
+is successively set to each word, and substituted in the
+.Ic make-rules
+inside the body of the for loop.
+.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.
+.Sh SPECIAL SOURCES
+.Bl -tag -width Ic
+.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 .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 .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
+cannot figure out how to create it, it will ignore this fact and assume
+the file is not needed or already exists.
+.It Ic .PRECIOUS
+When
+.Nm
+is interrupted, it removes any partially made targets.
+This source prevents the target from being removed.
+.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 .WAIT
+If special
+.Ic .WAIT
+source appears in a dependency line, the sources that precede it are
+made before the sources that succeed it in the line.
+Loops are not being
+detected and targets that form loops will be silently ignored.
+.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 Ic
+.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
+cannot figure out any other way to create.
+Only the shell script is used.
+The
+.Ic .IMPSRC
+variable of a target that inherits
+.Ic .DEFAULT Ns 's
+commands is set
+to the target's own name.
+.It Ic .END
+Any command lines attached to this target are executed after everything
+else is done.
+.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 .INCLUDES
+A list of suffixes that indicate files that can be included in a source
+file.
+The suffix must have already been declared with
+.Ic .SUFFIXES ;
+any suffix so declared will have the directories on its search path (see
+.Ic .PATH )
+placed in the
+.Va .INCLUDES
+special variable, each preceded by a
+.Fl I
+flag.
+.It Ic .INTERRUPT
+If
+.Nm
+is interrupted, the commands for this target will be executed.
+.It Ic .LIBS
+This does for libraries what
+.Ic .INCLUDES
+does for include files, except that the flag used is
+.Fl L .
+.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.
+Flags (except for
+.Fl f )
+and variable assignments specified as the source
+for this target are also appended to the
+.Va .MAKEFLAGS
+internal variable.
+Please note the difference between this target and the
+.Va .MAKEFLAGS
+internal variable: specifying an option or variable
+assignment as the source for this target will affect
+.Em both
+the current makefile and all processes that
+.Nm
+executes.
+.It Ic .MFLAGS
+Same as above, for backward compatibility.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .NOTPARALLEL
+.\" The named targets are executed in non parallel mode. If no targets are
+.\" specified, then all targets are executed in non parallel mode.
+.It Ic .NOTPARALLEL
+Disable parallel mode.
+.It Ic .NO_PARALLEL
+Same as above, for compatibility with other
+.Nm pmake
+variants.
+.It Ic .ORDER
+The named targets are made in sequence.
+.\" XXX: NOT YET!!!!
+.\" .It Ic .PARALLEL
+.\" The named targets are executed in parallel mode. If no targets are
+.\" specified, then 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
+deleted.
+Where possible, use of
+.Ic .PATH
+is preferred over use of the
+.Va VPATH
+variable.
+.It Ic .PATH\fIsuffix\fR
+The sources are directories which are to be searched for suffixed files
+not found in the current directory.
+The
+.Nm
+utility
+first searches the suffixed search path, before reverting to the default
+path if the file is not found there.
+This form is required for
+.Ic .LIBS
+and
+.Ic .INCLUDES
+to work.
+.It Ic .PHONY
+Apply the
+.Ic .PHONY
+attribute to any specified sources.
+Targets with this attribute are always
+considered to be out of date.
+.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 .SHELL
+Select another shell.
+The sources of this target have the format
+.Ar key Ns = Ns Ar value .
+The
+.Ar key
+is one of:
+.Bl -tag -width ".Va hasErrCtl"
+.It Va path
+Specify the path to the new shell.
+.It Va name
+Specify the name of the new shell.
+This may be either one of the three builtin shells (see below) or any
+other name.
+.It Va quiet
+Specify the shell command to turn echoing off.
+.It Va echo
+Specify the shell command to turn echoing on.
+.It Va filter
+Usually shells print the echo off command before turning echoing off.
+This is the exact string that will be printed by the shell and is used
+to filter the shell output to remove the echo off command.
+.It Va echoFlag
+The shell option that turns echoing on.
+.It Va errFlag
+The shell option to turn on error checking.
+If error checking is on, the shell should exit if a command returns
+a non-zero status.
+.It Va hasErrCtl
+True if the shell has error control.
+.It Va check
+If
+.Va hasErrCtl
+is true then this is the shell command to turn error checking on.
+If
+.Va hasErrCtl
+is false then this is a command template to echo commands for which error
+checking is disabled.
+The template must contain a
+.Ql %s .
+.It Va ignore
+If
+.Va hasErrCtl
+is true, this is the shell command to turn error checking off.
+If
+.Va hasErrCtl
+is false, this is a command template to execute a command so that errors
+are ignored.
+The template must contain a
+.Ql %s .
+.It Va meta
+This is a string of meta characters of the shell.
+.It Va builtins
+This is a string holding all the shell's builtin commands separated by blanks.
+The
+.Va meta
+and
+.Va builtins
+strings are used in compat mode.
+When a command line contains neither a meta
+character nor starts with a shell builtin, it is executed directly without
+invoking a shell.
+When one of these strings (or both) is empty all commands are executed
+through a shell.
+.It Va unsetenv
+If true, remove the
+.Ev ENV
+environment variable before executing any command.
+This is useful for the Korn-shell
+.Pq Nm ksh .
+.El
+.Pp
+Values that are strings must be surrounded by double quotes.
+Boolean values are specified as
+.Ql T
+or
+.Ql Y
+(in either case) to mean true.
+Any other value is taken to mean false.
+.Pp
+There are several uses of the
+.Ic .SHELL
+target:
+.Bl -bullet
+.It
+Selecting one of the builtin shells.
+This is done by just specifying the name of the shell with the
+.Va name
+keyword.
+It is also possible to modify the parameters of the builtin shell by just
+specifying other keywords (except for
+.Va path ) .
+.It
+Using another executable for one of the builtin shells.
+This is done by specifying the path to the executable with the
+.Va path
+keyword.
+If the last component is the same as the name of the builtin shell, no
+name needs to be specified; if it is different, the name must be given:
+.Bd -literal -offset indent
+\&.SHELL: path="/usr/local/bin/sh"
+.Ed
+.Pp
+selects the builtin shell
+.Dq Li sh
+but will execute it from
+.Pa /usr/local/bin/sh .
+Like in the previous case, it is possible to modify parameters of the builtin
+shell by just specifying them.
+.It
+Using an entirely different shell.
+This is done by specifying all keywords.
+.El
+.Pp
+The builtin shells are
+.Dq Li sh ,
+.Dq Li csh
+and
+.Dq Li ksh .
+Because
+.Fx
+has no
+.Nm ksh
+in
+.Pa /bin ,
+it is unwise to specify
+.Va name Ns = Ns Qq Li ksh
+without also specifying a path.
+.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 .SUFFIXES
+Each source specifies a suffix to
+.Nm .
+If no sources are specified, any previous specified suffices are deleted.
+.It Ic .WARN
+Each source specifies a warning flag as previously described for the
+.Fl x
+command line option.
+Warning flags specified on the command line take precedence over flags
+specified in the makefile.
+Also, command line warning flags are pushed to sub-makes through the
+.Ev MAKEFLAGS
+environment variables so that a warning flag specified on the command
+line will influence all sub-makes.
+Several flags can be specified on a single
+.Ic .WARN
+target by seperating them with blanks.
+.El
+.Sh REMAKING MAKEFILES
+After reading Makefile and all the files that are included using
+.Ic .include
+or
+.Ic .sinclude
+directives (source Makefiles)
+.Nm
+considers each source Makefile as a target and tries to rebuild it.
+Both explicit and implicit rules are checked and all source Makefiles
+are updated if necessary. If any of the source Makefiles were rebuilt,
+.Nm
+restarts from clean state.
+.Pp
+To prevent infinite loops the following source Makefile targets are ignored:
+.Bl -bullet
+.It
+.Ic ::
+targets that have no prerequisites but have commands
+.It
+.Ic !
+targets
+.It
+targets that have
+.Ic .PHONY
+or
+.Ic .EXEC
+attributes
+.It
+targets without prerequisites and without commands
+.El
+.Pp
+When remaking a source Makefile options
+.Ic -t
+(touch target),
+.Ic -q
+(query mode), and
+.Ic -n
+(no exec) do not take effect, unless source Makefile is specified
+explicitly as a target in
+.Nm
+command line.
+.Pp
+Additionally, system makefiles and
+.Ic .depend
+are not considered as Makefiles that can be rebuilt.
+.Sh ENVIRONMENT
+The
+.Nm
+utility uses the following environment variables, if they exist:
+.Ev MACHINE ,
+.Ev MAKE ,
+.Ev MAKEFLAGS ,
+.Ev MAKEOBJDIR ,
+and
+.Ev MAKEOBJDIRPREFIX .
+.Sh FILES
+.Bl -tag -width /usr/share/doc/psd/12.make -compact
+.It Pa .depend
+list of dependencies
+.It Pa Makefile
+list of dependencies
+.It Pa makefile
+list of dependencies
+.It Pa obj
+object directory
+.It Pa sys.mk
+system makefile
+.It Pa /usr/share/mk
+default system makefile directory
+.It Pa /usr/share/doc/psd/12.make
+PMake tutorial
+.It Pa /usr/obj
+default
+.Ev MAKEOBJDIRPREFIX
+directory.
+.It Pa /etc/make.conf
+default path to
+.Xr make.conf 5
+.El
+.Sh EXAMPLES
+List all included makefiles in order visited:
+.Pp
+.Dl "make -V .MAKEFILE_LIST | tr \e\ \e\en"
+.Sh COMPATIBILITY
+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 SEE ALSO
+.Xr mkdep 1 ,
+.Xr make.conf 5
+.Rs
+.%T "PMake - A Tutorial"
+.Re
+in
+.Pa /usr/share/doc/psd/12.make
+.Sh HISTORY
+A
+.Nm
+command appeared in PWB UNIX.
+.Sh BUGS
+The determination of
+.Va .OBJDIR
+is contorted to the point of absurdity.
+.Pp
+In the presence of several
+.Ic .MAIN
+special targets,
+.Nm
+silently ignores all but the first.
+.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 very simple-minded.
+Currently, the only form that works is
+.Ql .if ${VAR} op something
+For instance, you should write tests as
+.Ql .if ${VAR} == "string"
+not the other way around, which would give you an error.
+.Pp
+For loops are expanded before tests, so a fragment such as:
+.Bd -literal -offset indent
+\&.for ARCH in ${SHARED_ARCHS}
+\&.if ${ARCH} == ${MACHINE}
+ ...
+\&.endif
+\&.endfor
+.Ed
+.Pp
+will not work, and should be rewritten as:
+.Bd -literal -offset indent
+\&.for ARCH in ${SHARED_ARCHS}
+\&.if ${MACHINE} == ${ARCH}
+ ...
+\&.endif
+\&.endfor
+.Ed
+.Pp
+The parsing code is broken with respect to handling a semicolon
+after a colon, so a fragment like this will fail:
+.Bd -literal -offset indent
+HDRS= foo.h bar.h
+
+all:
+\&.for h in ${HDRS:S;^;${.CURDIR}/;}
+ ...
+\&.endfor
+.Ed
+.Pp
+A trailing backslash in a variable value defined on the command line causes
+the delimiting space in the
+.Ev MAKEFLAGS
+environment variable to be preceded by that backslash.
+That causes a submake to not treat that space as a word delimiter.
+Fixing this requires a larger rewrite of the code handling command line
+macros and assignments to
+.Va .MAKEFLAGS .