752 lines
18 KiB
Text
752 lines
18 KiB
Text
|
.HTML "Plan 9 Mkfiles
|
||
|
.TL
|
||
|
Plan 9 Mkfiles
|
||
|
.AU
|
||
|
Bob Flandrena
|
||
|
bobf@plan9.bell-labs.com
|
||
|
.SH
|
||
|
Introduction
|
||
|
.LP
|
||
|
Every Plan 9 source directory contains a file, called
|
||
|
.CW mkfile ,
|
||
|
specifying the rules for building the executable or
|
||
|
library that is the product of the directory.
|
||
|
.I Mk (1)
|
||
|
interprets the rules in the file, calculates
|
||
|
the dependencies, and executes an
|
||
|
.I rc (1)
|
||
|
script to construct the product.
|
||
|
If necessary components are supplied by
|
||
|
neighboring directories or sub-directories, the mkfiles in those
|
||
|
directories are first executed to build the components
|
||
|
before the local construction proceeds.
|
||
|
.LP
|
||
|
Most application source directories produce one of
|
||
|
four types of product:
|
||
|
a single executable, several
|
||
|
executables, a local library, or
|
||
|
a system library.
|
||
|
Four generic
|
||
|
mkfiles
|
||
|
define the normal rules
|
||
|
for building each type of product. The simplest
|
||
|
mkfiles need only
|
||
|
list the components
|
||
|
and include the appropriate
|
||
|
generic
|
||
|
mkfile
|
||
|
to do the work.
|
||
|
More complex
|
||
|
mkfiles
|
||
|
may supply additional rules
|
||
|
to augment, modify, or override the generic rules.
|
||
|
.SH
|
||
|
Using a Mkfile
|
||
|
.LP
|
||
|
To build a product, change to the directory containing
|
||
|
its source and invoke
|
||
|
.I mk
|
||
|
with the appropriate target as an argument.
|
||
|
All mkfiles provide the following standard targets:
|
||
|
.TS
|
||
|
lw(1i) lw(4.5i).
|
||
|
\f(CWall\fP T{
|
||
|
Build a local version of the product or products for the
|
||
|
current architecture. If the product is a single program,
|
||
|
the result is stored in file
|
||
|
.CW $O.out .
|
||
|
If the directory produces multiple executables, they are
|
||
|
stored in the files named
|
||
|
.CW $O.\fIprogname,\fP
|
||
|
where
|
||
|
.I progname
|
||
|
is the name of each executable.
|
||
|
A product may be built for a different architecture by
|
||
|
prefacing the
|
||
|
.CW mk
|
||
|
command with
|
||
|
\f(CWobjtype=\fP\fIarchitecture\fP,
|
||
|
where
|
||
|
.I architecture
|
||
|
is the name of the target architecture.
|
||
|
Directories producing system
|
||
|
libraries always operate directly on the installed version of the
|
||
|
library; in this case the target
|
||
|
.CW all
|
||
|
is equivalent to the target
|
||
|
.CW install .
|
||
|
T}
|
||
|
\f(CWinstall\fP T{
|
||
|
Build and install the product or products for the current
|
||
|
architecture.
|
||
|
T}
|
||
|
\f(CWinstallall\fP T{
|
||
|
Build and install the product or products for all architectures.
|
||
|
T}
|
||
|
\f(CWclean\fP T{
|
||
|
Rid the directory and its subdirectories of the by-products of
|
||
|
the build process. Intermediate files that are easily reproduced
|
||
|
(e.g., object files,
|
||
|
.CW yacc
|
||
|
intermediates, target executables) are always
|
||
|
removed. Complicated intermediates, such as local libraries, are
|
||
|
usually preserved.
|
||
|
T}
|
||
|
\f(CWnuke\fP T{
|
||
|
Remove all intermediates from the directory and any subdirectories.
|
||
|
This target guarantees that a subsequent build for the
|
||
|
architecture is performed
|
||
|
from scratch.
|
||
|
T}
|
||
|
.TE
|
||
|
.LP
|
||
|
If no target is specified on the
|
||
|
.CW mk
|
||
|
command line, the
|
||
|
.CW all
|
||
|
target is built by default. In a directory
|
||
|
producing multiple executables, there is
|
||
|
no default target.
|
||
|
.LP
|
||
|
In addition to the five standard targets,
|
||
|
additional targets may be supplied by each
|
||
|
generic mkfile or by the directory's mkfile.
|
||
|
.LP
|
||
|
The environment variable
|
||
|
.CW NPROC
|
||
|
is set by the system to the number of
|
||
|
available processors.
|
||
|
Setting
|
||
|
this variable, either in the environment or in
|
||
|
a mkfile, controls the amount of parallelism in
|
||
|
the build. For example, the command
|
||
|
.P1
|
||
|
NPROC=1 mk
|
||
|
.P2
|
||
|
restricts a build to a single thread of execution.
|
||
|
.SH
|
||
|
Creating a Mkfile
|
||
|
.LP
|
||
|
The easiest way to build a new mkfile is to copy and modify
|
||
|
an existing mkfile of the same type.
|
||
|
Failing that, it is usually possible to create a new
|
||
|
mkfile with minimal effort, since the appropriate
|
||
|
generic mkfile predefines the rules that do all the work.
|
||
|
In the simplest and most common cases, the new mkfile
|
||
|
need only define a couple of variables and include the appropriate
|
||
|
architecture-specific
|
||
|
and generic mkfiles.
|
||
|
.SH The Generic Mkfiles
|
||
|
.LP
|
||
|
There are four generic mkfiles containing commonly
|
||
|
used rules for building a product:
|
||
|
.CW mkone ,
|
||
|
.CW mkmany ,
|
||
|
.CW mklib ,
|
||
|
and
|
||
|
.CW mksyslib .
|
||
|
These rules
|
||
|
perform such actions as compiling C source files,
|
||
|
loading object files, archiving libraries, and
|
||
|
installing executables in the
|
||
|
.CW bin
|
||
|
directory of the appropriate architecture.
|
||
|
The generic mkfiles are stored in directory
|
||
|
.CW /sys/src/cmd .
|
||
|
Mkfile
|
||
|
.CW mkone
|
||
|
builds a single executable,
|
||
|
.CW mkmany
|
||
|
builds several executables from the source in a single
|
||
|
directory, and
|
||
|
.CW mklib
|
||
|
and
|
||
|
\f(CWmksyslib\fP,
|
||
|
maintain local and system libraries, respectively.
|
||
|
The rules in the generic mkfiles are driven by
|
||
|
the values of variables, some of which must be
|
||
|
set by the product mkfile and some of which are
|
||
|
supplied by the generic mkfile. Variables in the
|
||
|
latter class include:
|
||
|
.TS
|
||
|
center;
|
||
|
ri ci li
|
||
|
rw(1i) cw(0.5i) lw(2i).
|
||
|
Variable Default Meaning
|
||
|
.sp .5
|
||
|
\f(CWCFLAGS\fP \f(CW-FVw\fP C compiler flags
|
||
|
\f(CWLDFLAGS\fP Loader flags
|
||
|
\f(CWYFLAGS\fP \f(CW-d\fP Yacc flags
|
||
|
\f(CWAFLAGS\fP Assembler flags
|
||
|
.TE
|
||
|
.LP
|
||
|
The following variables are set by the product mkfile
|
||
|
and used by the generic mkfile.
|
||
|
Any may be empty depending on the specific product being
|
||
|
made.
|
||
|
.TS
|
||
|
center;
|
||
|
lw(1i) lw(2.5i).
|
||
|
\f(CWTARG\fP Name(s) of the executable(s) to be built
|
||
|
\f(CWLIB\fP Library name(s)
|
||
|
\f(CWOFILES\fP Object files
|
||
|
\f(CWHFILES\fP Header files included by all source files
|
||
|
\f(CWYFILES\fP \f(CWYacc\fP input files
|
||
|
\f(CWBIN\fP Directory where executables are installed
|
||
|
.TE
|
||
|
.SH
|
||
|
Mkfile Organization
|
||
|
.LP
|
||
|
All
|
||
|
mkfiles
|
||
|
share the following common structure:
|
||
|
.P1
|
||
|
</$objtype/mkfile # \f1architecture-dependent definitions\fP
|
||
|
.sp
|
||
|
\fIvariable definitions\fP # TARG\f1, \fPOFILES\f1, \fPHFILES\f1, etc.\fP
|
||
|
.sp
|
||
|
</sys/src/cmd/\fIgeneric\fP # mkone\f1, \fPmkmany\f1, \fPmklib\f1, or \fPmksyslib
|
||
|
.sp
|
||
|
\fIvariable overrides\fP # CFLAGS\f1, \fPobjtype\f1, etc.\fP
|
||
|
.sp
|
||
|
\fIextra rules\fP # \f1overrides, augmented rules, additional targets\fP
|
||
|
.P2
|
||
|
Note that the architecture-dependent mkfiles include file
|
||
|
.CW /sys/src/mkfile.proto
|
||
|
for system-wide variables that are common to all architectures.
|
||
|
.LP
|
||
|
The variables driving the expansion of the generic mkfile
|
||
|
may be specified in any order as long as they are defined
|
||
|
before the inclusion of the generic mkfile. The value
|
||
|
of a variable may be changed by assigning a new value
|
||
|
following the inclusion of the generic mkfile, but the
|
||
|
effects are sometimes counter-intuitive.
|
||
|
Such variable assignments do not apply to the target and
|
||
|
prerequisite portions of any previously defined rules;
|
||
|
the new values only apply to the recipes of rules preceding
|
||
|
the assignment statement and
|
||
|
to all parts of any rules following it.
|
||
|
.LP
|
||
|
The rules supplied by the generic mkfile may
|
||
|
be overridden or augmented. The new rules must
|
||
|
be specified after the inclusion of the generic
|
||
|
mkfile. If the target and prerequisite portion
|
||
|
of the rule exactly match the target and prerequisite
|
||
|
portion of a previously defined rule and the new rule contains
|
||
|
a recipe, the new rule replaces the old one.
|
||
|
If the target of a new rule exactly matches the
|
||
|
target of a previous rule and one or more new
|
||
|
prerequisites are specified and the new rule contains
|
||
|
no recipe, the new prerequisites are added to the prerequisites
|
||
|
of the old rule.
|
||
|
.LP
|
||
|
Following sections discuss
|
||
|
each generic mkfile in detail.
|
||
|
.SH
|
||
|
Mkone
|
||
|
.LP
|
||
|
The
|
||
|
.CW mkone
|
||
|
generic mkfile contains rules for building
|
||
|
a single executable from one or more files
|
||
|
in a directory.
|
||
|
The variable
|
||
|
.CW TARG
|
||
|
specifies the name of the executable and
|
||
|
variables
|
||
|
.CW OFILES
|
||
|
and
|
||
|
.CW YFILES
|
||
|
specify the object files and
|
||
|
.CW yacc
|
||
|
source files used to build it.
|
||
|
.CW HFILES
|
||
|
contains the names of the local header files
|
||
|
included in all source files.
|
||
|
.CW BIN
|
||
|
is the name of the directory where the executable
|
||
|
is installed.
|
||
|
.CW LIB
|
||
|
contains the names of local libraries used by the
|
||
|
linker. This variable is rarely needed
|
||
|
as libraries referenced by a
|
||
|
.CW #pragma
|
||
|
directive in an associated header file, including
|
||
|
all system libraries, are automatically
|
||
|
searched by the loader.
|
||
|
.LP
|
||
|
If
|
||
|
.CW mk
|
||
|
is executed without a target, the
|
||
|
.CW all
|
||
|
target is built; it
|
||
|
produces an executable in
|
||
|
.CW $O.out .
|
||
|
Variable
|
||
|
.CW HFILES
|
||
|
identifies the header files that
|
||
|
are included in all or most or
|
||
|
the C source files. Occasionally,
|
||
|
a program has other header files
|
||
|
that are only used in some
|
||
|
source files. A
|
||
|
header can be added to the prerequisites for
|
||
|
those object files by adding a rule of
|
||
|
the following form following the inclusion of generic mkfile
|
||
|
.CW mkone :
|
||
|
.P1
|
||
|
file.$O: header.h
|
||
|
.P2
|
||
|
.LP
|
||
|
The mkfile for a directory producing a single
|
||
|
executable using the normal set of rules is
|
||
|
trivial: a list of some files followed by the
|
||
|
inclusion of
|
||
|
.I mkone.
|
||
|
For example,
|
||
|
.CW /sys/src/cmd/diff/mkfile
|
||
|
contains:
|
||
|
.P1
|
||
|
< /$objtype/mkfile
|
||
|
|
||
|
TARG=diff
|
||
|
OFILES=\e
|
||
|
diffdir.$O\e
|
||
|
diffio.$O\e
|
||
|
diffreg.$O\e
|
||
|
main.$O\e
|
||
|
|
||
|
HFILES=diff.h
|
||
|
|
||
|
BIN=/$objtype/bin
|
||
|
</sys/src/cmd/mkone
|
||
|
.P2
|
||
|
The more complex mkfile in
|
||
|
.CW /sys/src/cmd/awk
|
||
|
overrides compiler and loader variables to
|
||
|
select the ANSI/POSIX Computing Environment with appropriately
|
||
|
defined command line variables. It also overrides
|
||
|
the default
|
||
|
.CW yacc
|
||
|
rule to place the output soure in file
|
||
|
.CW awkgram.c
|
||
|
and the
|
||
|
.CW clean
|
||
|
and
|
||
|
.CW nuke
|
||
|
rules, so it can remove the non-standard intermediate
|
||
|
files. Finally, the last three rules build a version of
|
||
|
.CW maketab
|
||
|
appropriate for the architecture where the
|
||
|
.CW mk
|
||
|
is being
|
||
|
run and then executes it to create source file
|
||
|
.CW proctab.c :
|
||
|
.P1
|
||
|
</$objtype/mkfile
|
||
|
|
||
|
TARG=awk
|
||
|
OFILES=re.$O\e
|
||
|
lex.$O\e
|
||
|
main.$O\e
|
||
|
parse.$O\e
|
||
|
proctab.$O\e
|
||
|
tran.$O\e
|
||
|
lib.$O\e
|
||
|
run.$O\e
|
||
|
awkgram.$O\e
|
||
|
|
||
|
HFILES=awk.h\e
|
||
|
y.tab.h\e
|
||
|
proto.h\e
|
||
|
|
||
|
YFILES=awkgram.y
|
||
|
|
||
|
BIN=/$objtype/bin
|
||
|
</sys/src/cmd/mkone
|
||
|
CFLAGS=-c -D_REGEXP_EXTENSION -D_RESEARCH_SOURCE \e
|
||
|
-D_BSD_EXTENSION -DUTF
|
||
|
YFLAGS=-S -d -v
|
||
|
CC=pcc
|
||
|
LD=pcc
|
||
|
cpuobjtype=`{sed -n 's/^O=//p' /$cputype/mkfile}
|
||
|
|
||
|
y.tab.h awkgram.c: $YFILES
|
||
|
$YACC -o awkgram.c $YFLAGS $prereq
|
||
|
|
||
|
clean:V:
|
||
|
rm -f *.[$OS] [$OS].out [$OS].maketab y.tab.? y.debug\e
|
||
|
y.output $TARG
|
||
|
|
||
|
nuke:V:
|
||
|
rm -f *.[$OS] [$OS].out [$OS].maketab y.tab.? y.debug\e
|
||
|
y.output awkgram.c $TARG
|
||
|
|
||
|
proctab.c: $cpuobjtype.maketab
|
||
|
./$cpuobjtype.maketab >proctab.c
|
||
|
|
||
|
$cpuobjtype.maketab: y.tab.h maketab.c
|
||
|
objtype=$cputype
|
||
|
mk maketab.$cputype
|
||
|
|
||
|
maketab.$cputype:V: y.tab.h maketab.$O
|
||
|
$LD -o $O.maketab maketab.$O
|
||
|
.P2
|
||
|
.SH
|
||
|
Mkmany
|
||
|
.LP
|
||
|
The
|
||
|
.CW mkmany
|
||
|
generic mkfile builds several
|
||
|
executables from the files in a
|
||
|
directory. It differs from the operation of
|
||
|
.CW mkone
|
||
|
in three respects:
|
||
|
.CW TARG
|
||
|
specifies the names of all executables,
|
||
|
there is no default command-line target,
|
||
|
and additional rules allow a single executable to
|
||
|
be built or installed.
|
||
|
.LP
|
||
|
The
|
||
|
.CW TARG
|
||
|
variable specifies the names of all
|
||
|
executables produced by the mkfile. The
|
||
|
rules assume the name of each executable is also
|
||
|
the name of the file containing its
|
||
|
.CW main
|
||
|
function.
|
||
|
.CW OFILES
|
||
|
specifies files containing
|
||
|
common subroutines loaded with all executables.
|
||
|
Consider the mkfile:
|
||
|
.P1
|
||
|
</$objtype/mkfile
|
||
|
|
||
|
TARG=alpha beta
|
||
|
OFILES=common.$O
|
||
|
BIN=/$objtype/bin
|
||
|
</sys/src/cmd/mkmany
|
||
|
.P2
|
||
|
It assumes the main functions for executables
|
||
|
.CW alpha
|
||
|
and
|
||
|
.CW beta
|
||
|
are in files
|
||
|
.CW alpha.$O
|
||
|
and
|
||
|
.CW beta.$O
|
||
|
and that both programs use the subroutines
|
||
|
in file
|
||
|
.CW common.$O .
|
||
|
The
|
||
|
.CW all
|
||
|
target builds all executables, leaving each in
|
||
|
a file with a name of the form
|
||
|
.CW $O.\fIprogname\fP
|
||
|
where
|
||
|
.I progname
|
||
|
is the name of the executable. In this
|
||
|
example the
|
||
|
.CW all
|
||
|
target produces executables
|
||
|
.CW $O.alpha
|
||
|
and
|
||
|
.CW $O.beta .
|
||
|
.LP
|
||
|
The
|
||
|
.CW mkmany
|
||
|
rules provide additional
|
||
|
targets for building a single
|
||
|
executable:
|
||
|
.TS
|
||
|
lw(1i) lw(3.8i).
|
||
|
\f(CW$O.progname\fP T{
|
||
|
Builds executable
|
||
|
\f(CW$O.\fP\fIprogname\fP
|
||
|
in the current directory. When the target
|
||
|
architecture is not the current architecture
|
||
|
the
|
||
|
.CW mk
|
||
|
command
|
||
|
must be prefixed with the customary
|
||
|
.CW objtype=\fIarchitecture\fP
|
||
|
assignment to select the proper compilers and loaders.
|
||
|
T}
|
||
|
\f(CWprogname.install\fP T{
|
||
|
Installs executable
|
||
|
.I progname
|
||
|
for the target architecture.
|
||
|
T}
|
||
|
\f(CWprogname.installall\fP T{
|
||
|
Installs executable
|
||
|
.I progname
|
||
|
for all architectures.
|
||
|
T}
|
||
|
.TE
|
||
|
.SH
|
||
|
Mklib
|
||
|
.LP
|
||
|
The
|
||
|
.CW mklib
|
||
|
generic mkfile builds a local library.
|
||
|
Since this form of mkfile constructs no
|
||
|
executable, the
|
||
|
.CW TARG
|
||
|
and
|
||
|
.CW BIN
|
||
|
variables are not needed. Instead, the
|
||
|
.CW LIB
|
||
|
variable specifies the library
|
||
|
to be built or updated. Variable
|
||
|
.CW OFILES
|
||
|
contains the names of the object files to be archived
|
||
|
in the library. The use of variables
|
||
|
.CW YFILES
|
||
|
and
|
||
|
.CW HFILES
|
||
|
does not change. When possible, only the
|
||
|
out-of-date members of the library are updated.
|
||
|
.LP
|
||
|
The variable
|
||
|
.CW LIBDIR
|
||
|
contains the name of the directory where the
|
||
|
library is installed; by default it selects
|
||
|
the current directory. It can be overridden
|
||
|
by assigning the new directory name after the
|
||
|
point where
|
||
|
.CW mklib
|
||
|
is included.
|
||
|
.LP
|
||
|
The
|
||
|
.CW clean
|
||
|
target removes object files and
|
||
|
.CW yacc
|
||
|
intermediate files but does not touch the
|
||
|
library. The
|
||
|
.CW nuke
|
||
|
target removes the library as well as the
|
||
|
files removed by the
|
||
|
.CW clean
|
||
|
target. The command
|
||
|
.RS
|
||
|
.CW "mk -s clean all"
|
||
|
.RE
|
||
|
causes the existing library to be updated, or
|
||
|
created if it doesn't already exist. The command
|
||
|
.RS
|
||
|
.CW "mk -s nuke all"
|
||
|
.RE
|
||
|
forces the library to be rebuilt from scratch.
|
||
|
.LP
|
||
|
The mkfile from
|
||
|
.CW /sys/src/cmd/upas/libString
|
||
|
contains the following specifications to
|
||
|
build the local library
|
||
|
.CW libString.a$O
|
||
|
for the object architecture referenced by
|
||
|
.CW $O\fR\:\fP
|
||
|
.P1
|
||
|
</$objtype/mkfile
|
||
|
|
||
|
LIB=libString.a$O
|
||
|
OFILES= s_alloc.$O\e
|
||
|
s_append.$O\e
|
||
|
s_array.$O\e
|
||
|
s_copy.$O\e
|
||
|
s_getline.$O\e
|
||
|
s_grow.$O\e
|
||
|
s_nappend.$O\e
|
||
|
s_parse.$O\e
|
||
|
s_read.$O\e
|
||
|
s_read_line.$O\e
|
||
|
s_tolower.$O\e
|
||
|
|
||
|
</sys/src/cmd/mklib
|
||
|
|
||
|
nuke:V:
|
||
|
mk clean
|
||
|
rm -f libString.a[$OS]
|
||
|
.P2
|
||
|
The override of the rule for target
|
||
|
.CW nuke
|
||
|
removes the libraries for all architectures as
|
||
|
opposed to the default recipe for this target
|
||
|
which removes the library for the current architecture.
|
||
|
.SH
|
||
|
Mksyslib
|
||
|
.LP
|
||
|
The
|
||
|
.CW mksyslib
|
||
|
generic mkfile is similar to the
|
||
|
.CW mklib
|
||
|
mkfile except that it operates on a system library
|
||
|
instead of a local library.
|
||
|
The
|
||
|
.CW install
|
||
|
and
|
||
|
.CW all
|
||
|
targets are the same; since there is no local copy of
|
||
|
the library, all updates are performed on the
|
||
|
installed library.
|
||
|
The rule for the
|
||
|
.CW nuke
|
||
|
target is identical to that of the
|
||
|
.CW clean
|
||
|
target; unlike the
|
||
|
.CW nuke
|
||
|
target for local libraries,
|
||
|
the library is never removed.
|
||
|
.LP
|
||
|
No attempt is made to determine if individual library
|
||
|
members are up-to-date; all members of a
|
||
|
library are always updated.
|
||
|
Special targets support manipulation of a single
|
||
|
object file; the target
|
||
|
.CW objfile
|
||
|
updates file
|
||
|
.CW objfile\f(CW.$O\fP
|
||
|
in the library of the current architecture and the target
|
||
|
.CW objfile.all
|
||
|
updates
|
||
|
.CW objfile\f(CW.$O\fP
|
||
|
in the libraries of all architectures.
|
||
|
.SH
|
||
|
Overrides
|
||
|
.LP
|
||
|
The rules provided by a generic mkfile or
|
||
|
the variables used to control the evaluation
|
||
|
of those rules may be overridden in most
|
||
|
circumstances. Overrides
|
||
|
must be specified in the product mkfile
|
||
|
after the point where the generic
|
||
|
mkfile is included; in general, variable
|
||
|
and rule overrides occupy the end of a
|
||
|
product mkfile.
|
||
|
.LP
|
||
|
The value of a variable is overridden by
|
||
|
assigning a new value to the variable.
|
||
|
Most variable overrides modify the
|
||
|
values of flags or the names of commands executed
|
||
|
in recipes. For example, the default value of
|
||
|
.CW CFLAGS
|
||
|
is often overridden or augmented and
|
||
|
the ANSI/POSIX Computing Environment is selected by
|
||
|
setting the
|
||
|
.CW CC
|
||
|
and
|
||
|
.CW LD
|
||
|
variables to
|
||
|
.CW pcc.
|
||
|
.LP
|
||
|
Modifying rules is trickier than modifying
|
||
|
variables. Additional constraints can be added
|
||
|
to a rule by specifying the target and
|
||
|
the new prerequisite. For example,
|
||
|
.P1
|
||
|
%.$O: header.h
|
||
|
.P2
|
||
|
adds file
|
||
|
.CW header.h
|
||
|
the set of prerequisites for all object files.
|
||
|
There is no mechanism for adding additional
|
||
|
commands to an existing recipe; if a
|
||
|
recipe is unsatisfactory, the rule and its recipe
|
||
|
must be completely overridden.
|
||
|
A rule is overridden only when the replacement rule
|
||
|
matches the target and prerequisite portions
|
||
|
of the original rule exactly. The recipe
|
||
|
associated with the new rule
|
||
|
then replaces the recipe of the original rule.
|
||
|
For example,
|
||
|
.CW /sys/src/cmd/lex/mkfile
|
||
|
overrides the default
|
||
|
.CW installall
|
||
|
rule to perform the normal loop on all
|
||
|
architectures and then copy a prototype file
|
||
|
to the system library directory.
|
||
|
.P1
|
||
|
</$objtype/mkfile
|
||
|
|
||
|
TARG=lex
|
||
|
OFILES=lmain.$O\e
|
||
|
y.tab.$O\e
|
||
|
sub1.$O\e
|
||
|
sub2.$O\e
|
||
|
header.$O\e
|
||
|
|
||
|
HFILES=ldefs.h\e
|
||
|
|
||
|
YFILES=parser.y\e
|
||
|
|
||
|
BIN=/$objtype/bin
|
||
|
</sys/src/cmd/mkone
|
||
|
|
||
|
installall:V:
|
||
|
for(objtype in $CPUS)
|
||
|
mk install
|
||
|
cp ncform /sys/lib/lex
|
||
|
.P2
|
||
|
Another way to perform the same override is to
|
||
|
add a dependency to the default
|
||
|
.CW installall
|
||
|
rule that executes an additional rule to
|
||
|
install the prototype file:
|
||
|
.P1
|
||
|
installall:V: ncform.install
|
||
|
|
||
|
ncform.install:V:
|
||
|
cp ncform /sys/lib/lex
|
||
|
.P2
|
||
|
.SH
|
||
|
Special Tricks
|
||
|
.LP
|
||
|
Two special cases
|
||
|
require extra deviousness.
|
||
|
.LP
|
||
|
In the first, a file needed to build an
|
||
|
executable is generated by a program that,
|
||
|
in turn, is built from a source file that
|
||
|
is not part of the product. In this case,
|
||
|
the
|
||
|
executable must be built for the
|
||
|
target architecture, but the intermediate
|
||
|
executable must be built for the architecture
|
||
|
.CW mk
|
||
|
is executing on. The intermediate executable
|
||
|
is built by recursively invoking
|
||
|
.CW mk
|
||
|
with the appropriate target and the
|
||
|
executing architecture as the target
|
||
|
architecture. When that
|
||
|
.CW mk
|
||
|
completes, the intermediate is
|
||
|
executed to generate the source file to
|
||
|
complete the build for the target architecture.
|
||
|
The earlier example of
|
||
|
.CW /sys/src/cmd/awk/mkfile
|
||
|
illustrates this technique.
|
||
|
.LP
|
||
|
Another awkward situation
|
||
|
occurs when a directory contains
|
||
|
source to build an executable as
|
||
|
well as source for auxiliary executables
|
||
|
that are not to be installed. In this case
|
||
|
the
|
||
|
.CW mkmany
|
||
|
generic rules are inappropriate, because
|
||
|
all executables would be built and installed.
|
||
|
Instead, use the
|
||
|
.CW mkone
|
||
|
generic file to build the primary executable
|
||
|
and provide extra targets to
|
||
|
build the auxiliary files. This
|
||
|
approach is also useful when the auxiliary
|
||
|
files are not executables;
|
||
|
.CW /sys/src/cmd/spell/mkfile
|
||
|
augments the default rules to build and install the
|
||
|
.CW spell
|
||
|
executable with
|
||
|
elaborate rules to generate
|
||
|
and maintain the auxiliary spelling lists.
|