1528 lines
60 KiB
XML
1528 lines
60 KiB
XML
<?xml version="1.0" encoding="iso-8859-1"?>
|
|
<!--
|
|
$FreeBSD$
|
|
-->
|
|
<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="basics">
|
|
<title>The Basics of PMake</title>
|
|
|
|
<para><application>PMake</application> takes as input a file that
|
|
tells which files depend on which other files to be complete and
|
|
what to do about files that are <quote>out-of-date</quote>.
|
|
This file is known as a <quote>makefile</quote> and is usually
|
|
kept in the top-most directory of the system to be built.
|
|
While you can call the makefile anything you want,
|
|
<application>PMake</application> will look for
|
|
<filename>Makefile</filename> and <filename>makefile</filename>
|
|
(in that order) in the current directory if you do not tell it
|
|
otherwise. To specify a different makefile, use the
|
|
<option>-f</option> flag, e.g.</para>
|
|
|
|
<screen>&prompt.user; <userinput>pmake -f <replaceable>program.mk</replaceable></userinput></screen>
|
|
|
|
<para>A makefile has four different types of lines in it:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>File dependency specifications</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Creation commands</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Variable assignments</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Comments, include statements and conditional directives</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>Any line may be continued over multiple lines by ending it
|
|
with a backslash. The backslash, following newline and any
|
|
initial whitespace on the following line are compressed into a
|
|
single space before the input line is examined by
|
|
<application>PMake</application>.</para>
|
|
|
|
<section xml:id="deplines">
|
|
<title>Dependency Lines</title>
|
|
|
|
<para>As mentioned in the introduction, in any system, there are
|
|
dependencies between the files that make up the system.
|
|
For instance, in a program made up of several C source files and
|
|
one header file, the C files will need to be re-compiled should
|
|
the header file be changed. For a document of several chapters
|
|
and one macro file, the chapters will need to be reprocessed if
|
|
any of the macros changes. These are dependencies and are
|
|
specified by means of dependency lines in the makefile.</para>
|
|
|
|
<para>On a dependency line, there are targets and sources,
|
|
separated by a one- or two-character operator. The targets
|
|
<quote>depend</quote> 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. Targets and sources need not be
|
|
actual files, but every source must be either an actual file or
|
|
another target in the makefile. If you run out of room, use a
|
|
backslash at the end of the line to continue onto the next
|
|
one.</para>
|
|
|
|
<para>Any file may be a target and any file may be a source, but
|
|
the relationship between the two (or however many) is determined
|
|
by the <quote>operator</quote> that separates them. Three types
|
|
of operators exist: one specifies that the datedness of a target
|
|
is determined by the state of its sources, while another
|
|
specifies other files (the sources) that need to be dealt with
|
|
before the target can be re-created. The third operator is very
|
|
similar to the first, with the additional condition that the
|
|
target is out-of-date if it has no sources. These operations
|
|
are represented by the colon, the exclamation point and the
|
|
double-colon, respectively, and are mutually exclusive.
|
|
Their exact semantics are as follows:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<tbody>
|
|
<row valign="top">
|
|
<entry><literal>:</literal></entry>
|
|
|
|
<entry>If a colon is used, a target on the line is
|
|
considered to be <quote>out-of-date</quote> (and in need
|
|
of creation) if any of the sources has been modified
|
|
more recently than the target, or the target does not
|
|
exist. Under this operation, steps will be taken to
|
|
re-create the target only if it is found to be
|
|
out-of-date by using these two rules.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>!</literal></entry>
|
|
|
|
<entry>If an exclamation point is used, the target will
|
|
always be re-created, but this will not happen until all
|
|
of its sources have been examined and re-created, if
|
|
necessary.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>::</literal></entry>
|
|
|
|
<entry>If a double-colon is used, a target is
|
|
<quote>out-of-date</quote> if any of the sources has
|
|
been modified more recently than the target, or the
|
|
target does not exist, or the target has no sources.
|
|
If the target is out-of-date according to these rules,
|
|
it will be re-created. This operator also does
|
|
something else to the targets, but I will go into that
|
|
in the next section
|
|
(see <xref linkend="shellcmds"/>).</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Enough words, now for an example. Take that C program I
|
|
mentioned earlier. Say there are three C files
|
|
(<filename>a.c</filename>, <filename>b.c</filename> and
|
|
<filename>c.c</filename>) each of which includes the file
|
|
<filename>defs.h</filename>. The dependencies between the files
|
|
could then be expressed as follows:</para>
|
|
|
|
<programlisting>program : a.o b.o c.o
|
|
|
|
a.o b.o c.o : defs.h
|
|
|
|
a.o : a.c
|
|
|
|
b.o : b.c
|
|
|
|
c.o : c.c</programlisting>
|
|
|
|
<para>You may be wondering at this point, where
|
|
<filename>a.o</filename>, <filename>b.o</filename> and
|
|
<filename>c.o</filename> came in and why they depend on
|
|
<filename>defs.h</filename> and the C files do not.
|
|
The reason is quite simple: <buildtarget>program</buildtarget>
|
|
cannot be made by linking together <filename>.c</filename>
|
|
files—it must be made from <filename>.o</filename> files.
|
|
Likewise, if you change <filename>defs.h</filename>, it is not
|
|
the <filename>.c</filename> files that need to be re-created,
|
|
it is the <filename>.o</filename> files. If you think of
|
|
dependencies in these terms—which files (targets) need to
|
|
be created from which files (sources)—you should have no
|
|
problems.</para>
|
|
|
|
<para>An important thing to notice about the above example, is
|
|
that all the <filename>.o</filename> files appear as targets on
|
|
more than one line. This is perfectly all right: the target is
|
|
made to depend on all the sources mentioned on all the
|
|
dependency lines. For example, <filename>a.o</filename> depends
|
|
on both <filename>defs.h</filename> and <filename>a.c</filename>.</para>
|
|
|
|
<para>The order of the dependency lines in the makefile is
|
|
important: the first target on the first dependency line in the
|
|
makefile will be the one that gets made if you do not say
|
|
otherwise. That is why program comes first in the example
|
|
makefile, above.</para>
|
|
|
|
<para>Both targets and sources may contain the standard C-Shell wildcard
|
|
characters (<literal>{</literal>, <literal>}</literal>,
|
|
<literal>*</literal>, <literal>?</literal>, <literal>[</literal>, and
|
|
<literal>]</literal>), but the non-curly-brace ones may only appear in
|
|
the final component (the file portion) of the target or source.
|
|
The characters mean the following things:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<tbody>
|
|
<row valign="top">
|
|
<entry><literal>{}</literal></entry>
|
|
|
|
<entry>These enclose a comma-separated list of options and
|
|
cause the pattern to be expanded once for each element
|
|
of the list. Each expansion contains a different
|
|
element. For example,
|
|
<filename>src/{whiffle,beep,fish}.c</filename> expands
|
|
to the three words <filename>src/whiffle.c</filename>,
|
|
<filename>src/beep.c</filename>, and
|
|
<filename>src/fish.c</filename>. These braces may be
|
|
nested and, unlike the other wildcard characters, the
|
|
resulting words need not be actual files. All other
|
|
wildcard characters are expanded using the files that
|
|
exist when <application>PMake</application> is
|
|
started.</entry> </row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>*</literal></entry>
|
|
|
|
<entry>This matches zero or more characters of any sort.
|
|
<filename>src/*.c</filename> will expand to the same
|
|
three words as above as long as src contains those three
|
|
files (and no other files that end in
|
|
<filename>.c</filename>).></entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>?</literal></entry>
|
|
|
|
<entry>Matches any single character.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>[]</literal></entry>
|
|
|
|
<entry>This is known as a character class and contains
|
|
either a list of single characters, or a series of
|
|
character ranges (<literal>a-z</literal>, for example
|
|
means all characters between <literal>a</literal> and
|
|
<literal>z</literal>), or both. It matches any single
|
|
character contained in the list. For example,
|
|
<literal>[A-Za-z]</literal> will match all letters,
|
|
while <literal>[0123456789]</literal> will match all
|
|
numbers.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
</section>
|
|
|
|
<section xml:id="shellcmds" xreflabel="Shell Commands">
|
|
<title>Shell Commands</title>
|
|
|
|
<para><quote>Is not that nice,</quote> you say to yourself,
|
|
<quote>but how are files actually ``re-created'', as he likes to
|
|
spell it?</quote>
|
|
The re-creation is accomplished by commands you place in the
|
|
makefile. These commands are passed to the Bourne shell (better
|
|
known as <filename>/bin/sh</filename>) to be executed and are
|
|
expected to do what is necessary to update the target file
|
|
(<application>PMake</application> does not actually check to see
|
|
if the target was created. It just assumes it is there).</para>
|
|
|
|
<para>Shell commands in a makefile look a lot like shell commands
|
|
you would type at a terminal, with one important exception: each
|
|
command in a makefile must be preceded by at least one
|
|
tab.</para>
|
|
|
|
<para>Each target has associated with it a shell script made up of
|
|
one or more of these shell commands. The creation script for a
|
|
target should immediately follow the dependency line for that
|
|
target. 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 <literal>::</literal>
|
|
operator was used on the dependency line.</para>
|
|
|
|
<para>If the double-colon was used, each dependency line for the
|
|
target may be followed by a shell script. That script will only
|
|
be executed if the target on the associated dependency line is
|
|
out-of-date with respect to the sources on that line, according
|
|
to the rules I gave earlier. I'll give you a good example of
|
|
this later on.</para>
|
|
|
|
<para>To expand on the earlier makefile, you might add commands
|
|
as follows:</para>
|
|
|
|
<programlisting>program : a.o b.o c.o
|
|
cc a.o b.o c.o -o program
|
|
|
|
a.o b.o c.o : defs.h
|
|
a.o : a.c
|
|
cc -c a.c
|
|
|
|
b.o : b.c
|
|
cc -c b.c
|
|
|
|
c.o : c.c
|
|
cc -c c.c</programlisting>
|
|
|
|
<para>Something you should remember when writing a makefile is,
|
|
the commands will be executed if the target on the dependency
|
|
line is out-of-date, not the sources. In this example, the
|
|
command <command>cc -c a.c</command> will be executed if
|
|
<filename>a.o</filename> is out-of-date. Because of the
|
|
<literal>:</literal> operator, this means that should
|
|
<filename>a.c</filename> or <filename>defs.h</filename> have
|
|
been modified more recently than <filename>a.o</filename>, the
|
|
command will be executed (<filename>a.o</filename> will be
|
|
considered out-of-date).</para>
|
|
|
|
<para>Remember how I said the only difference between a makefile
|
|
shell command and a regular shell command was the leading tab?
|
|
I lied. There is another way in which makefile commands differ
|
|
from regular ones. The first two characters after the initial
|
|
whitespace are treated specially. If they are any combination
|
|
of <filename>@</filename> and <literal>-</literal>, they cause
|
|
<application>PMake</application> to do different things.</para>
|
|
|
|
<para>In most cases, shell commands are printed before they are
|
|
actually executed. This is to keep you informed of what is
|
|
going on. If an <literal>@</literal> appears, however, this
|
|
echoing is suppressed. In the case of an echo command,
|
|
say</para>
|
|
|
|
<programlisting>echo Linking index</programlisting>
|
|
|
|
<para>it would be rather silly to see</para>
|
|
|
|
<screen>echo Linking index
|
|
Linking index</screen>
|
|
|
|
<para>so <application>PMake</application> allows you to place an
|
|
<literal>@</literal> before the command to prevent the command
|
|
from being printed:</para>
|
|
|
|
<programlisting>@echo Linking index</programlisting>
|
|
|
|
<para>The other special character is the <literal>-</literal>.
|
|
In case you did not know, shell commands finish with a certain
|
|
<quote>exit status</quote>. This status is made available by
|
|
the operating system to whatever program invoked the command.
|
|
Normally this status will be <literal>0</literal> if everything
|
|
went ok and non-zero if something went wrong. For this reason,
|
|
<application>PMake</application> will consider an error to have
|
|
occurred if one of the shells it invokes returns a non-zero
|
|
status. When it detects an error,
|
|
<application>PMake</application>'s usual action is to abort
|
|
whatever it is doing and exit with a non-zero status itself (any
|
|
other targets that were being created will continue being made,
|
|
but nothing new will be started.
|
|
<application>PMake</application> will exit after the last job
|
|
finishes). This behavior can be altered, however, by placing a
|
|
<literal>-</literal> at the front of a command
|
|
(e.g. <command>-mv index index.old</command>), certain
|
|
command-line arguments, or doing other things, to be detailed
|
|
later. In such a case, the non-zero status is simply ignored
|
|
and <application>PMake</application> keeps chugging
|
|
along.</para>
|
|
|
|
<para>Because all the commands are given to a single shell to
|
|
execute, such things as setting shell variables, changing
|
|
directories, etc., last beyond the command in which they are
|
|
found. This also allows shell compound commands (like for
|
|
loops) to be entered in a natural manner. Since this could
|
|
cause problems for some makefiles that depend on each command
|
|
being executed by a single shell,
|
|
<application>PMake</application> has a <option>-B</option> flag
|
|
(it stands for backwards-compatible) that forces each command to
|
|
be given to a separate shell. It also does several other
|
|
things, all of which I discourage since they are now
|
|
old-fashioned.</para>
|
|
|
|
<para>A target's shell script is fed to the shell on its (the
|
|
shell's) input stream. This means that any commands, such as
|
|
<application>ci</application> that need to get input from the
|
|
terminal will not work right – they will get the shell's
|
|
input, something they probably will not find to their liking.
|
|
A simple way around this is to give a command like this:</para>
|
|
|
|
<screen><command>ci $(SRCS) < /dev/tty</command></screen>
|
|
|
|
<para>This would force the program's input to come from the
|
|
terminal. If you cannot do this for some reason, your only
|
|
other alternative is to use <application>PMake</application> in
|
|
its fullest compatibility mode.
|
|
See <quote>Compatibility</quote> in <xref linkend="gods"/>.</para>
|
|
</section>
|
|
|
|
|
|
<section xml:id="variables">
|
|
<title>Variables</title>
|
|
|
|
<para><application>PMake</application>, like
|
|
<application>Make</application> before it, has the ability to
|
|
save text in variables to be recalled later at your convenience.
|
|
Variables in <application>PMake</application> are used much like
|
|
variables in the shell and, by tradition, consist of all
|
|
upper-case letters (you do not have to use all upper-case
|
|
letters. In fact there is nothing to stop you from calling a
|
|
variable <literal>@^&$%$</literal>. Just tradition). Variables
|
|
are assigned-to using lines of the form:</para>
|
|
|
|
<programlisting>VARIABLE = value</programlisting>
|
|
|
|
<para>appended-to by:</para>
|
|
|
|
<programlisting>VARIABLE += value</programlisting>
|
|
|
|
<para>conditionally assigned-to (if the variable is not already
|
|
defined) by:</para>
|
|
|
|
<programlisting>VARIABLE ?= value</programlisting>
|
|
|
|
<para>and assigned-to with expansion (i.e. the value is expanded
|
|
(see below) before being assigned to the variable—useful
|
|
for placing a value at the beginning of a variable, or other
|
|
things) by:</para>
|
|
|
|
<programlisting>VARIABLE := value</programlisting>
|
|
|
|
<para>Any whitespace before value is stripped off. When
|
|
appending, a space is placed between the old value and the stuff
|
|
being appended.</para>
|
|
|
|
<para>The final way a variable may be assigned to is using:</para>
|
|
|
|
<programlisting>VARIABLE != shell-command</programlisting>
|
|
|
|
<para>In this case, shell-command has all its variables expanded
|
|
(see below) and is passed off to a shell to execute. The output
|
|
of the shell is then placed in the variable. Any newlines
|
|
(other than the final one) are replaced by spaces before the
|
|
assignment is made. This is typically used to find the current
|
|
directory via a line like:</para>
|
|
|
|
<programlisting>CWD != pwd</programlisting>
|
|
|
|
<note>
|
|
<para>This is intended to be used to execute commands that
|
|
produce small amounts of output
|
|
(e.g. <application>pwd</application>).
|
|
The implementation is less than intelligent and will likely
|
|
freeze if you execute something that produces thousands of
|
|
bytes of output (8 Kb is the limit on many &unix; systems).
|
|
The value of a variable may be retrieved by enclosing the
|
|
variable name in parentheses or curly braces and preceding the
|
|
whole thing with a dollar sign.</para>
|
|
</note>
|
|
|
|
<para>For example, to set the variable <envar>CFLAGS</envar> to
|
|
the string <literal>-I/sprite/src/lib/libc -O,</literal> you
|
|
would place a line:</para>
|
|
|
|
<programlisting>CFLAGS = -I/sprite/src/lib/libc -O</programlisting>
|
|
|
|
<para>in the makefile and use the word
|
|
<literal>$(CFLAGS)</literal> wherever you would like the string
|
|
<literal>-I/sprite/src/lib/libc -O</literal> to appear. This is
|
|
called variable expansion.</para>
|
|
|
|
<note>
|
|
<para>Unlike <application>Make</application>,
|
|
<application>PMake</application> will not expand a variable
|
|
unless it knows the variable exists. E.g. if you have a
|
|
<literal>${i}</literal> in a shell command and you have not
|
|
assigned a value to the variable <varname>i</varname> (the
|
|
empty string is considered a value, by the way), where
|
|
<application>Make</application> would have substituted the
|
|
empty string, <application>PMake</application> will leave the
|
|
<literal>${i}</literal> alone.
|
|
To keep <application>PMake</application> from substituting for
|
|
a variable it knows, precede the dollar sign with another
|
|
dollar sign (e.g. to pass <literal>${HOME}</literal> to
|
|
the shell, use <literal>$${HOME}</literal>). This causes
|
|
<application>PMake</application>, in effect, to expand the
|
|
<literal>$</literal> macro, which expands to a single
|
|
<literal>$</literal>.</para>
|
|
</note>
|
|
|
|
<para>For compatibility, <application>Make</application>'s style
|
|
of variable expansion will be used if you invoke
|
|
<application>PMake</application> with any of the compatibility
|
|
flags (<option>-V</option>, <option>-B</option> or
|
|
<option>-M</option>. The <option>-V</option> flag alters just
|
|
the variable expansion). There are two different times at which
|
|
variable expansion occurs: when parsing a dependency line, the
|
|
expansion occurs immediately upon reading the line. If any
|
|
variable used on a dependency line is undefined,
|
|
<application>PMake</application> will print a message and exit.
|
|
Variables in shell commands are expanded when the command is
|
|
executed. Variables used inside another variable are expanded
|
|
whenever the outer variable is expanded (the expansion of an
|
|
inner variable has no effect on the outer variable. For
|
|
example, if the outer variable is used on a dependency line and
|
|
in a shell command, and the inner variable changes value between
|
|
when the dependency line is read and the shell command is
|
|
executed, two different values will be substituted for the outer
|
|
variable).</para>
|
|
|
|
<para>Variables come in four flavors, though they are all expanded
|
|
the same and all look about the same. They are (in order of
|
|
expanding scope):</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Local variables.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Command-line variables.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Global variables.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Environment variables.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>The classification of variables does not matter much, except
|
|
that the classes are searched from the top (local) to the bottom
|
|
(environment) when looking up a variable. The first one found
|
|
wins.</para>
|
|
|
|
<section xml:id="localvariables">
|
|
<title>Local Variables</title>
|
|
|
|
<para>Each target can have as many as seven local variables.
|
|
These are variables that are only <quote>visible</quote>
|
|
within that target's shell script and contain such things as
|
|
the target's name, all of its sources (from all its dependency
|
|
lines), those sources that were out-of-date, etc. Four local
|
|
variables are defined for all targets. They are:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><varname>.TARGET</varname></term>
|
|
|
|
<listitem>
|
|
<para>The name of the target.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><varname>.OODATE</varname></term>
|
|
|
|
<listitem>
|
|
<para>The list of the sources for the target that were
|
|
considered out-of-date. The order in the list is not
|
|
guaranteed to be the same as the order in which the
|
|
dependencies were given.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><varname>.ALLSRC</varname></term>
|
|
|
|
<listitem>
|
|
<para>The list of all sources for this target in the order
|
|
in which they were given.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><varname>.PREFIX</varname></term>
|
|
|
|
<listitem>
|
|
<para>The target without its suffix and without any
|
|
leading path. E.g. for the target
|
|
<filename>../../lib/compat/fsRead.c</filename>, this
|
|
variable would contain <literal>fsRead</literal>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>Three other local variables are set only for certain
|
|
targets under special circumstances. These are the
|
|
<varname>.IMPSRC,</varname> <varname>.ARCHIVE,</varname> and
|
|
<varname>.MEMBER</varname> variables. When they are set and
|
|
how they are used is described later.</para>
|
|
|
|
<para>Four of these variables may be used in sources as well as
|
|
in shell scripts. These are <varname>.TARGET</varname>,
|
|
<varname>.PREFIX</varname>, <varname>.ARCHIVE</varname> and
|
|
<varname>.MEMBER</varname>. The variables in the sources are
|
|
expanded once for each target on the dependency line,
|
|
providing what is known as a <quote>dynamic source,</quote>
|
|
allowing you to specify several dependency lines at once.
|
|
For example:</para>
|
|
|
|
<programlisting>$(OBJS) : $(.PREFIX).c</programlisting>
|
|
|
|
<para>will create a dependency between each object file and its
|
|
corresponding C source file.</para>
|
|
</section>
|
|
|
|
<section xml:id="cmdvars">
|
|
<title>Command-line Variables</title>
|
|
|
|
<para>Command-line variables are set when
|
|
<application>PMake</application> is first invoked by giving a
|
|
variable assignment as one of the arguments.
|
|
For example:</para>
|
|
|
|
<screen>pmake "CFLAGS = -I/sprite/src/lib/libc -O"</screen>
|
|
|
|
<para>would make <envar>CFLAGS</envar> be a command-line
|
|
variable with the given value. Any assignments to
|
|
<envar>CFLAGS</envar> in the makefile will have no effect,
|
|
because once it is set, there is (almost) nothing you can do
|
|
to change a command-line variable (the search order, you see).
|
|
Command-line variables may be set using any of the four
|
|
assignment operators, though only <literal>=</literal> and
|
|
<literal>?=</literal> behave as you would expect them to,
|
|
mostly because assignments to command-line variables are
|
|
performed before the makefile is read, thus the values set in
|
|
the makefile are unavailable at the time.
|
|
<literal>+=</literal> is the same as <literal>=</literal>,
|
|
because the old value of the variable is sought only in the
|
|
scope in which the assignment is taking place (for reasons of
|
|
efficiency that I will not get into here). <literal>:=</literal>
|
|
and <literal>?=</literal> will work if the only variables
|
|
used are in the environment. <literal>!=</literal> is sort of
|
|
pointless to use from the command line, since the same effect
|
|
can no doubt be accomplished using the shell's own command
|
|
substitution mechanisms (backquotes and all that).</para>
|
|
</section>
|
|
|
|
<section xml:id="globalvariables">
|
|
<title>Global Variables</title>
|
|
|
|
<para>Global variables are those set or appended-to in the
|
|
makefile. There are two classes of global variables: those
|
|
you set and those <application>PMake</application> sets.
|
|
As I said before, the ones you set can have any name you want
|
|
them to have, except they may not contain a colon or an
|
|
exclamation point.
|
|
The variables <application>PMake</application> sets (almost)
|
|
always begin with a period and always contain upper-case
|
|
letters, only. The variables are as follows:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><varname>.PMAKE</varname></term>
|
|
|
|
<listitem>
|
|
<para>The name by which <application>PMake</application>
|
|
was invoked is stored in this variable. For
|
|
compatibility, the name is also stored in the
|
|
<varname>MAKE</varname> variable.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><varname>.MAKEFLAGS</varname></term>
|
|
|
|
<listitem>
|
|
<para>All the relevant flags with which
|
|
<application>PMake</application> was invoked.
|
|
This does not include such things as <option>-f</option>
|
|
or variable assignments. Again for compatibility, this
|
|
value is stored in the <varname>MFLAGS</varname>
|
|
variable as well.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>Two other variables, <varname>.INCLUDES</varname> and
|
|
<varname>.LIBS,</varname> are covered in the section on
|
|
special targets in <xref linkend="shortcuts"/>.</para>
|
|
|
|
<para>Global variables may be deleted using lines of the
|
|
form:</para>
|
|
|
|
<programlisting>#undef variable</programlisting>
|
|
|
|
<para>The <literal>#</literal> must be the first character on
|
|
the line. Note that this may only be done on global
|
|
variables.</para>
|
|
</section>
|
|
|
|
<section xml:id="envvars">
|
|
<title>Environment Variables</title>
|
|
|
|
<para>Environment variables are passed by the shell that invoked
|
|
<application>PMake</application> and are given by
|
|
<application>PMake</application> to each shell it invokes.
|
|
They are expanded like any other variable, but they cannot be
|
|
altered in any way.</para>
|
|
|
|
<para>One special environment variable, <envar>PMAKE</envar>, is
|
|
examined by <application>PMake</application> for command-line
|
|
flags, variable assignments, etc., it should always use. This
|
|
variable is examined before the actual arguments to
|
|
<application>PMake</application> are. In addition, all flags
|
|
given to <application>PMake</application>, either through the
|
|
<envar>PMAKE</envar> variable or on the command line, are
|
|
placed in this environment variable and exported to each shell
|
|
<application>PMake</application> executes. Thus recursive
|
|
invocations of <application>PMake</application> automatically
|
|
receive the same flags as the top-most one.</para>
|
|
|
|
<para>Using all these variables, you can compress the sample
|
|
makefile even more:</para>
|
|
|
|
<programlisting>OBJS = a.o b.o c.o
|
|
|
|
program : $(OBJS)
|
|
cc $(.ALLSRC) -o $(.TARGET)
|
|
|
|
$(OBJS) : defs.h
|
|
|
|
a.o : a.c
|
|
cc -c a.c
|
|
|
|
b.o : b.c
|
|
cc -c b.c
|
|
|
|
c.o : c.c
|
|
cc -c c.c</programlisting>
|
|
</section>
|
|
</section>
|
|
|
|
<section xml:id="comments">
|
|
<title>Comments</title>
|
|
|
|
<para>Comments in a makefile start with a <literal>#</literal>
|
|
character and extend to the end of the line. They may appear
|
|
anywhere you want them, except in a shell command (though the
|
|
shell will treat it as a comment, too). If, for some reason,
|
|
you need to use the <literal>#</literal> in a variable or on a
|
|
dependency line, put a backslash in front of it.
|
|
<application>PMake</application> will compress the two into a
|
|
single <literal>#</literal>.</para>
|
|
|
|
<note>
|
|
<para>This is not true if <application>PMake</application> is
|
|
operating in full-compatibility mode).</para>
|
|
</note>
|
|
</section>
|
|
|
|
<section xml:id="parellelism">
|
|
<title>Parallelism</title>
|
|
|
|
<para><application>PMake</application> was specifically designed
|
|
to re-create several targets at once, when possible. You do not
|
|
have to do anything special to cause this to happen (unless
|
|
<application>PMake</application> was configured to not act in
|
|
parallel, in which case you will have to make use of the
|
|
<option>-L</option> and <option>-J</option> flags (see below)),
|
|
but you do have to be careful at times.</para>
|
|
|
|
<para>There are several problems you are likely to encounter. One
|
|
is that some makefiles (and programs) are written in such a way
|
|
that it is impossible for two targets to be made at once. The
|
|
program <application>xstr</application>, for example, always
|
|
modifies the files <filename>strings</filename> and
|
|
<filename>x.c</filename>. There is no way to change it. Thus
|
|
you cannot run two of them at once without something being
|
|
trashed. Similarly, if you have commands in the makefile that
|
|
always send output to the same file, you will not be able to
|
|
make more than one target at once unless you change the file you
|
|
use. You can, for instance, add a <literal>$$$$</literal> to
|
|
the end of the file name to tack on the process ID of the shell
|
|
executing the command (each <literal>$$</literal> expands to a
|
|
single <literal>$</literal>, thus giving you the shell variable
|
|
<literal>$$</literal>). Since only one shell is used for all
|
|
the commands, you will get the same file name for each command
|
|
in the script.</para>
|
|
|
|
<para>The other problem comes from improperly-specified
|
|
dependencies that worked in <application>Make</application>
|
|
because of its sequential, depth-first way of examining them.
|
|
While I do not want to go into depth on how
|
|
<application>PMake</application> works (look in <xref linkend="gods"/> if you are interested), I will warn you that
|
|
files in two different levels of the dependency tree may be
|
|
examined in a different order in
|
|
<application>PMake</application> than they were in
|
|
<application>Make</application>.
|
|
For example, given the makefile:</para>
|
|
|
|
<programlisting>a :
|
|
|
|
b c b : d</programlisting>
|
|
|
|
<para><application>PMake</application> will examine the targets in
|
|
the order <buildtarget>c</buildtarget>,
|
|
<buildtarget>d</buildtarget>, <buildtarget>b</buildtarget>,
|
|
<buildtarget>a</buildtarget>. If the makefile's author expected
|
|
<application>PMake</application> to abort before making
|
|
<buildtarget>c</buildtarget> if an error occurred while making
|
|
<buildtarget>b</buildtarget>, or if <buildtarget>b</buildtarget>
|
|
needed to exist before <buildtarget>c</buildtarget> was made,
|
|
(s)he will be sorely disappointed. The dependencies are
|
|
incomplete, since in both these cases,
|
|
<buildtarget>c</buildtarget> would depend on
|
|
<buildtarget>b</buildtarget>. So watch out.</para>
|
|
|
|
<para>Another problem you may face is that, while
|
|
<application>PMake</application> is set up to handle the output
|
|
from multiple jobs in a graceful fashion, the same is not so for
|
|
input. It has no way to regulate input to different jobs, so if
|
|
you use the redirection from <filename>/dev/tty</filename> I
|
|
mentioned earlier, you must be careful not to run two of the
|
|
jobs at once.</para>
|
|
</section>
|
|
|
|
<section xml:id="writeanddebug">
|
|
<title>Writing and Debugging a Makefile</title>
|
|
|
|
<para>Now you know most of what is in a
|
|
<filename>Makefile</filename>, what do you do next? There are
|
|
two choices: use one of the uncommonly-available makefile
|
|
generators or write your own makefile (I leave out the third
|
|
choice of ignoring <application>PMake</application> and doing
|
|
everything by hand as being beyond the bounds of common
|
|
sense).</para>
|
|
|
|
<para>When faced with the writing of a makefile, it is usually
|
|
best to start from first principles: just what are you trying to
|
|
do? What do you want the makefile finally to produce? To begin
|
|
with a somewhat traditional example, let's say you need to write
|
|
a makefile to create a program, <command>expr</command>, that
|
|
takes standard infix expressions and converts them to prefix
|
|
form (for no readily apparent reason). You have got three
|
|
source files, in C, that make up the program:
|
|
<filename>main.c</filename>, <filename>parse.c</filename>, and
|
|
<filename>output.c</filename>. Harking back to my pithy advice
|
|
about dependency lines, you write the first line of the
|
|
file:</para>
|
|
|
|
<programlisting>expr : main.o parse.o output.o</programlisting>
|
|
|
|
<para>because you remember <filename>expr</filename> is made from
|
|
<filename>.o</filename> files, not <filename>.c</filename>
|
|
files. Similarly for the <filename>.o</filename> files you
|
|
produce the lines:</para>
|
|
|
|
<programlisting>main.o : main.c
|
|
|
|
parse.o : parse.c
|
|
|
|
output.o : output.c
|
|
|
|
main.o parse.o output.o : defs.h</programlisting>
|
|
|
|
<para>Great. You have now got the dependencies specified. What
|
|
you need now is commands. These commands, remember, must
|
|
produce the target on the dependency line, usually by using the
|
|
sources you have listed. You remember about local variables?
|
|
Good, so it should come to you as no surprise when you
|
|
write:</para>
|
|
|
|
<programlisting>expr : main.o parse.o output.o
|
|
cc -o $(.TARGET) $(.ALLSRC)</programlisting>
|
|
|
|
<para>Why use the variables? If your program grows to produce
|
|
postfix expressions too (which, of course, requires a name
|
|
change or two), it is one fewer place you have to change the
|
|
file. You cannot do this for the object files, however, because
|
|
they depend on their corresponding source files and
|
|
<filename>defs.h</filename>, thus if you said:</para>
|
|
|
|
<programlisting>cc -c $(.ALLSRC)</programlisting>
|
|
|
|
<para>you will get (for <filename>main.o</filename>):</para>
|
|
|
|
<programlisting>cc -c main.c defs.h</programlisting>
|
|
|
|
<para>which is wrong. So you round out the makefile with these
|
|
lines:</para>
|
|
|
|
<programlisting>main.o : main.c
|
|
cc -c main.c
|
|
|
|
parse.o : parse.c
|
|
cc -c parse.c
|
|
|
|
output.o : output.c
|
|
cc -c output.c</programlisting>
|
|
|
|
<para>The makefile is now complete and will, in fact, create the
|
|
program you want it to without unnecessary compilations or
|
|
excessive typing on your part. There are two things wrong with
|
|
it, however (aside from it being altogether too long, something
|
|
I will address in <xref linkend="shortcuts"/>):</para>
|
|
|
|
<orderedlist>
|
|
<listitem>
|
|
<para>The string <literal>main.o parse.o output.o</literal> is
|
|
repeated twice, necessitating two changes when you add
|
|
postfix (you were planning on that, were not you?). This is
|
|
in direct violation of de Boor's First Rule of writing
|
|
makefiles:</para>
|
|
|
|
<para>Anything that needs to be written more than once should
|
|
be placed in a variable. I cannot emphasize this enough as
|
|
being very important to the maintenance of a makefile and
|
|
its program.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>There is no way to alter the way compilations are
|
|
performed short of editing the makefile and making the
|
|
change in all places. This is evil and violates de Boor's
|
|
Second Rule, which follows directly from the first:</para>
|
|
|
|
<para>Any flags or programs used inside a makefile should be
|
|
placed in a variable so they may be changed, temporarily or
|
|
permanently, with the greatest ease.</para>
|
|
</listitem>
|
|
</orderedlist>
|
|
|
|
<para>The makefile should more properly read:</para>
|
|
|
|
<programlisting>OBJS = main.o parse.o output.o
|
|
|
|
expr : $(OBJS)
|
|
$(CC) $(CFLAGS) -o $(.TARGET) $(.ALLSRC)
|
|
|
|
main.o : main.c
|
|
$(CC) $(CFLAGS) -c main.c
|
|
|
|
parse.o : parse.c
|
|
$(CC) $(CFLAGS) -c parse.c
|
|
|
|
output.o : output.c
|
|
$(CC) $(CFLAGS) -c output.c
|
|
|
|
$(OBJS) : defs.h</programlisting>
|
|
|
|
<para>Alternatively, if you like the idea of dynamic sources
|
|
mentioned in <xref linkend="localvariables"/>, you could write it
|
|
like this:</para>
|
|
|
|
<programlisting>OBJS = main.o parse.o output.o
|
|
|
|
expr : $(OBJS)
|
|
$(CC) $(CFLAGS) -o $(.TARGET) $(.ALLSRC)
|
|
|
|
$(OBJS) : $(.PREFIX).c defs.h
|
|
$(CC) $(CFLAGS) -c $(.PREFIX).c</programlisting>
|
|
|
|
<para>These two rules and examples lead to de Boor's First
|
|
Corollary:
|
|
<emphasis>Variables are your friends</emphasis>.</para>
|
|
|
|
<para>Once you have written the makefile comes the
|
|
sometimes-difficult task of making sure the darn thing works.
|
|
Your most helpful tool to make sure the makefile is at least
|
|
syntactically correct is the <option>-n</option> flag, which
|
|
allows you to see if <application>PMake</application> will choke
|
|
on the makefile. The second thing the <option>-n</option> flag
|
|
lets you do is see what <application>PMake</application> would
|
|
do without it actually doing it, thus you can make sure the
|
|
right commands would be executed were you to give
|
|
<application>PMake</application> its head.</para>
|
|
|
|
<para>When you find your makefile is not behaving as you hoped,
|
|
the first question that comes to mind (after <quote>What time is
|
|
it, anyway?</quote>) is <quote>Why not?</quote> In answering
|
|
this, two flags will serve you well: <literal>-d m</literal> and
|
|
<quote>-p 2</quote>.
|
|
The first causes <application>PMake</application> to tell you as
|
|
it examines each target in the makefile and indicate why it is
|
|
deciding whatever it is deciding. You can then use the
|
|
information printed for other targets to see where you went
|
|
wrong. The <quote>-p 2</quote> flag makes
|
|
<application>PMake</application> print out its internal state
|
|
when it is done, allowing you to see that you forgot to make
|
|
that one chapter depend on that file of macros you just got a
|
|
new version of. The output from <quote>-p 2</quote> is intended
|
|
to resemble closely a real makefile, but with additional
|
|
information provided and with variables expanded in those
|
|
commands <application>PMake</application> actually printed or
|
|
executed.</para>
|
|
|
|
<para>Something to be especially careful about is circular
|
|
dependencies. For example:</para>
|
|
|
|
<programlisting>a : b
|
|
|
|
b : c d
|
|
|
|
d : a</programlisting>
|
|
|
|
<para>In this case,
|
|
because of how <application>PMake</application> works,
|
|
<buildtarget>c</buildtarget> is the only thing
|
|
<application>PMake</application> will examine, because
|
|
<buildtarget>d</buildtarget> and <buildtarget>a</buildtarget> will
|
|
effectively fall off the edge of the universe, making it
|
|
impossible to examine <buildtarget>b</buildtarget> (or them, for
|
|
that matter). <application>PMake</application> will tell you
|
|
(if run in its normal mode) all the targets involved in any
|
|
cycle it looked at (i.e. if you have two cycles in the
|
|
graph (naughty, naughty), but only try to make a target in one
|
|
of them, <application>PMake</application> will only tell you
|
|
about that one. You will have to try to make the other to find
|
|
the second cycle). When run as <application>Make</application>,
|
|
it will only print the first target in the cycle.</para>
|
|
</section>
|
|
|
|
<section xml:id="invoking">
|
|
<title>Invoking PMake</title>
|
|
|
|
<para><application>PMake</application> comes with a wide variety
|
|
of flags to choose from. They may appear in any order,
|
|
interspersed with command-line variable assignments and targets
|
|
to create. The flags are as follows:</para>
|
|
|
|
<variablelist>
|
|
<varlistentry>
|
|
<term><option>-d <replaceable>what</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>This causes <application>PMake</application> to spew
|
|
out debugging information that may prove useful to you.
|
|
If you cannot figure out why
|
|
<application>PMake</application> is doing what it is
|
|
doing, you might try using this flag.
|
|
The <replaceable>what</replaceable> parameter is a string
|
|
of single characters that tell
|
|
<application>PMake</application> what aspects you are
|
|
interested in. Most of what I describe will make little
|
|
sense to you, unless you have dealt with
|
|
<application>Make</application> before. Just remember
|
|
where this table is and come back to it as you read on.
|
|
The characters and the information they produce are as
|
|
follows:</para>
|
|
|
|
<informaltable frame="none">
|
|
<tgroup cols="2">
|
|
<tbody>
|
|
<row valign="top">
|
|
<entry><literal>a</literal></entry>
|
|
|
|
<entry>Archive searching and caching.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>c</literal></entry>
|
|
|
|
<entry>Conditional evaluation.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>d</literal></entry>
|
|
|
|
<entry>The searching and caching of
|
|
directories.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>j</literal></entry>
|
|
|
|
<entry>Various snippets of information related to
|
|
the running of the multiple shells. Not
|
|
particularly interesting.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>m</literal></entry>
|
|
|
|
<entry>The making of each target: what target is
|
|
being examined; when it was last modified; whether
|
|
it is out-of-date; etc.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>p</literal></entry>
|
|
|
|
<entry>Makefile parsing.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>r</literal></entry>
|
|
|
|
<entry>Remote execution.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>s</literal></entry>
|
|
|
|
<entry>The application of suffix-transformation
|
|
rules. (See <xref linkend="shortcuts"/>.)</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>t</literal></entry>
|
|
|
|
<entry>The maintenance of the list of targets.</entry>
|
|
</row>
|
|
|
|
<row valign="top">
|
|
<entry><literal>v</literal></entry>
|
|
|
|
<entry>Variable assignment.</entry>
|
|
</row>
|
|
</tbody>
|
|
</tgroup>
|
|
</informaltable>
|
|
|
|
<para>Of these all, the <literal>m</literal> and
|
|
<literal>s</literal> letters will be most useful to you.
|
|
If the <option>-d</option> is the final argument or the
|
|
argument from which it would get these key letters (see
|
|
below for a note about which argument would be used)
|
|
begins with a –, all of these debugging flags will
|
|
be set, resulting in massive amounts of output.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-f</option> makefile</term>
|
|
|
|
<listitem>
|
|
<para>Specify a makefile to read different from the standard
|
|
makefiles (<filename>Makefile</filename> or
|
|
<filename>makefile</filename>).
|
|
If makefile is <literal>-</literal>,
|
|
<application>PMake</application> uses the standard input.
|
|
This is useful for making quick and dirty makefiles.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-h</option></term>
|
|
|
|
<listitem>
|
|
<para>Prints out a summary of the various flags
|
|
<application>PMake</application> accepts.
|
|
It can also be used to find out what level of concurrency was
|
|
compiled into the version of <application>PMake</application> you
|
|
are using (look at <literal>-J</literal> and
|
|
<literal>-L</literal>) and various other information on how
|
|
<application>PMake</application> was configured.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-i</option></term>
|
|
|
|
<listitem>
|
|
<para>If you give this flag, <application>PMake</application> will
|
|
ignore non-zero status returned by any of its shells. It is like
|
|
placing a <literal>-</literal> before all the commands in the
|
|
makefile.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-k</option></term>
|
|
|
|
<listitem>
|
|
<para>This is similar to <option>-i</option> in that it allows
|
|
<application>PMake</application> to continue when it sees an
|
|
error, but unlike <option>-i</option>, where
|
|
<application>PMake</application> continues blithely as if nothing
|
|
went wrong, <option>-k</option> causes it to recognize the error
|
|
and only continue work on those things that do not depend on the
|
|
target, either directly or indirectly (through depending on
|
|
something that depends on it), whose creation returned the error.
|
|
The <option>k</option> is for <quote>keep going</quote>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-l</option></term>
|
|
|
|
<listitem>
|
|
<para><application>PMake</application> has the ability to lock a
|
|
directory against other people executing it in the same directory
|
|
(by means of a file called <filename>LOCK.make</filename> that it
|
|
creates and checks for in the directory). This is a Good Thing
|
|
because two people doing the same thing in the same place can be
|
|
disastrous for the final product (too many cooks and all that).
|
|
Whether this locking is the default is up to your system
|
|
administrator. If locking is on, <option>-l</option> will turn it
|
|
off, and vice versa.
|
|
Note that this locking will not prevent you from invoking
|
|
<application>PMake</application> twice in the same place–if
|
|
you own the lock file, <application>PMake</application> will warn
|
|
you about it but continue to execute.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-m <replaceable>directory</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>Tells <application>PMake</application> another place to search
|
|
for included makefiles via the
|
|
<<replaceable>filename</replaceable>> style.
|
|
Several <filename>-m</filename> options can be given to form a
|
|
search path. If this construct is used the default system
|
|
makefile search path is completely overridden.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-n</option></term>
|
|
|
|
<listitem>
|
|
<para>This flag tells <application>PMake</application> not to
|
|
execute the commands needed to update the out-of-date targets in
|
|
the makefile. Rather, <application>PMake</application> will
|
|
simply print the commands it would have executed and exit.
|
|
This is particularly useful for checking the correctness of a
|
|
makefile. If <application>PMake</application> does not do what
|
|
you expect it to, it is a good chance the makefile is wrong.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-p number</option></term>
|
|
|
|
<listitem>
|
|
<para>This causes <application>PMake</application> to print its
|
|
input in a reasonable form, though not necessarily one that would
|
|
make immediate sense to anyone but me. The number is a bitwise OR
|
|
of 1 and 2, where 1 means it should print the input before doing
|
|
any processing and 2 says it should print it after everything has
|
|
been re-created.
|
|
Thus <option>-p 3</option> would print it twice-a-once before
|
|
processing and once after (you might find the difference between
|
|
the two interesting). This is mostly useful to me, but you may
|
|
find it informative in some bizarre circumstances.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-q</option></term>
|
|
|
|
<listitem>
|
|
<para>If you give <application>PMake</application> this flag, it
|
|
will not try to re-create anything. It will just see if anything
|
|
is out-of-date and exit non-zero if so.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-r</option></term>
|
|
|
|
<listitem>
|
|
<para>When <application>PMake</application> starts up, it reads a
|
|
default makefile that tells it what sort of system it is on and
|
|
gives it some idea of what to do if you do not tell it anything.
|
|
I will tell you about it in <xref linkend="shortcuts"/>.
|
|
If you give this flag, <application>PMake</application> will not
|
|
read the default makefile.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-s</option></term>
|
|
|
|
<listitem>
|
|
<para>This causes <application>PMake</application> to not print
|
|
commands before they are executed. It is the equivalent of
|
|
putting an <quote>@</quote> before every command in the
|
|
makefile.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-t</option></term>
|
|
|
|
<listitem>
|
|
<para>Rather than try to re-create a target,
|
|
<application>PMake</application> will simply <quote>touch</quote>
|
|
it so as to make it appear up-to-date.
|
|
If the target did not exist before, it will when
|
|
<application>PMake</application> finishes, but if the target did
|
|
exist, it will appear to have been updated.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-v</option></term>
|
|
|
|
<listitem>
|
|
<para>Targets can still be created in parallel, however.
|
|
This is the mode <application>PMake</application> will enter
|
|
if it is invoked either as <command>smake</command> or
|
|
<command>vmake</command>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-x</option></term>
|
|
|
|
<listitem>
|
|
<para>This tells <application>PMake</application> it is OK to export
|
|
jobs to other machines, if they are available. It is used when
|
|
running in Make mode, as exporting in this mode tends to make
|
|
things run slower than if the commands were just executed
|
|
locally.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-B</option></term>
|
|
|
|
<listitem>
|
|
<para>Forces <application>PMake</application> to be as
|
|
backwards-compatible with <application>Make</application> as
|
|
possible while still being itself. This includes:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Executing one shell per shell command</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Expanding anything that looks even vaguely like a
|
|
variable, with the empty string replacing any variable
|
|
<application>PMake</application> does not know.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Refusing to allow you to escape a <literal>#</literal>
|
|
with a backslash.</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Permitting undefined variables on dependency lines and
|
|
conditionals (see below). Normally this causes
|
|
<application>PMake</application> to abort.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-C</option></term>
|
|
|
|
<listitem>
|
|
<para>This nullifies any and all compatibility mode flags you may
|
|
have given or implied up to the time the <option>-C</option> is
|
|
encountered. It is useful mostly in a makefile that you wrote for
|
|
<application>PMake</application> to avoid bad things happening
|
|
when someone runs <application>PMake</application> as
|
|
<application>make</application> or has things set in the
|
|
environment that tell it to be compatible.
|
|
<option>-C</option> is not placed in the <envar>PMAKE</envar>
|
|
environment variable or the <varname>.MAKEFLAGS</varname> or
|
|
<envar>MFLAGS</envar> global variables.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-D <replaceable>variable</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>Allows you to define a variable to have <quote>1</quote> as
|
|
its value. The variable is a global variable, not a command-line
|
|
variable. This is useful mostly for people who are used to the C
|
|
compiler arguments and those using conditionals, which I will get
|
|
into in <xref linkend="condition"/>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-I <replaceable>directory</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>Tells <application>PMake</application> another place to search
|
|
for included makefiles. Yet another thing to be explained in
|
|
<xref linkend="shortcuts"/> (<xref linkend="including"/>, to be
|
|
precise).</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-J <replaceable>number</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>Gives the absolute maximum number of targets to create at once
|
|
on both local and remote machines.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-L <replaceable>number</replaceable></option></term>
|
|
|
|
<listitem>
|
|
<para>This specifies the maximum number of targets to create on the
|
|
local machine at once.
|
|
This may be <literal>0</literal>, though you should be wary of
|
|
doing this, as <application>PMake</application> may hang until a
|
|
remote machine becomes available, if one is not available when it
|
|
is started.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-M</option></term>
|
|
|
|
<listitem>
|
|
<para>This is the flag that provides absolute, complete, full
|
|
compatibility with <application>Make</application>. It still
|
|
allows you to use all but a few of the features of
|
|
<application>PMake</application>, but it is non-parallel.
|
|
This is the mode <application>PMake</application> enters if you
|
|
call it <command>make</command>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-P</option></term>
|
|
|
|
<listitem>
|
|
<para>When creating targets in parallel, several shells are
|
|
executing at once, each wanting to write its own two cents'-worth
|
|
to the screen.
|
|
This output must be captured by <application>PMake</application>
|
|
in some way in order to prevent the screen from being filled with
|
|
garbage even more indecipherable than you usually see.
|
|
<application>PMake</application> has two ways of doing this, one
|
|
of which provides for much cleaner output and a clear separation
|
|
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 you when the creation
|
|
of a target starts, capturing the output and transferring it to
|
|
the screen all at once when the job finishes. 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 an indication of which job produced the output.
|
|
Since I prefer this second method, it is the one used by default.
|
|
The first method will be used if you give the <option>-P</option>
|
|
flag to <application>PMake</application>.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-V</option></term>
|
|
|
|
<listitem>
|
|
<para>As mentioned before, the <option>-V</option> flag tells
|
|
<application>PMake</application> to use
|
|
<application>Make</application>'s style of expanding variables,
|
|
substituting the empty string for any variable it does not
|
|
know.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-W</option></term>
|
|
|
|
<listitem>
|
|
<para>There are several times when <application>PMake</application>
|
|
will print a message at you that is only a warning, i.e. it
|
|
can continue to work in spite of your having done something silly
|
|
(such as forgotten a leading tab for a shell command). Sometimes
|
|
you are well aware of silly things you have done and would like
|
|
<application>PMake</application> to stop bothering you. This flag
|
|
tells it to shut up about anything non-fatal.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
<varlistentry>
|
|
<term><option>-X</option></term>
|
|
|
|
<listitem>
|
|
<para>This flag causes <application>PMake</application> to not
|
|
attempt to export any jobs to another machine.</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
</variablelist>
|
|
|
|
<para>Several flags may follow a single <literal>-</literal>. Those flags
|
|
that require arguments take them from successive parameters.
|
|
For example:</para>
|
|
|
|
<screen>pmake -fDnI server.mk DEBUG /chip2/X/server/include</screen>
|
|
|
|
<para>will cause <application>PMake</application> to read
|
|
<filename>server.mk</filename> as the input makefile,
|
|
define the variable <varname>DEBUG</varname> as a global variable and
|
|
look for included makefiles in the directory
|
|
<filename>/chip2/X/server/include</filename>.</para>
|
|
</section>
|
|
|
|
<section xml:id="summary">
|
|
<title>Summary</title>
|
|
|
|
<para>A makefile is made of four types of lines:</para>
|
|
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>Dependency lines</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Creation commands</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Variable assignments</para>
|
|
</listitem>
|
|
|
|
<listitem>
|
|
<para>Comments, include statements and conditional directives</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
|
|
<para>A dependency line is a list of one or more targets, an operator
|
|
(<literal>:</literal>, <literal>::</literal>, or <literal>!</literal>),
|
|
and a list of zero or more sources. Sources may contain wildcards and
|
|
certain local variables.</para>
|
|
|
|
<para>A creation command is a regular shell command preceded by a tab. In
|
|
addition, if the first two characters after the tab
|
|
(and other whitespace) are a combination of <literal>@</literal> or
|
|
<literal>-</literal>, <application>PMake</application> will cause the
|
|
command to not be printed (if the character is <literal>@</literal>) or
|
|
errors from it to be ignored (if <literal>-</literal>). A blank line,
|
|
dependency line or variable assignment terminates a creation script.
|
|
There may be only one creation script for each target with a
|
|
<literal>:</literal> or <literal>!</literal> operator.</para>
|
|
|
|
<para>Variables are places to store text. They may be unconditionally
|
|
assigned-to using the <literal>=</literal> operator, appended-to using
|
|
the <literal>+=</literal> operator, conditionally (if the variable is
|
|
undefined) assigned-to with the <literal>?=</literal> operator, and
|
|
assigned-to with variable expansion with the <literal>:=</literal>
|
|
operator. The output of a shell command may be assigned to a variable
|
|
using the <literal>!=</literal> operator. Variables may be expanded
|
|
(their value inserted) by enclosing their name in parentheses or curly
|
|
braces, preceded by a dollar sign. A dollar sign may be escaped with
|
|
another dollar sign. Variables are not expanded if
|
|
<application>PMake</application> does not know about them.
|
|
There are seven local variables: <varname>.TARGET</varname>,
|
|
<varname>.ALLSRC</varname>, <varname>.OODATE</varname>,
|
|
<varname>.PREFIX</varname>, <varname>.IMPSRC</varname>,
|
|
<varname>.ARCHIVE</varname>, and <varname>.MEMBER</varname>.
|
|
Four of them (<varname>.TARGET</varname>, <varname>.PREFIX</varname>,
|
|
<varname>.ARCHIVE</varname>, and <varname>.MEMBER</varname>) may be used
|
|
to specify <quote>dynamic sources</quote>. Variables are good. Know
|
|
them. Love them. Live them.</para>
|
|
|
|
<para>Debugging of makefiles is best accomplished using the
|
|
<option>-n</option>, <option>-d m</option>, and
|
|
<option>-p 2</option> flags.</para>
|
|
</section>
|
|
</chapter>
|