1
0
Files
irix-657m-src/eoe/cmd/pmake/doc/pmake.1
2022-09-29 17:59:04 +03:00

1968 lines
60 KiB
Groff

'\"macro stdmacro
'\" Id: pmake.mansp,v 1.4 89/01/21 18:34:36 adam Exp $ SPRITE (Berkeley)
'#
'#---Start of mansp macros
'# Header: tmac.ansp.doc,v 1.12 86/07/11 08:11:34 ouster Exp $ SPRITE (Berkeley)
'# Troff/Nroff macros for Sprite manual pages
'# default tabs - set tabs every half inch
.de DT
'ta .5i 1i 1.5i 2i 2.5i 3i 3.5i 4i 4.5i 5i 5.5i 6i 6.5i
..
'# set title and heading, initialize parameters
'# NAME section heading
'.de NA
'.SH "NAME"
'..
'# SYNOPSIS section heading
.de SY
.br
.SH "SYNOPSIS"
.nf
..
'# ARGUMENTS section heading
.de AR
.br
.fi
.SH "ARGUMENTS"
..
'# OPTIONS section heading
.de OP
.br
.fi
.SH "OPTIONS"
..
'# define tabbing values for .AP
.de AS
.nr )A 8n
.if !"\\$1"" .nr )A \\w'\\$1'u+2n
.nr )B \\n()Au+10n
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+2n
..
'# special .IP used for printing command/procedure args
.de AP
.ie !"\\$4"" .TP \\$4 0v
.el \{\
. ie !"\\$2"" .TP \\n()Cu 0v
. el .TP 15 0v
.\}
.ie !"\\$3"" \{\
.ta \\n()Au \\n()Bu
\&\\$1 \\f2\\$2\\fP (\\$3)
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1 \\f2\\$2\\fP
.\}
.el \{\
\&\\f2\\$1\\fP
.\}
.\}
.DT
..
'#---End of mansp macros
.de Pm
.ie \\n(.$ .BR pmake \\$1
.el .B pmake
..
.if n .nr #D 3n
.if t .nr #D .5i
.if n .ds -> \->
.if t .ds -> \(->
.de DS \" Real Display-Start macro. It actually works!
.sp .5v
.nf
.in +\\n(#Du
..
.de DE \" Real Display-End macro.
.in
.fi
.sp .5v
..
.TH PMAKE 1
.BS
.SH NAME
pmake, smake \- create programs in parallel
.SY
.HP
.fi
.B pmake
[\c
.B \-d
.I what\c
] [\c
.B \-e\c
] [\c
.B \-f
.I makefile\c
] [\c
.B \-h\c
] [\c
.B \-i\c
] [\c
.B \-k\c
] [\c
.B \-l\c
] [\c
.B \-n\c
] [\c
.B \-p
.I #\c
] [\c
.B \-q\c
] [\c
.B \-r\c
] [\c
.B \-s\c
] [\c
.B \-t\c
] [\c
'\".B \-x\c
'\"] [\c
.B \-v\c
] [\c
.B \-B\c
] [\c
.B \-C\c
] [\c
.B \-D
.I variable\c
] [\c
.B \-I
.I directory\c
]
.br
[\c
.B \-J
.I #\c
] [\c
.\" .B \-L
.\" .I #\c
.\" ] [\c
.B \-M\c
] [\c
.B \-P\c
] [\c
.B \-V\c
] [\c
.B \-W\c
] [\c
'\".B \-X\c
'\"] [\c
.IB VAR1 = value1\c
] [\c
.IB VAR2 = value2 ...\c
] [\c
.I targ1\c
] [\c
.I targ2 ...\c
]
.BE
.AR
.AS \-I directory
.AP \-d what
Specify what modules should print debugging information.
.I what
is a string of letters from the following set:
a, c, d, j, m, s, t, v. Use A or * to print all information.
.AP \-e "\&"
Give environment variables precedence over those in the makefile(s).
.AP \-f makefile
Specify a different makefile to read than the standard
``Makefile'' or ``makefile''. If
.I makefile
is "\-", standard input is read.
.AP \-h "\&"
Prints out help information and default values.
.AP \-i "\&"
``Ignore errors'' \(em ignore non-zero exit statuses of commands.
.AP \-k "\&"
``Keep-going'' \(em if an error is encountered,
keep working on those parts of the input graph that are not affected by the
error.
.AP \-l "\&"
Create a lock file (called ``LOCK.make'') to prevent other
people from executing
.Pm
in the same directory.
Useful when simultaneous makes in the same place can be disastrous
for the final product (too many cooks and all that).
Note that this locking will not
prevent \f2you\fP from invoking
.Pm
twice in the same place \(em if
you own the lock file,
.Pm
will warn you about it but continue to execute.
.AP \-n "\&"
``No execute'' \(em do not execute commands.
Just print the ones that would be executed.
.AP \-p "#"
Tell
.Pm
if and when to print the input graph.
The number is the bitwise OR of the numbers 1 and 2. 1 means print the
graph before making anything and 2 means print the graph after making
everything. 3 means do both.
.AP \-q "\&"
``Query'' \(em do not execute any commands.
Just exit 0 if the given target(s) is (are) up to date and exit non-zero
otherwise.
.AP \-r "\&"
``Remove built-in rules'' \(em do not parse the built-in rules given in
the system makefile.
.AP \-s "\&"
``Silence'' \(em do not echo commands as they are executed.
.AP \-t "\&"
``Touch targets'' \(em rather than executing the commands to create a target,
just change its modification time so it appears up-to-date.
This is dangerous.
'\" .AP \-x "\&"
'\" ``Export'' \(em causes commands to be exported when in
'\" Make-compatibility mode. Since exporting commands in this mode will
'\" often take longer than running them on the local machine, exportation
'\" is off by default and must be turned on using this flag.
.AP \-v "\&"
``System V'' \(em invokes compatibility functions suitable for acting
like the System V (IRIX) version of
.BR make (1).
This implies
.BR \-B ,
and
.BR \-V .
Automatically set when
.Pm
is invoked as \f4smake\fP.
.AP \-B "\&"
``Backwards-compatible'' \(em performs as much like
.BR make (1)
as possible
(including executing a single shell per command and expanding
variables as
.B make
did) while still performing in parallel.
.AP \-C "\&"
``Non-compatible'' \(em turns off all compatibility specified up to the point at
which
.B \-C
is encountered.
.AP \-D variable
Defines the given variable to be
.B 1
in the global context.
.AP \-I directory
Specify another directory in which to look for #include'd makefiles.
This flag may be repeated as many times as necessary.
.AP \-J #
Specify the maximum number of jobs to run at once.
.\" on all machines.
.\" .AP \-L #
.\" Specify the maximum number of jobs to run locally.
.AP \-M "\&"
Be as much like
.BR make (1)
as possible. No parallel execution. Old-style
variable expansion. One shell per command, etc.
.AP \-P "\&"
``Don't use Pipes'' \(em see the section on
.BR OUTPUT .
.AP \-V "\&"
``Do old-style variable expansion'' \(em expands an unknown variable to
the empty string.
.AP \-W "\&"
Don't print warning messages.
'\" .AP \-X "\&"
'\" ``No Export'' \(em prohibits exportation. \-x and \-X should not be used
'\" in the same command.
.AP VAR=value "\&"
Set the value of the variable
.B VAR
to the given value.
This supersedes any value assigned to the variable in the makefile.
See
.BR VARIABLES .
.P
.B smake
is equivalent to
.BR "pmake \-v" .
.P
The flags \-x, \-X and \-L are recognized but ignored by this
implementation of
.Pm .
.br
.ne 5
.SH DESCRIPTION
.Pm
is a program designed to make the maintenance of other programs much
easier.
Its input is a ``makefile'' that specifies which files depend
on which other files and what to do about files that are
``out-of-date.''
.Pm 's
most important feature is its ability to run
several different jobs at once, making the creation of systems
considerably faster. It also has a great deal more functionality than
.BR make (1).
.PP
.Pm
is generally compatible with
.BR make (1).
The main differences\ are:
.IP 1) 3
The
.Pm
variable substitution, as described below, is very different and
will cause problems unless the makefile is converted or the
.B \-V
flag is given or when
.Pm
is invoked
as \f4smake\fP.
.IP 2)
Because
.Pm
creates targets in parallel, certain sequences which
depend on the sources of a target being created sequentially will fail.
For example:
.DS
prod : $(PROGRAM) clean
.DE
This is liable to cause some of the object files to be removed after
having been created during the current invocation (or, at the very
least, the object files will not be removed when the program has been
made), leading to errors in the final linking stage. This problem
cannot even be avoided by limiting the maximum concurrency to
one, since the traversal of the dependency graph is done in a
breadth-first, rather than a depth-first way.
For
.BR make (1)
behavior, rewrite the makefile, or give
.Pm
the
.B \-M
flag.
.IP 3)
.Pm
forks only one shell to execute the commands to recreate a target.
This means that changes of directory, environment, etc., remain in
effect throughout the creation process. It also allows for a more
natural entry of shell loop constructs
without the need for backslashes and
semicolons required by the one-shell-per-command paradigm used by
.BR make (1).
It is possible to have
.Pm
execute each command in a single shell by giving it the
.B \-B
flag.
.IP 4)
.Pm
strips the leading directory from the files in a target's local
variables, unlike
.BR make (1).
For example,
.Pm
looks in the current directory for file.c when making gen/file.o:
.DS
default: gen/file.o
\&.c.o:
cc \-c\ \ \-o\ \ $@\ \ $<
.DE
To have
.Pm
look in the gen directory for file.c,
add a ``.PATH: gen'' target to the makefile. The
.B .PATH
target, which is described below, is ignored by
.BR make (1).
Note that
.Pm
in system V (IRIX) compatibility mode will not strip leading directories.
.IP 5)
.Pm
can interpret a comment line that begins with ``# if'' as a conditional
statement. Duplicate the comment character before the line to avoid
a warning message.
.IP 6)
.Pm
doesn't have
.BR make (1)'s
tilde rules for SCCS files.
.IP 7)
.Pm
only understands the i,k,n,q,r,s,t, and u options in
.BR make 's
MAKEFLAGS environment variable. The other
.B make
options are ignored due to
differences in semantics.
.IP 8)
.Pm
converts an escaped newline into a space.
.br
.ne 10
.SH MAKEFILES
.PP
If you don't specify a makefile to read,
.Pm
looks for
.B Makefile
in the current directory.
If that file does not exist, it looks for
.BR makefile .
(This search order is reversed for \f4smake\fP or when using the
.B \-M
flag.)
.PP
There are four basic types of lines in a makefile:
.IP 1) 3
File dependency specifications
.IP 2)
Creation commands
.IP 3)
Variable assignments
.IP 4)
Comments,
include statements and conditional directives
.PP
Any line may be continued over multiple lines by ending it with a backslash.
The backslash,
following newline and any initial white-space on the following line are
compressed into a single space.
.SH DEPENDENCY LINES
.PP
On a dependency line, there are targets, sources and an operator.
The targets ``depend'' on the sources and are usually created from them.
Any number of targets and sources may be specified on a dependency
line. All the targets in the line are made to depend on all the sources.
If you run out of room, use a backslash at the end of the line to
continue onto the next one.
.PP
Any file may be a target and any file may be a source, but the relationship
between them is determined by the ``operator''
that separates them. Three operators are defined:
.RS
.IP ":"
A target on the line is considered ``out-of-date''
if any of its sources has been modified
more recently than the target. Sources for a target accumulate over
lines when this operator is used.
.IP "!"
Targets will always be recreated, but this will not happen until all
of its sources have been examined and recreated, if necessary.
Sources accumulate over lines as for the colon.
.IP "::"
Much like the colon, but acts like the ! operator if no sources are
specified. In addition sources do not accumulate over lines. Rather,
the commands associated with the line (see below) are executed only if
the target is out-of-date with respect to the sources on that line only.
In addition, the target will not be removed if
.Pm
is interrupted, unlike for the other two operators.
.RE
.PP
For example:
.DS
a : a.o b.o c.o
b ! d.o e.o
c :: f.o
command1
a : g.o
b ! h.o
c ::
command2
.DE
specifies that a depends on a.o, b.o, c.o and g.o and will be remade
only if out-of-date with respect to these four files. b depends on
d.o, e.o and h.o and will always be remade, but only after these three
files have been remade. c will be remade with command1 if it is
out-of-date with respect to f.o, as for the colon operator, while
command2 will always be executed.
.PP
Targets and sources may also contain standard shell wildcard
characters (?, *, [ and {}), but the ?, *, [ and ] characters may only
be used in the final component of the target or source. If a target or
source contains only curly braces and no other wildcard characters, it
need not describe an existing file. Otherwise, only existing files
will be used. For example, the pattern
.DS
{a,b,c}.o
.DE
will expand to
.DS
a.o b.o c.o
.DE
regardless of whether these three files exist, while
.DS
[abc].o
.DE
will only expand to this if all three files exist. The resulting
expansion is in directory order, not alphabetically sorted as in the shell.
.SH COMMANDS
.PP
Associated with each target is a series of shell commands, collectively
called a script. The creation script for a target should
immediately follow the dependency line for that target.
Each of the commands in this script
.I must
be preceded by a tab character.
.PP
While any given target
may appear on more than one dependency line, only one of these dependency lines
may be followed by a creation script, unless the "::" operator is used.
.PP
One helpful feature of
.Pm
is the ability to delay execution of a target's commands until
everything else has been done. To do this, make one of the commands
for the target be just ``.\|.\|.'' (an ellipsis) on a line by itself. The
ellipsis itself won't be executed, of course, but any commands in the
target's script that follow the ellipsis will be saved until
.Pm
is done processing everything it needs to process.
If you were to say,
.DS
a.o : a.c
cc\ \ \-c\ \ a.c
.\|.\|.
@echo "All done"
.DE
Then the command ``echo "All done"'' would execute once everything
else had finished. Note that this will only happen if ``a.o'' is found
to be out-of-date.
Macros and variables in these delayed commands are evaluated once
at the time they would have executed and again when (at the end) they are
actually executed.
This means that shell variables, which usually must be escaped with a
`$' (as in `$$i') must now be escaped twice (as in `$$$$i').
.PP
There is another way in which makefile shell commands differ from
regular shell commands, as illustrated in the previous example.
The first two characters after the initial tab (and any other
white-space) are treated specially. If they are any combination of `@'
and `\-', (``@'', ``@\-'', ``\-@'' or ``\-''), they cause
.Pm
to do different things.
.PP
In most cases, shell commands are printed to
the screen before they're actually executed. This is to keep you
informed of what's going on. If an `@' appears, however, this echoing
is suppressed. In the case of the echo command, above, this makes
sense. It would look silly to see
.DS
echo "All done"
All done
.DE
so
.Pm
allows you to avoid that (this sort of echo control is
only available if you use the Bourne or C shells to execute your
commands, since the commands are echoed by the shell,
not by
.Pm ).
.PP
The other special character is the `\-'. Shell commands exit with a
certain ``exit status.'' Normally this status will be 0 if everything
went ok and non-zero if something went wrong. For this reason,
.Pm
will consider an error to have occurred if one of the commands it
invokes returns a non-zero status. When it detects an error, its usual
action is to stop working, wait for everything in process to finish,
and exit with a non-zero status itself. This behavior can be altered,
however, by means of
.B \-i
or
.B \-k
arguments, or by placing a `\-' at the
front of the command.
(Another quick note: the decision of whether to abort a target when
one of its shell commands returns non-zero is left to the shell that
is executing the commands. Some shells allow this ``error-checking''
to be switched on and off at will while others do not.)
.SH VARIABLES
.PP
.Pm
has the ability to save text in variables to be recalled later at your
convenience. Variables in
.Pm
are used much like variables in
.IR sh (1)
and, by tradition, consist of all upper-case letters.
(They can also contain lower-case letters, numbers, and
punctuation characters except =, :, ) and }. # must be preceded with
a backslash).
They are assigned- and appended-to using lines of the form
.DS
\f2VARIABLE\fP \f3=\fP \f2value\fP
\f2VARIABLE\fP \f3+=\fP \f2value\fP
.DE
respectively, while being conditionally assigned-to (if not already
defined) and assigned-to with expansion by lines of the form
.DS
\f2VARIABLE\fP \f3?=\fP \f2value\fP
\f2VARIABLE\fP \f3:=\fP \f2value\fP
.DE
With \f3:=\fP, any variable on the right-hand side will be replaced
with its current definition. Put at least one blank between the
end of the variable name and the assignment operator.
Finally,
.DS
\f2VARIABLE\fP \f3!=\fP \f2command\fP
.DE
will execute
.I command
using the Bourne shell and place the result in the given variable.
Newlines are converted to spaces before the assignment is made. This
is not intended to be used with commands that produce a large amount
of output. If you use it this way,
.Pm
will probably deadlock.
A particularly useful example of this is:
.DS
OSVERS!=uname -r | sed 'y/\\./\\_/' | cut -c1-3
.DE
.sp
which will set the variable \f4OSVERS\fP to the major and minor release
of the current system, separated by an underscore.
.PP
Variables are expanded by enclosing the variable name in either
parentheses or curly braces and preceding the whole thing with a
dollar sign. For example, to set the variable
.B CFLAGS
to the string ``\-I../hdrs\ \ \-O'' place the line
.DS
CFLAGS = \-I../hdrs\ \ \-O
.DE
in the makefile and use the word
.B $(CFLAGS)
wherever you would like the string ``\-I../hdrs\ \ \-O'' to
appear. To pass a string of the form ``$(\f2name\fP)'' or
``${\f2name\fP}'' through to the shell (e.g., to tell it to substitute
one of its variables),
you can use ``$$(\f2name\fP)'' and ``$${\f2name\fP}'',
respectively,
or,
as long as the \f2name\fP is not a
.Pm
variable,
you can just place the string in directly, as
.Pm
will not expand a variable it doesn't know, unless it is given one of
the three compatibility flags
.BR \-V ,
.BR \-B ,
or
.BR \-M ,
or invoked as \f4smake\fP.
.PP
There are two distinct times at which variable substitution occurs:
When parsing a dependency line,
such substitution occurs immediately upon reading the line.
Thus all variables used in dependency lines must be defined before
they appear on any dependency line.
For variables that appear in shell commands,
variable substitution occurs when the command is processed,
that is, when it is prepared to be passed to the shell or before being
saved for later execution (see \f3COMMANDS\fP above).
.PP
There are four different types of variables at which
.Pm
will look when trying to expand any given variable.
They are (in order of decreasing precedence): (1) variables that are
defined specific to a certain target. These are the so-called
``local'' variables and will only be used when performing variable
substitution on the target's shell script and in dynamic sources (see below
for more details), (2) variables that were defined on the command line,
(3) variables defined in the makefile and (4) those defined in
.Pm 's
environment, as passed by your login shell.
An important side effect of this searching order is that once you
define a variable on the command line, \f2nothing\fP in the makefile can
change it.
.PP
The \f4SHELL\fP macro is treated specially. It is automatically
set by
.Pm
at the start to be \f2/bin/sh\fP.
The value of the environment variable \f4SHELL\fP does not affect
the value of the \f4SHELL\fP macro.
If the \f4SHELL\fP macro is defined in the makefile or on the command line
it replaces the original value (and changes the shell used for all commands),
but does NOT affect the \f4SHELL\fP environment variable.
.PP
As mentioned above,
each target has associated with it as many as seven ``local''
variables. Four of these variables are always set for every target
that must be recreated. Each local variable has a long, meaningful
name and a short, one-character name that exists for backwards-compatibility.
They are:
.RS
.IP ".TARGET\ \ (@)" 20
The name of the target.
.IP ".OODATE\ \ (?)" 20
The list of sources for this target that were deemed out-of-date.
.IP ".ALLSRC\ \ (>)" 20
The list of all sources for this target.
.IP ".PREFIX\ \ (*)" 20
The file prefix of the file. This contains only the file portion \- no
suffix or leading directory components.
.RE
.PP
Three other ``local'' variables are set only for certain targets under
special circumstances. These are the ``.IMPSRC'', ``.ARCHIVE''
and ``.MEMBER'' variables. When
they are set, how they are used, and what their short forms are detailed
in later sections.
.PP
In addition, for System V Make compatibility, the variables ``@F'', ``<F'', and
``*F'' are defined as the file parts of the ``@'', ``>'' and ``*'' variables.
Likewise, ``@D'', ``<D'', and ``*D'' are directory parts.
.PP
Four of these local variables may be used in sources on dependency
lines. The variables expand to the proper value for each target on the
line. The variables are ``.TARGET'', ``.PREFIX'', ``.ARCHIVE'', and
``.MEMBER''.
.PP
In addition, certain variables are set by or have special meaning to
.Pm .
The
.B .PMAKE
(and
.BR MAKE)
variable is set to the name by which
.Pm
was invoked, to allow recursive makes to use the same version,
whatever it may be.
All command-line flags given to
.Pm
are stored in the
.B .MAKEFLAGS
(and
.BR MFLAGS)
variable just as they were given. This variable is also exported to
subshells as the
.B PMAKE
environment variable.
.PP
Variable expansion may be modified as for the C shell. A general
expansion specification looks like:
.DS
\f3$(\fP\f2variable\fP[\f3:\fP\f2modifier\fP[\f3:\fP...]]\f3)\fP
.DE
Each modifier begins with a single character, thus:
.RS
.IP "M\f2pattern\fP"
This is used to select only those words (a word is a series of
characters that are neither spaces nor tabs) that match the given
.I pattern .
The pattern is a wildcard pattern like that used by the shell, where "*"
means 0 or more characters of any sort; "?" is any single character;
"[abcd]" matches any single character that is either `a', `b', `c' or `d'
(there may be any number of characters between the brackets);
.B [0-9]
matches any single character that is between `0' and `9' (i.e., any
digit. This form may be freely mixed with the other bracket form), and
\&\e is used to escape any of the characters "*", "?", "[" or ":",
leaving them as regular characters to match themselves in a word.
For example, the system makefile
<makelint.mk>
uses
$(CFLAGS:M\-[ID]*)
to extract all the
.B \-I
and
.B \-D
C compiler flags for
.IR lint .
.IP "N\f2pattern\fP"
This is identical to ":M" except it substitutes all words that don't
match the given pattern.
.IP "S/\f2search-string\fP/\f2replacement-string\fP/[g]"
Causes the first occurrence of
.I search-string
in the variable to be replaced by
.IR replacement-string ,
unless the "g"
flag is given at the end, in which case all occurrences of the string
are replaced. The substitution is performed on each word in the
variable in turn. If
.I search-string
begins with a "^",
the string must match starting at the beginning of the word. If
.I search-string
ends with a "$",
the string must match to the end of the word (these two may be
combined to force an exact match). If a backslash precedes these two
characters, however, they lose their special meaning. Variable
expansion also occurs in the normal fashion inside both the
.I search-string
and the
.IR replacement-string ,
.B except
that a backslash is used to prevent the expansion of a "$",
not another dollar sign, as is usual.
Note that
.I search-string
is just a string, not a pattern, so none of the usual
regular-expression/wildcard characters has any special meaning save "^"
and "$".
In the replacement string,
the "&"
character is replaced by the
.I search-string
unless it is preceded by a backslash.
You are allowed to use any character except
colon or exclamation point to separate the two strings. This so-called
delimiter character may be placed in either string by preceding it
with a backslash.
.IP T
Replaces each word in the variable expansion by its last
component (its ``tail'').
For example, given
.DS
OBJS = ../lib/a.o b /usr/lib/libm.a
TAILS = $(OBJS:T)
.DE
the variable
TAILS
would expand to
``a.o\ \ b\ \ libm.a''.
.IP H
This is similar to ":T",
except that every word is replaced by everything but the tail (the
``head'').
Using the same definition of OBJS from above, the string ``$(OBJS:H)''
would expand to ``../lib\ \ /usr/lib''.
Note that the final slash on the heads is removed and
anything without a head is replaced by the empty string.
.IP E
":E" replaces each word by its suffix (``extension'').
For example, ``$(OBJS:E)'' would give you ``.o\ \ .a''.
.IP R
This replaces each word by everything but the suffix (the ``root'' of
the word).
For example, ``$(OBJS:R)'' would give you ``../lib/a\ \ b\ \ /usr/lib/libm''.
.RE
.PP
In addition,
.Pm
supports the System V form of substitution
.DS
\f3$(\f2variable\f3:\f2string1\f3=\f2string2\f3)\f1
.DE
.br
\f1where all occurrences of \f2string1\fP
at the end of each word in the variable expansion are replaced by \f2string2\fP.
.br
.ne 5
.SH COMMENTS, INCLUSION AND CONDITIONALS
.PP
Makefile inclusion and conditional structures reminiscent of
the C compiler have also been included in
.Pm .
.PP
Comments begin with a `#' anywhere but in a shell command and continue
to the end of the line. The comment character can included in macros
if preceded with a backslash (\e).
If the `#' comes at the beginning of the line, however, the following
keywords are recognized and acted on:
.SS #include """\f2makefile\fP"""
.SS #include "<\f2system makefile\fP>"
.PP
This is very similar to the C compiler's file-inclusion facility,
right down to the syntax. What follows the
.B #include
must be a filename enclosed either in double-quotes or angle brackets.
Variables will be expanded between the double-quotes or
angle-brackets. If angle-brackets are used, the system makefile
directory is searched. If the name is enclosed in double-quotes, the
including makefile's directory, followed by all directories given via
.B \-I
arguments, followed by the system directory, is searched for a
file of the given name.
.PP
If the file is found,
.Pm
starts taking input from that file as if it were part of the original
makefile.
.PP
When the end of the file is reached,
.Pm
goes back to the previous file and continues from where it left off.
This facility is recursive up to a depth limited only by the number of open
files allowed to any process at one time.
.SS include \f2makefile\fP
.SS sinclude \f2makefile\fP
This (non-standard) include syntax is recognized for compatibility with the
IRIX
.BR make (1)
command.
No search paths are used.
The file name may contain variables.
For ``include'', it is a fatal error if the file is not readable;
for ``sinclude'', a non-readable file is silently ignored.
.SS "#if [!] \f2expr\fP [ \f2op\fP \f2expr\fP ... ]"
.SS #ifdef [!] \f2variable\fP [\f2op\fP \f2variable\fP...]
.SS #ifndef [!] \f2variable\fP [\f2op\fP \f2variable\fP...]
.SS #ifmake [!] \f2target\fP [\f2op\fP \f2target\fP...]
.SS #ifnmake [!] \f2target\fP [\f2op\fP \f2target\fP...]
.PP
These are all the beginnings of conditional constructs in the spirit of
the C compiler.
Conditionals may be nested to a depth of thirty.
.PP
In the expressions given above,
.I op
may be either \f3||\fP (logical \s-2OR\s0) or \f3&&\fP (logical
\s-2AND\s0).
.B &&
has a higher precedence than
.BR || .
As in C,
.Pm
will evaluate an expression only as far as necessary to determine its
value. If the left side of an
.B &&
is false, the expression is false and vice versa for
.BR || .
Parentheses may be used as usual to change the order of evaluation.
.PP
One other boolean operator is provided: \f3!\fP (logical negation). It
is of a higher precedence than either the \s-2AND\s0 or \s-2OR\s0 operators,
and may be applied in any of the ``if'' constructs,
negating the given function for ``#if'' or the implicit function for
the other four.
.PP
.I Expr
can be one of several things. Four functions are provided, each of
which takes a different sort of argument.
.PP
The function
.I defined
is used to test for the existence of a variable.
Its argument is, therefore, a variable name.
Certain variable names (e.g., ``IRIX'', ``SYSV'', and ``unix'')
are defined in the system makefile (see \f3FILES\fP) to
specify the sort of system on which
.Pm
is being run. These are intended to make makefiles more portable.
Any variable may be used as the argument of the
.B defined
function.
.PP
The
.B make
function is given the name of a target in the makefile and evaluates
to true if the target was given on
.Pm 's
command-line or as a source for the
.B .MAIN
target before the line containing the conditional.
.PP
The
.I exists
function takes a file name, which file is searched for on the system
search path (as defined by
.B .PATH
targets (see below)). It evaluates true if the file is found.
.PP
The function
.I empty
takes a variable expansion specification (minus the dollar sign) as
its argument. If the resulting expansion is empty, this evaluates
true.
.PP
.I Expr
can also be an arithmetic or string comparison, with the left-hand side
being a variable.
The standard C relational operators are
allowed, and the usual number/base conversion is performed, with the
exception that octal numbers are not supported. If the right-hand side
of a "==" or "!=" operator begins with a quotation mark, a string
comparison is done between the expanded variable and the text between
the quotation marks.
.PP
If no relational operator is given, the expression must be a single variable,
which is interpreted as a boolean. If the variable evaluates to
a 0 value, the expression is false and
if it evaluates to a non-zero value, the expression is true.
.PP
When, in the course of evaluating one of these conditional
expressions,
.Pm
encounters some word it does not recognize, it applies one of either
.I make
or
.I defined
to it, depending on the form of ``if'' used. For example, ``#ifdef'' will
apply the
.I defined
function, while ``#ifnmake'' will apply the negation of the
.I make
function.
.PP
If the expression following one of these forms evaluates true, the
reading of the makefile continues as before. If it evaluates false,
the following lines are skipped. In both cases, this continues until
either an
.B #else
or an
.B #endif
line is encountered.
.SS #else
.PP
The #else,
as in the C compiler,
causes the sense of the last conditional to be inverted and the reading of
the makefile to be based on this new value,
i.e., if the previous expression evaluated true,
the parsing of the makefile is suspended until an #endif line is read.
If the previous expression evaluated false,
the parsing of the makefile is resumed.
.SS "#elif [!] \f2expr\fP [ \f2op\fP \f2expr\fP ... ]"
.SS #elifdef [!] \f2variable\fP [\f2op\fP \f2variable\fP...]
.SS #elifndef [!] \f2variable\fP [\f2op\fP \f2variable\fP...]
.SS #elifmake [!] \f2target\fP [\f2op\fP \f2target\fP...]
.SS #elifnmake [!] \f2target\fP [\f2op\fP \f2target\fP...]
.PP
The ``elif'' constructs are a combination of ``else'' and ``if,'' as
the name implies. If the preceding ``if'' evaluated false, the
expression following the ``elif'' is evaluated and the lines following
it are read or ignored the same as for a regular ``if.''
If the preceding ``if'' evaluated true, however, the ``elif'' is
ignored and all following lines until the ``endif'' (see below) are ignored.
.SS #endif
.PP
.B #endif
is used to end a conditional section. If lines were being skipped, the
reading of the makefile resumes. Otherwise, it has no effect (the
makefile continues to be parsed as it was just before the
.B #endif
was encountered).
.SS #undef
.PP
Takes the next word on the line as a global variable to be undefined
(only undefines global variables, not command-line variables). If the
variable is already undefined, no message is generated.
.SH TARGET ATTRIBUTES
.PP
In
.Pm ,
files can have certain ``attributes.''
These attributes cause
.Pm
to treat the targets in special ways. An attribute is a special word
given as a source to a target on a dependency line.
The words and their functions are given below:
.nr pw \w'.EXPORTSAMExx'u
.IP .DONTCARE \n(pwu
If a target is marked with this attribute and
.Pm
can't figure out
how to create it, it will ignore this fact and assume the file isn't
really needed or actually exists and
.Pm
just can't find it.
(\f4.OPTIONAL\fP is a synonym for \f4.DONTCARE\fP.)
.IP .EXEC \n(pwu
This causes the marked target's shell script to always be executed
(unless the
.B \-n
or
.B \-t
flag is given), but appear invisible to any targets that depend on it.
.IP .IGNORE \n(pwu
Giving a target the
.B .IGNORE
attribute causes
.Pm
to ignore errors from any of the target's commands, as
if they all had `\-' before them.
.IP .INVISIBLE \n(pwu
This allows you to specify one target as a source for another without
the one affecting the other's local variables.
.IP .JOIN \n(pwu
This forces the target's shell script to be executed only if one or more of the
sources was out-of-date. In addition, the target's name,
in both its
.B .TARGET
variable and all the local variables of any target that depends on it,
is replaced by the value of its
.B .ALLSRC
variable.
Another aspect of the \f4.JOIN\fP attribute is it keeps the target from
being created if the
.B \-t
flag was given.
.IP .MAKE \n(pwu
The
.B .MAKE
attribute marks its target as being a recursive invocation of
.Pm
\&.
This forces
.Pm
to execute the script associated with
the target (if it is out-of-date) even if you gave the
.B \-n
or
.B \-t
flag.
.IP .NOTMAIN \n(pwu
Normally, if you do not specify a target to make in any other way,
.Pm
will take the first target on the first dependency line of a
makefile as the target to create.
Giving a target this attribute keeps it from this fate.
.IP .PRECIOUS \n(pwu
When
.Pm
is interrupted, it
will attempt to clean up after itself by removing any half-made
targets. If a target has this attribute, however,
.Pm
will leave it alone
.IP .SILENT \n(pwu
Marking a target with this attribute keeps its commands from being
printed when they're executed.
.IP .USE \n(pwu
By giving a target this attribute, you turn the target into
.Pm 's
equivalent of a macro. When the target is used as a source for another target,
the other target acquires the commands, sources and attributes (except
.BR .USE )
of the source.
If the target already has commands, the
.B .USE
target's commands are added to the end. If more than one \f4.USE\fP-marked
source is given to a target, the rules are applied sequentially.
.PP
The following target attributes are recognized but not implemented on
IRIX: .EXPORT, .EXPORTSAME, and .NOEXPORT.
.\".IP .EXPORT \n(pwu
.\"This is used to mark those targets whose creation should be sent to
.\"another machine if at all possible. This may be used by some
.\"exportation schemes if the exportation is expensive. You should ask
.\"your administrator if it is necessary.
.\".IP .EXPORTSAME \n(pwu
.\"Tells the export system that the job should be exported to a machine
.\"of the same architecture as the current one. Certain operations (e.g.,
.\"running text through
.\""nroff")
.\"can be performed the same on any architecture (CPU and
.\"operating system type), while others (e.g., compiling a program with
.\""cc")
.\"must be performed on a machine with the same architecture. Not all
.\"export systems will support this attribute.
.\".IP .NOEXPORT \n(pwu
.\"Forces the target to be created locally, even if you've given
.\".Pm
.\"the
.\".B "\-L 0"
.\"flag.
.SH SPECIAL TARGETS
.PP
As there were in
.BR make (1),
so there are certain targets that have special meaning to
.Pm
\&. When you use one on a dependency line, it is the
only target that may appear on the left-hand-side of the operator.
The targets are as follows:
.nr pw \w'.MAKEFLAGSxx'u
.IP .BEGIN \n(pwu
.Ix 0 def .BEGIN
Any commands attached to this target are executed before anything else
is done. You can use it for any initialization that needs doing.
.IP .DEFAULT \n(pwu
This is sort of a .USE rule for any target (that was used only as a
source) that
.Pm
can't figure out any other way to create. Only the shell script is used. The
.B .IMPSRC
variable of a target that inherits \f3.DEFAULT\fP's
commands is set to the target's own name.
.IP .END \n(pwu
This serves a function similar to
.BR .BEGIN :
commands attached to it are executed once everything has been
recreated (so long as no errors occurred). It also serves the extra
function of being a place on which
.Pm
can hang commands you put off
to the end. Thus the script for this target will be executed before
any of the commands you save with the ``.\|.\|.''.
.\".IP .EXPORT \n(pwu
.\"The sources for this target are passed to the exportation system compiled
.\"into
.\".Pm .
.\"Some systems will use these sources to configure
.\"themselves. You should ask your system administrator about this.
.IP .IGNORE \n(pwu
This target marks each of its sources with the
.B .IGNORE
attribute. If you don't give it any sources, then it is like
giving the
.B \-i
flag.
.IP .INCLUDES \n(pwu
The sources for this target are taken to be suffixes that indicate a
file that can be included in a program source file.
The suffix must have already been declared with
.B .SUFFIXES
(see below).
Any suffix so marked will have the directories on its search path
(see
.BR .PATH ,
below) placed in the
.B .INCLUDES
variable, each preceded by a
.B \-I
flag.
The
.B .h
suffix is already marked in this way in the system makefile.
.IP .INTERRUPT \n(pwu
When
.Pm
is interrupted,
it will execute the commands in the script for this target, if it
exists.
.IP .LIBS \n(pwu
This does for libraries what
.B .INCLUDES
does for include files, except the flag used is
.BR \-L ,
as required by those linkers that allow you to tell them where to find
libraries. The variable used is
.BR .LIBS .
.IP .MAIN \n(pwu
If you didn't give a target (or targets) to create when you invoked
.Pm
, it will take the sources of this target as the targets to
create.
.IP .MAKEFLAGS \n(pwu
This target provides a way for you to always specify flags for
.Pm
when the makefile is used. The flags are just as they would be typed
to the shell,
though the
.B \-f
and
.B \-r
flags have no effect.
.IP .NOTPARALLEL \n(pwu
This is used to make only one target at a time.
It is equivalent to giving the
.B \-J " 1"
flag.
.IP .NULL \n(pwu
This allows you to specify what suffix
.Pm
should pretend a file has if, in fact, it has no known suffix. Only
one suffix may be so designated. The last source on the dependency
line is the suffix that is used (you should, however, only give one
suffix).
.IP .ORDER \n(pwu
Sources for this target, which are targets themselves,
are made in the specified order.
This feature only works in the simplest of cases, and is never applied
if the listed target is a 'main' target (i.e. listed on the command line).
This feature does not interact well with '::' rules.
.IP .PATH \n(pwu
If you give sources for this target,
.Pm
will take them as
directories to search for files it cannot find in the current
directory. If you give no sources, it will clear out any directories
added to the search path before.
.IP .PATH\f2suffix\fP \n(pwu
This does a similar thing to
.BR .PATH ,
but it does it only for files with the given suffix. The suffix must
have been defined already.
.IP .PRECIOUS \n(pwu
Gives the
.B .PRECIOUS
attribute to each source on the dependency line, unless there are no
sources, in which case the
.B .PRECIOUS
attribute is given to every target in the file.
.IP .RECURSIVE \n(pwu
Applies the
.B .MAKE
attribute to all its sources. It does nothing if you don't give it any sources.
.IP .SHELL \n(pwu
Tells
.Pm
to use some other shell than the Bourne Shell.
The sources for the target are organized as
\f2keyword\fP\f3=\fP\f2value\fP strings. If a \f2value\fP contains
white-space, it may be surrounded by double-quotes to make it a single
word.
Be sure to have at least one space between the ':' and the start of the
first keyword/value string.
The possible sources are:
.RS
.IP "\f3path=\fP\f2path\fP"
Tells where the shell actually resides. If you specify this and nothing else,
.Pm
will use the
last component of the path to find the specification. Use this if you just
want to use a different version of the Bourne or C Shell (\c
.Pm
knows
how to use the C Shell too).
.IP "\f3name=\fP\f2name\fP"
This is the name by which the shell is to be known. It is a single
word and, if no other keywords are specified (other than
.BR path ),
it is the name by which
.Pm
attempts to find a specification for the
it. You can use this if you would just rather use
the C Shell than the Bourne Shell (``\c
.BR ".SHELL: name=csh" ''
will do it).
Similarly, use the name ``ksh'' for the Korn Shell and ``tcsh'' for the 'totally-cool' version of C Shell.
.IP "\f3quiet=\fP\f2echo-off command\fP"
The command
.Pm
should send to stop the shell from printing its commands. Once echoing
is off, it is expected to remain off until explicitly turned on.
.IP "\f3echo=\fP\f2echo-on command\fP"
The command
.Pm
should give to turn echoing back on again.
.IP "\f3filter=\fP\f2printed echo-off command\fP"
Many shells will echo the echo-off command when it is given. This
keyword tells
.Pm
in what format the shell actually prints the
echo-off command. Wherever
.Pm
sees this string in the shell's
output, it will delete it and any following white-space, up to and
including the next newline.
.IP "\f3echoFlag=\fP\f2flag to turn echoing on\fP"
The flag to pass to the shell to turn echoing on at the start. If
either this or the next flag begins with a `\-', the flags will be
passed to the shell as separate arguments. Otherwise, the two will be
concatenated.
.IP "\f3errFlag=\fP\f2flag to turn error checking on\fP"
Flag to give the shell to turn error checking on at the start.
.IP "\f3check=\fP\f2command to turn error checking on\fP"
The command to make the shell check for errors or to print the command
that's about to be executed (%s indicates where the command to print
should go), if hasErrCtl is "no".
.IP "\f3ignore=\fP\f2command to turn error checking off\fP"
The command to turn error checking off or the command to execute a
command ignoring any errors. "%s" takes the place of the command.
.IP "\f3hasErrCtl=\fP\f2yes or no\fP"
This takes a value that is either
.B yes
or
.BR no ,
telling how the "check" and "ignore" commands should be used.
NOTE: If this is "no", both the check and ignore commands should
contain a \en at their end if the shell requires a newline before
executing a command.
.IP "\f3noninterFlag=\fP\f2flag to turn interactivity checking off\fP"
Flag to give the shell to turn force the shell into non-interactive
mode.
.RE
.IP "\&" \n(pwu
The strings that follow these keywords may be enclosed in single or
double quotes (the quotes will be stripped off) and may contain the
usual C backslash characters.
.IP "\&" \n(pwu
The built-in rule for using \f4csh\fP will convince \f4csh\fP to read
the \f4.cshrc\fP file in 'interactive' mode - i.e. the standard test
\f4if ($?prompt)\fP
will return true.
This may not be acceptable.
The only way around this is to specify a complete \f4csh\fP shell
specification and specify the \f4\-f\fP flag. This will simply
tell \f4csh\fP to not read the \f4.cshrc\fP at all.
The appropriate \f4SHELL\fP specification is:
.DS
.SHELL: path=/bin/csh \\
name=csh \\
noninterFlag=-f \\
quiet="unset verbose" \\
echo="set verbose" \\
filter="unset verbose" \\
echoFlag=v \\
errFlag=e \\
hasErrCtl=F \\
check="echo \\"%s\\"\\n" \\
ignore="csh -c \\"%s || exit 0\\""
.DE
.IP .SILENT \n(pwu
Applies the
.B .SILENT
attribute to each of its sources. If there are no sources on the
dependency line, then it is as if you gave
.Pm
the
.B \-s
flag.
.IP .SINGLESHELL \n(pwu
This is used to create a shell for each command.
It is equivalent to giving the
.B \-B
flag.
.IP .SUFFIXES \n(pwu
This is used to give new file suffixes for
.Pm
to handle. Each
source is a suffix
.Pm
should recognize. If you give a
.B .SUFFIXES
dependency line with no sources,
.Pm
will forget about all the
suffixes it knew (this also clobbers the null suffix).
For those targets that need to have suffixes defined, this is how you do it.
.PP
In addition to these targets, a line of the form
.DS
\f2attribute\fP : \f2sources\fP
.DE
applies the
.I attribute
to all the targets listed as
.I sources
except as noted above.
.P
The .EXPORT target is recognized but not implemented on IRIX.
.SH THE POWER OF SUFFIXES
.PP
One of the best aspects of both
.BR make (1)
and
.Pm
comes from their understanding of how the suffix of a file pertains to
its contents and their ability to do things with a file based solely on its
suffix.
.Pm
also has the ability to find a file based on its suffix,
supporting different types of files being in different directories.
The former ability derives from the existence of so-called
transformation rules while the latter comes from the specification of
search paths using the
.B .PATH
target.
.br
.ne 10
.SS TRANSFORMATION RULES
.PP
A special type of dependency, called a transformation rule, consists
of a target made of
two known suffixes stuck together followed by a shell script to transform a
file of one suffix into a file of the other.
The first suffix is the suffix of the source file and the second is that of
the target file.
For example, the target ``.c.o,'' followed by commands,
would define a transformation from files with the
``.c'' suffix to those with the ``.o'' suffix.
A transformation rule has no source files associated with it, though
attributes may be given to one in the usual way. These attributes are
then applied to any target that is on the ``target end'' of a
transformation rule.
The suffixes that are concatenated must be already known to
.Pm
in order for their concatenation to be recognized as a transformation,
i.e., the suffixes must have been the source for a .SUFFIXES target at some
time before the transformation is defined.
Many transformations are defined in the system makefile (see
.BR FILES ),
which you should examine for more examples as well as to find what is
already available. (You should especially note the various variables
used to contain flags for the compilers, assemblers, etc., used to
transform the files. These variables allow you to customize the
transformations to your own needs without having to redefine them.)
A transformation rule may be defined more than once, but only the last
such definition is remembered by
.Pm .
This allows you to redefine the transformations in the system makefile if
you wish.
.PP
Transformation rules are used only when a target has no commands associated
with it,
both to find any additional files on which it depends and to attempt to
figure out just how to make the target should it end up being out-of-date.
When a transformation is found for a target, another of the seven ``local''
variables mentioned earlier is defined:
.RS
.IP ".IMPSRC\ \ (<)" 20
The name/path of the source from which the target is to be transformed (the
``implied'' source).
.RE
.PP
For example,
given the following makefile:
.DS
a.out : a.o b.o
$(CC) $(.ALLSRC)
.DE
and a directory containing the files a.o, a.c and b.c,
.Pm
will look at the list of suffixes and transformations given in the
built-in rules and find that the suffixes ``.c'' and ``.o'' are both
known and there is a transformation rule defined from one to the other
with the command ``$(CC) $(CFLAGS) \-c\ \ $(.IMPSRC).'' Having found
this, it can then check the modification times of both a.c and b.c and
execute the command from the transformation rule as necessary in order
to update the files a.o and b.o.
.PP
.Pm ,
unlike
.BR make (1)
before it,
has the ability to apply several transformations to a file even if the
intermediate files do not exist.
Given a directory containing a .o file and a .v file, and transformations
from .v to .w, .w to .c and .c to .o,
.Pm
will define a transformation from .v \*(-> .o using the three transformation
rules you defined.
In the event of two paths between the same suffixes, the shortest path will be
chosen between the target and the first existing file on the path.
So if there were also a transformation from .w files to .o files,
.Pm
would use the path .v \*(-> .w \*(-> .o instead
of .v \*(-> .w \*(-> .c \*(-> .o.
.PP
Once an existing file is found,
.Pm
will continue to look at and record transformations until it comes to a
file to which nothing it knows of can be transformed,
at which point it will stop looking and use the path it has already found.
.PP
What happens if you have a .o file, a .v file and a .r file, all with
the same prefix, and transformations from .v \*(-> .o and .r \*(-> .o?
Which transformation will be used?
.Pm
uses the order in which the suffixes were given on the
.B .SUFFIXES
line to decide between transformations: whichever suffix came first,
wins.
So if the three suffixes were declared
.DS
\&.SUFFIXES : .o .v .r
.DE
the .v \*(-> .o transformation would be applied. Similarly, if they were
declared as
.DS
\&.SUFFIXES : .o .r .v
.DE
the .r \*(-> .o transformation would be used.
You should keep this in mind when writing such rules.
Note also that because the placing of a suffix on a
.B .SUFFIXES
line doesn't alter the precedence of previously-defined
transformations,
it is sometimes necessary to clear the whole lot of them out and start
from scratch. This is what the
.BR .SUFFIXES -only
line, mentioned earlier, will do.
.SH SEARCH PATHS
.PP
.Pm
also supports the notion of multiple directories in a more flexible,
easily-used manner than has been available in the past.
You can define a list of directories in which to search for any and
all files that aren't in the current directory by giving the directories
as sources to the
.B .PATH
target. The search will only be conducted for those files used only as
sources, on the assumption that files used as targets will be created
in the current directory.
.PP
The line
.DS
\&.PATH : RCS
.DE
would tell
.Pm
to look for any files it is seeking (including ones made up by means
of transformation rules) in the RCS directory as well as the current
one. Note, however, that this searching is only done if the file is
used only as a source in the makefile; the file cannot be
created by commands in the makefile.
.PP
A search path specific to files with a given suffix can also be
specified in much the same way.
.DS
\&.PATH.h :\ \ \ h\ \ \ /usr/include
.DE
causes the search for header files to be conducted in the ``h'' and
``/usr/include'' directories as well as the current one.
.PP
When expanding wildcards, these paths are also used. If the pattern
has a recognizable suffix, the search path for that suffix is used.
Otherwise, the path defined with the regular
.B .PATH
target is used.
.PP
When a file is found somewhere other than the current directory, its
name is replaced by its full pathname in any ``local'' variables.
.PP
Two types of suffixes are given special attention when a search path is defined
for them. On IRIX, the C compiler lets you specify where to
find header files (.h files) by means of
.B \-I
flags similar to those used by
.Pm .
If a search path is given for any suffix used as a source for the
.B .INCLUDES
target, the variable
.B $(.INCLUDES)
will be set to contain all the directories on the path, in the order
given, in a format which can be passed directly to the C compiler.
Similarly, one may give directories to search for
libraries to the compiler by means of
.B \-L
flags.
Directories on the search path for a suffix which was the source of the
.B .LIBS
target will be placed
in the
.B $(.LIBS)
variable ready to be passed to the compiler.
.SH LIBRARIES AND ARCHIVES
.PP
Two other special forms of sources are recognized by
.Pm .
Any source that begins with the characters ``\-l'' (lower-case L)
or ends in a suffix
that is a source for the
.B .LIBS
target is assumed to be a library, and any source that contains a left
parenthesis in it is considered to be a member (or members) of an archive.
.PP
Libraries are treated specially mostly in how they appear in the local
variables of those targets that depend on them.
Since IRIX supports the
.B \-L
flag when linking, the name of the library (i.e., its ``\-l'' form) is
used in all local variables.
.Pm
assumes that you will use the $(.LIBS) variable in the appropriate place.
.\"If, however, the system does not have this feature, the name is
.\"expanded to its full pathname before it is placed in any local
.\"variable.
.\".PP
.\"One problem with libraries is they have a table of contents in them
.\"and when the file is touched (so the file's modification time and the
.\"time listed in the table of contents don't match), the library is
.\"declared to be ``out-of-date'' by the linker and the final linking
.\"stage of creating your program fails miserably. To avoid this problem,
.\"when you use the
.\".B \-t
.\"flag,
.\".Pm
.\"updates the time of the table of contents for the library, as well as
.\"the library itself.
.PP
The process of creating a library or archive can be a painful one,
what with all the members having to be kept outside the archive as
well as inside it in order to keep them from being recreated.
.Pm
has been set up, however, to allow you to reference files that are in
an archive in a relatively painless manner.
The specification of an archive member is written as:
.DS
\f2archive\fP(\f2member\fP [\f2member\fP...])\f1
.DE
Both the open and close parentheses are required and there may be any
number of members between them (except 0, that is). Members may also
include wildcards characters. When such a source is examined, it is
the modification time of the member, as recorded in the archive, that
is used to determine its datedness.
.PP
If an archive member has no commands associated with it,
.Pm
goes through a special process to find commands for it.
First, implicit sources are sought using the ``member'' portion of the
specification. So if you have something like
``libmalloc.a(malloc.o)'' for a target,
.Pm
attempts to find sources for the file ``malloc.o,'' even if it
doesn't exist. If such sources exist,
.Pm
then looks for a transformation rule from the member's suffix to the
archive's (in this case from .o \*(-> .a) and tacks those commands on
as well.
.ne 5
.PP
To make these transformations easier to write,
three local variables are defined for the target:
.RS
.IP ".ARCHIVE\ \ (%)" 20
The path to the archive file.
.IP ".MEMBER\ \ (!)" 20
The actual member name (literally the part in parentheses).
.IP ".TARGET\ \ (@)" 20
The path to the file which will be archived, if it is only a source,
or the same as the
.B .MEMBER
variable if it is also a target.
.RE
.PP
Using the transformations already in the system makefile, a makefile
for a library might look something like this:
.DS
OBJS = setup.o doit.o transfer.o shutdown.o
\&.o.a :
.\|.\|.
rm \-f $(.MEMBER)
lib.a : lib.a($(OBJS))
ar\ \ cru\ \ $(.TARGET)\ \ $(.OODATE)
.DE
.PP
Note that the following .o \*(-> .a transformation is bad:
.DS
\&.o.a :
ar\ \ r\ \ $(.ARCHIVE)\ \ $(.TARGET)
.\|.\|.
rm \-f\ \ $(.TARGET)
.DE
The reason is simple: you should not execute ``ar'' on the same archive
several times at once. Also, it is much slower than archiving all the .o
files at the end.
.SH OUTPUT
.PP
When creating targets in parallel,
several shells are executing at once,
each wanting to write its output to the screen.
This output must be captured by
.Pm
in some way in order to prevent the screen from being filled with
garbage even more indecipherable than one can already get from these programs.
.Pm
has two ways of doing this,
one of which provides for much cleaner output and a clear delineation between
the output of different jobs,
the other of which provides a more immediate response so one can tell what is
really happening.
The former is done by notifying the user when the creation of a given target
starts, capturing the output, and transferring it
to the screen when the job finishes,
preceded by an indication as to which job produced the output.
The latter is done by catching the output of the shell (and its children)
and buffering it until an entire line is received, then printing
that line preceded by the name of the job from which the line came.
The name of the job is just the target which is being created by it.
Since this second method is preferred,
it is the one used by default.
The first method will be used if the
.B \-P
flag is given to
.Pm .
.SH PARALLELISM
.PP
.Pm
and \f4smake\fP
attempt to create several targets at once.
The degree of useful concurrency depends on the targets,
as well as the number of processors on the machine.
On IRIX,
the default concurrency value for single-processor systems is 2.
On multi-processor systems that have more than 1 unrestricted processor,
the value is 4 (see
.IR mpadmin (1)
to change the number of unrestricted processors).
To change the default concurrency, use the
.B \-J
flag.
This flag can be set on the
command line, inside a makefile with the \f3.MAKEFLAGS\fP target or
with the \f3PMAKE\fP environment variable.
.SH DEBUGGING
.PP
To debug makefiles, use
the
.BI \-d " what"
option to
print various information about
.Pm 's
internal processing.
The
.I what
argument is a string of single characters that tell
.Pm
what
aspects you are interested in.
The characters and the information they produce are as follows:
.RS
.IP a
Archive searching and caching.
.IP c
Conditional evaluation.
.IP d
The searching and caching of directories.
.IP j
Various snippets of information related to the running of the multiple
shells.
.IP m
The making of each target: what target is being examined; when it was
last modified; whether it is out-of-date; etc.
.IP s
The application of suffix-transformation rules.
.IP t
The maintenance of the list of targets.
.IP v
Variable assignment.
.IP "A or *"
Print all information.
.RE
.LP
Of these all, the
.B m
and
.B s
letters will be most useful to you.
If the
.B \-d
is the final argument or the argument from which it would get these
key letters begins with a
.BR \- ,
all of these debugging flags will be set, resulting in massive amounts
of output.
.SH COMPATIBILITY
Invoking
.Pm
as
.B smake
or using the
.I \-v
option turns on numerous compatibility options.
However there are still a few areas where
.Pm 's
behavior differs from classic System V
.BR make .
.PP
The
.I \-d
option in
.B make
doesn't take any sub-options, whereas in
.Pm
it does.
.PP
In
.Pm
the standard output and standard error streams for all executed
rules are merged together.
Unlike
.B make
it is impossible
to redirect the standard error of a rule to a location other than
the standard output of
.Pm .
.PP
The set of default suffixes defined is not completely the same between
.Pm
and
.BR make .
In particular
the suffixes
.I .a
and
.I .b
are defined in
.B system.mk
for
.Pm
while in
.B make
they are not.
This means that single (or NULL) suffix rules will not be applied
to
.I .a
files in
.Pm
whereas they will (potentially) be applied in
.BR make .
To make
.Pm
the same as
.B make
one would have to undefine all the pre-defined suffixes, and add back
just those that were in common with
.BR make .
.PP
The
.B \-n
option functions quite differently between
.Pm
and
.BR make .
.B make
will scan each shell command looking for potential re-invocations
of itself, and if it finds one, will assume that it is a recursive
make and execute the line.
.Pm
does no such scanning of the shell commands and will only execute a command
in
.B \-n
mode if the target is specified as a recursive target using the
.SM
.B .RECURSIVE
attribute.
.PP
The treatment of the \f4SHELL\fP environment variable differs - \f4pmake\fP
is in conformance with POSIX 1003.2.
.PP
The compatibility modes of
.Pm
attempt to emulate a 'least common denominator' version of
.B make
as might be found in early
.I BSD
releases
or System V Release 3.
It makes no attempt to emulate the more modern features found in later
System V and BSD releases.
.SH FILES
.TP \w'/usr/include/make/makelint.mkXX'u
Makefile or makefile
default input file
.TP \w'$(TOOLROOT)/usr/include/make/system.mkXX'u
$(TOOLROOT)/usr/include/make/system.mk
System makefile (the built-in rules)
.TP \w'/usr/include/make/makelint.mkXX'u
/usr/include/make/system.mk
Alternate system makefile (the built-in rules)
.TP \w'/usr/include/make/makelint.mkXX'u
/usr/include/make/makelib.mk
\&.USE target for making archives
.TP \w'/usr/include/make/makelint.mkXX'u
/usr/include/make/makelint.mk
\&.USE target for making lint libraries
.SH ENVIRONMENT
.ta \w'\f3PMAKE\fPXXX'u
\f3PMAKE\fP Flags \f4pmake\fP and \f4smake\fP should always use when invoked.
.br
\f4SHELL\fP Not used to set shell interpretor for commands.
.br
.SH SEE ALSO
.BR make (1)
for a more complete explanation of the lower-case flags to
.Pm .
.PP
There are numerous books on \f4make\fP usage.
These explain many of the features described here though most versions
of \f4make\fP are not as feature rich as \f4pmake\fP.
One such book is:\f2Managing Projects with Make, 2nd ed.\fP; authored
by \f2Andrew Oram\fP and \f2Steve Talbott\fP, from O'Reilly & Associates.
'\".SH AUTHOR
'\"Adam de Boor
'\".SH ORIGINS
'\"Sprite project at U.C. Berkeley