Manual Page Result
0
Command: mk | Section: 1 | Source: UNIX v10 | File: mk.1
MK(1) General Commands Manual MK(1)
NAME
mk, mkconv, membername - maintain (make) related files
SYNOPSIS
mk [ -f mkfile ] ... [ option ... ] [ name ... ]
mkconv makefile
membername aggregate ...
DESCRIPTION
Mk is most often used to keep object files current with the source they
depend on.
Mk reads mkfile and builds and executes dependency dags (directed
acyclic graphs) for the target names. If no target is specified, the
targets of the first non-metarule in the first mkfile are used. If no
-f option is present, is tried. Other options are:
-a Assume all targets to be out of date. Thus, everything gets
made.
-d[egp] Produce debugging output (p is for parsing, g for graph build-
ing, e for execution).
-e Explain why each target is made.
-i Force any missing intermediate targets to be made.
-k Do as much work as possible in the face of errors.
-m Generate an equivalent makefile on standard output. Recipes
are not handled well.
-n Print, but do not execute, the commands needed to update the
targets.
-t Touch (update the modified date of) non-virtual targets, with-
out executing any recipes.
-u Produce a table of clock seconds spent with n recipes running.
-wname1,name2,...
Set the initial date stamp for each name to the current time.
The names may also be separated by blanks or newlines. (Use
with -n to find what else would need to change if the named
files were modified.)
Mkconv attempts to convert a make(1) makefile to a mkfile on standard
output. The conversion is not likely to be faithful.
The shell script membername extracts member names (see `Aggregates' be-
low) from its arguments.
Definitions
A mkfile consists of assignments (described under `Environment') and
rules. A rule contains targets and a tail. A target is a literal
string, or label, and is normally a file name. The tail contains zero
or more prerequisites and an optional recipe, which is a shell script.
A metarule has a target of the form A%B where A and B are (possibly
empty) strings. A metarule applies to any label that matches the tar-
get with % replaced by an arbitrary string, called the stem. In inter-
preting a metarule, the stem is substituted for all occurrences of % in
the prerequisite names. A metarule may be marked as using regular ex-
pressions (described under `Syntax'). In this case, % has no special
meaning; the target is interpreted according to regexp(3). The depen-
dencies may refer to subexpressions in the normal way, using \n. The
dependency dag for a target consists of nodes connected by directed
arcs. A node consists of a label and a set of arcs leading to prereq-
uisite nodes. The root node is labeled with an original target name.
Building the Dependency Dag
Read the mkfiles in command line order and distribute rule tails over
targets to get single-target rules.
For a node n, for every rule r that matches n's label generate an arc
to a prerequisite node. The node n is then marked as done. The
process is then repeated for each of the prerequisite nodes. The
process stops if n is already done, or if n has no prerequisites, or if
any rule would be used more than $NREP times on the current path in the
dag. A probable node is one where the label exists as a file or is a
target of a non-metarule.
After the graph is built, it is checked for cycles, and subdags con-
taining no probable nodes are deleted. Also, for any node with arcs
generated by a non-metarule with a recipe, arcs generated by a metarule
with a recipe are deleted. Disconnected subdags are deleted.
Execution
Labels have an associated date stamp. A label is ready if it has no
prerequisites, or all its prerequisites are made. A ready label is
trivially uptodate if it is not a target and has a nonzero date stamp,
or it has a nonzero date stamp, and all its prerequisites are made and
predate the ready label. A ready label is marked made (and given a
date stamp) if it is trivially uptodate or by executing the recipe as-
sociated with the arcs leading from the node associated with the ready
label. The P attribute can be used to generalize mk's notion of deter-
mining if prerequisites predate a label. Rather than comparing date
stamps, it executes a specified program and uses the exit status.
Date stamps are calculated differently for virtual labels, for labels
that correspond to extant files, and for other labels. If a label is
virtual (target of a rule with the V attribute), its date stamp is ini-
tially zero and upon being made is set to the most recent date stamp of
its prerequisites. Otherwise, if a label is nonexistent (does not ex-
ist as a file), its date stamp is set to the most recent date stamp of
its prerequisites, or zero if it has no prerequisites. Otherwise, the
label is the name of a file and the label's date stamp is always that
file's modification date.
Nonexistent labels which have prerequisites and are prerequisite to
other label(s) are treated specially unless the -i flag is used. Such
a label l is given the date stamp of its most recent prerequisite and
if this causes all the labels which have l as a prerequisite to be
trivially uptodate, l is considered to be trivially uptodate. Other-
wise, l is made in the normal fashion.
Two recipes are called identical if they arose by distribution from a
single rule as described above. Identical recipes may be executed only
when all their prerequisite nodes are ready, and then just one instance
of the identical recipes is executed to make all their target nodes.
Files may be made in any order that respects the preceding restric-
tions.
A recipe is executed by supplying the recipe as standard input to the
command
/bin/sh -e
The environment is augmented by the following variables:
$alltarget all the targets of this rule.
$newprereq the prerequisites that caused this rule to execute.
$nproc the process slot for this recipe. It satisfies
0<=$nproc<$NPROC, where $NPROC is the maximum number of
recipes that may be executing simultaneously.
$pid the process id for the mk forking the recipe.
$prereq all the prerequisites for this rule.
$stem if this is a metarule, $stem is the string that matched
%. Otherwise, it is empty. For regular expression
metarules, the variables are set to the corresponding
subexpressions.
$target the targets for this rule that need to be remade.
Unless the rule has the Q attribute, the recipe is printed prior to ex-
ecution with recognizable shell variables expanded. To see the com-
mands print as they execute, include a in your rule. Commands return-
ing nonzero status (see intro(1)) cause mk to terminate.
Aggregates
Names of the form a(b) refer to member b of the aggregate a. Cur-
rently, the only aggregates supported are ar(1) archives.
Environment
Rules may make use of shell (or environment) variables. A legal shell
variable reference of the form $OBJ or ${name} is expanded as in sh(1).
A reference of the form ${name:A%B=C%D}, where A, B, C, D are (possibly
empty) strings, has the value formed by expanding $name and substitut-
ing C for A and D for B in each word in $name that matches pattern A%B.
Variables can be set by assignments of the form
var=[attr=]tokens
where tokens and the optional attributes are defined under `Syntax' be-
low. The environment is exported to recipe executions. Variable val-
ues are taken from (in increasing order of precedence) the default val-
ues below, the environment, the mkfiles, and any command line assign-
ment. A variable assignment argument overrides the first (but not any
subsequent) assignment to that variable.
AS=as FFLAGS= NPROC=1
CC=cc LEX=lex NREP=1
CFLAGS= LFLAGS= YACC=yacc
FC=f77 LDFLAGS= YFLAGS=
BUILTINS='
%.o: %.c
$CC $CFLAGS -c $stem.c
%.o: %.s
$AS -o $stem.o $stem.s
%.o: %.f
$FC $FFLAGS -c $stem.f
%.o: %.y
$YACC $YFLAGS $stem.y &&
$CC $CFLAGS -c y.tab.c && mv y.tab.o $stem.o; rm y.tab.c
%.o: %.l
$LEX $LFLAGS -t $stem.l > $stem.c &&
$CC $CFLAGS -c $stem.c && rm $stem.c'
ENVIRON=
The builtin rules are obtained from the variable BUILTINS after all in-
put has been processed. The ENVIRON variable is split into parts at
control-A characters, the control-A characters are deleted, and the
parts are placed in the environment. The variable MKFLAGS contains all
the option arguments (arguments starting with or containing and MKARGS
contains all the targets in the call to mk.
Syntax
Leading white space (blank or tab) is ignored. Input after an unquoted
# (a comment) is ignored as are blank lines. Lines can be spread over
several physical lines by placing a \ before newlines to be elided.
Non-recipe lines are processed by substituting for `cmd` and then sub-
stituting for variable references. Finally, the filename metacharac-
ters []*? are expanded. Quoting by '', "", and \ is supported. The
semantics for substitution and quoting are given in sh(1).
The contents of files may be included by lines beginning with < fol-
lowed by a filename.
Assignments and rule header lines are distinguished by the first un-
quoted occurrence of : (rule header) or = (assignment).
A rule definition consists of a header line followed by a recipe. The
recipe consists of all lines following the header line that start with
white space. The recipe may be empty. The first character on every
line of the recipe is elided. The header line consists of at least one
target followed by the rule separator and a possibly empty list of pre-
requisites. The rule separator is either a single or is a immediately
followed by attributes and another If any prerequisite is more recent
than any of the targets, the recipe is executed. This meaning is modi-
fied by the following attributes
< The standard output of the recipe is read by mk as an additional
mkfile. Assignments take effect immediately. Rule definitions
are used when a new dependency dag is constructed.
D If the recipe exits with an error status, the target is deleted.
N If there is no recipe, the target has its time updated.
P The characters after the P until the terminating : are taken as
a program name. It will be invoked as sh -c prog 'arg1' 'arg2'
and should return 0 exit status if and only if arg1 is not out
of date with respect to arg2. Date stamps are still propagated
in the normal way.
Q The recipe is not printed prior to execution.
R The rule is a metarule using regular expressions.
U The targets are considered to have been updated even if the
recipe did not do so.
V The targets of this rule are marked as virtual. They are dis-
tinct from files of the same name.
Similarly, assignments may have attributes terminated by =. The only
assignment attribute is
U Do not export this variable to recipe executions.
EXAMPLES
A simple mkfile to compile a program.
prog: a.o b.o c.o
$CC $CFLAGS -o $target $prereq
Override flag settings in the mkfile.
$ mk target CFLAGS='-O -s'
To get the prerequisites for an aggregate.
$ membername 'libc.a(read.o)' 'libc.a(write.o)'
read.o write.o
Maintain a library.
libc.a(%.o):N:%.o
libc.a: libc.a(abs.o) libc.a(access.o) libc.a(alarm.o) ...
names=`membername $newprereq`
ar r libc.a $names && rm $names
Backquotes used to derive a list from a master list.
NAMES=alloc arc bquote builtins expand main match mk var word
OBJ=`echo $NAMES|sed -e 's/[^ ][^ ]*/&.o/g'`
Regular expression metarules. The single quotes are needed to protect
the \s.
'([^/]*)/(.*)\.o':R: '\1/\2.c'
cd $stem1; $CC $CFLAGS -c $stem2.c
A correct way to deal with yacc(1) grammars. The file lex.c includes
the file x.tab.h rather than y.tab.h in order to reflect changes in
content, not just modification time.
YFLAGS=-d
lex.o: x.tab.h
x.tab.h:y.tab.h
cmp -s x.tab.h y.tab.h || cp y.tab.h x.tab.h
y.tab.c y.tab.h:gram.y
$YACC $YFLAGS gram.y
The above example could also use the P attribute for the x.tab.h rule:
x.tab.h:Pcmp -s:y.tab.h
cp y.tab.h x.tab.h
SEE ALSO
make(1), chdate(1), sh(1), regexp(3)
A. Hume, `Mk: a Successor to Make', this manual, Volume 2
BUGS
Identical recipes for regular expression metarules only have one tar-
get.
Seemingly appropriate input like CFLAGS=-DHZ=60 is parsed as an erro-
neous attribute; correct it by inserting a space after the first
MK(1)