diff options
Diffstat (limited to 'static/freebsd/man1/bmake.1')
| -rw-r--r-- | static/freebsd/man1/bmake.1 | 2927 |
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 |
