henesyinit from p9fd787fda5 years agoHistory
1594 lines · 37.5 KB · HTML
RawDownload
<html><title>data</title><body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#330088" ALINK="#FF0044"><H1>Maintaining Files on Plan 9 with Mk</H1><DL><DD><I>Andrew G. Hume<br>andrew@research.att.com<br>Bob Flandrena<br>bobf@plan9.bell-labs.com<br></I></DL><DL><DD><H4>ABSTRACT</H4><P><TT>Mk</TT>is a toolfor describing and maintaining dependencies betweenfiles.It is similar to theUNIX program<TT>make</TT>,but provides several extensions.<TT>Mk's</TT>flexible rule specifications, implieddependency derivation, and parallelexecution of maintenance actions arewell-suited to the Plan 9 environment.Almost all Plan 9 maintenance proceduresare automated using<TT>mk</TT>.</DL></P><H4>1 Introduction</H4><P>This document describes how<TT>mk</TT>,a program functionally similar to<TT>make</TT>[Feld79],is used to maintain dependencies betweenfiles in Plan 9.<TT>Mk</TT>provides several extensions to thecapabilities of its predecessor that workwell in Plan 9's distributed, multi-architectureenvironment.  Itexploits the power of multiprocessors by executingmaintenance actions in parallel and interacts withthe Plan 9 command interpreter<TT>rc</TT>to provide a powerful set of maintenance tools.It accepts pattern-based dependency specificationsthat are not limited to describingrules for program construction.The result is a tool that is flexible enough toperform many maintenance tasks includingdatabase maintenance,hardware design, and document production.</P><P>This document begins by discussing the syntax of the control file,the pattern matching capabilities, andthe special rules for maintaining archives.A brief description of<TT>mk's</TT>algorithm for deriving dependenciesis followed by a discussionof the conventions used to resolve ambiguousspecifications.  The final sectionsdescribe parallel executionand special features.</P><P>An earlier paper [Hume87]provides a detailed discussion of<TT>mk's</TT>design and an appendix summarizesthe differences between<TT>mk</TT>and<TT>make</TT>.</P><H4>2 The <TT>Mkfile</TT></H4><P><TT>Mk</TT>reads a file describing relationships among filesand executes commands to bring the files up to date.The specification file, called a<TT>mkfile</TT>,contains three types of statements:assignments, includes, and rules.Assignment and include statements are similarto those in C.Rules specify dependencies between a<I>target</I>and its<I>prerequisites</I>.When the target and prerequisites are files, theirmodification times determine if theyare out of date.  Rules often contain a<I>recipe</I>,an<A href="/magic/man2html/1/rc"><I>rc</I>(1)</A>script that produces the target fromthe prerequisites.</P><P>This simple<TT>mkfile</TT>produces an executablefrom a C source file:<DL><DT><DD><TT><PRE>CC=pccf1:	f1.c	$CC -o f1 f1.c</PRE></TT></DL>The first line assigns the name of the portable ANSI/POSIX compilerto the<TT>mk</TT>variable<TT>CC</TT>;subsequent references of the form<TT>$CC</TT>select this compiler.The only rule specifies a dependence between the target file<TT>f1</TT>and the prerequisite file<TT>f1.c</TT>.If the target does not exist or if theprerequisite has been modified more recently thanthe target,<TT>mk</TT>passes the recipe to<TT>rc</TT>for execution.  Here,<TT>f1.c</TT>is compiled and loaded to produce<TT>f1</TT>.</P><P>The native Plan 9 environmentrequires executables forall architectures, not only the current one.The Plan 9 version of the same<TT>mkfile</TT>looks like:<DL><DT><DD><TT><PRE>&#60;/$objtype/mkfile f1:	f1.$O	$LD $LDFLAGS -o f1 f1.$Of1.$O:	f1.c	$CC $CFLAGS f1.c</PRE></TT></DL>The first line is an include statementthat replaces itself with the contents of the file<TT>/$objtype/mkfile</TT>.The variable<TT>$objtype</TT>is inherited from the environment andcontains the name of the target architecture.The prototype<TT>mkfile</TT>for that architecture defines architecture-specific variables:<TT>CC</TT>and<TT>LD</TT>are the names of the compiler and loader,<TT>O</TT>is the code character of the architecture.The rules compile the source file into an objectfile and invoke the loader to produce<TT>f1</TT>.Invoking<TT>mk</TT>from the command line as follows<DL><DT><DD><TT><PRE>% objtype=mips mkvc -w f1.cvl $LDFLAGS -o f1 f1.k%</PRE></TT></DL>produces the<TT>mips</TT>executable of program<TT>f1</TT>regardless of the current architecture type.</P><P>We can extend the<TT>mkfile</TT>to build two programs:<DL><DT><DD><TT><PRE>&#60;/$objtype/mkfileALL=f1 f2 all:V:	$ALL f1:	f1.$O	$LD $LDFLAGS -o f1 f1.$Of1.$O:	f1.c	$CC $CFLAGS f1.cf2:	f2.$O	$LD $LDFLAGS -o f2 f2.$Of2.$O:	f2.c	$CC $CFLAGS f2.c</PRE></TT></DL>The target<TT>all</TT>,modified by the<I>attribute</I><TT>V</TT>,builds both programs.The attribute identifies <TT>all</TT>as a dummy target that isnot related to a file of the same name;its precise effect is explained later.This example describes cascading dependencies:the first target depends on another which depends on a third andso on.Here, individual rules build eachprogram; later we'll see how to do this with ageneral rule.</P><H4>3 Variables and the environment</H4><P><TT>Mk</TT>does not distinguish between itsinternal variables and<TT>rc</TT>variables in the environment.When<TT>mk</TT>starts, it imports each environment variable into a<TT>mk</TT>variable of the same name.  Before executing a recipe,<TT>mk</TT>exports all variables, including thoseinherited from the environment,to the environment in which<TT>rc</TT>executes the recipe.</P><P>There are several ways for avariable to take a value.It can be set with an assignment statement,inherited from the environment, or specifiedon the command line.<TT>Mk</TT>also maintains several special internal variablesthat are described in<A href="/magic/man2html/1/mk"><I>mk</I>(1).</A>Assignments have the following decreasing order of precedence:</P><br>&#32;<br><DL><DT><DD>1)  Command line assignment<br>2)  Assignment statement<br>3)  Imported from the environment<br>4)  Implicitly set by <TT>mk</TT></DL><br>&#32;<br>For example, a command line assignment overridesa value imported from the environment.<P>All variable values are strings.  They can beused for pattern matching andcomparison but not for arithmetic.A<I>list</I>is a string containing several values separated bywhite space.  Each member ishandled individually during pattern matching,target selection, and prerequisite evaluation.</P><P>A<I>namelist</I>is a list produced bytransforming the members of an existing list.The transform applies a pattern to each member,replacing each matched string with a new string,much as in the substitute command in<A href="/magic/man2html/1/sam"><I>sam</I>(1)</A>or<A href="/magic/man2html/1/ed"><I>ed</I>(1).</A>The syntax is<DL><DT><DD><TT><PRE>${<I>var</I>:A%B=C%D}</PRE></TT></DL>where<I>var</I>is a variable.The pattern<TT>A%B</TT>matches a member beginning with the string<I>A</I>and ending with the string<I>B</I>with any string in between;it behaves like the regular expression<TT>A.*B</TT>.When a member of the<I>var</I>listmatches this pattern,the string<I>C</I>replaces<I>A</I>,<I>D</I>replaces<I>B</I>,and the matched string replaces itself.Any of<I>A</I>,<I>B</I>,<I>C</I>,or<I>D</I>may be the empty string.  In effect, a namelist isgenerated by applying the<A href="/magic/man2html/1/ed"><I>ed</I>(1)</A>substitute command<DL><DT><DD><TT><PRE>	s/<I>A</I>(.*)<I>B</I>/<I>C</I>\1<I>D</I>/</PRE></TT></DL>to each member of a variable list.</P><P>Namelists are useful for generatinga list based on a predictable transformation.For example,<DL><DT><DD><TT><PRE>	SRC=a.c b.c c.c	OBJ=${SRC:%.c=%.v}</PRE></TT></DL>assigns the list <TT>(a.v b.v c.v)</TT> to<TT>OBJ</TT>.A namelist may be used anywhere a variable is allowedexcept in a recipe.</P><P>Command output is assigned to a variableusing the normal<TT>rc</TT>syntax:<DL><DT><DD><TT><PRE>	var=`{rc command}</PRE></TT></DL>The command executes in an environment populatedwith previously assigned variables, including thoseinherited from<TT>mk's</TT>execution environment.The command maybe arbitrarily complex; for example,<DL><DT><DD><TT><PRE>	TARG=`{ls -d *.[cy] | sed 's/..$//'}</PRE></TT></DL>assigns a list of the C and yacc source files in the currentdirectory, stripped of their suffix, to the variable<TT>TARG</TT>.</P><H4>4 The include statement</H4><P>The include statementreplaces itself with the contents of a file.It is functionally similar to the C<TT>#include</TT>statement but uses a different syntax:<DL><DT><DD><TT><PRE>	&#60;<I>filename</I></PRE></TT></DL>The contents of the file are evaluatedas they are read.An include statement may be used anywhere exceptin a recipe.</P><P>Unlike<TT>make</TT>,<TT>mk</TT>has no built-in rules.  Instead,the include statement allows generic rulesto be imported from a prototype<TT>mkfile</TT>;most Plan 9<TT>mkfiles</TT>use this approach [Flan95].</P><H4>5 Rules</H4><P>A rule has four elements: targets,prerequisites, attributes, and a recipe.It has the form:<DL><DT><DD><TT><PRE><I>targets</I>:<I>attributes</I>:<I>prerequisites</I>	<I>recipe</I></PRE></TT></DL>The first line, containing thetargets, attributes, and prerequisites isthe<I>rule header</I>;itmust begin at the left margin.The recipe contains zero or more lines,each of which begins with white space.One or more targets must be specified but theattributes, prerequisites, and recipe are optional.A rule specifiesa dependency between the target(s) and its prerequisite(s),the recipe brings the target(s)up to date with the prerequisite(s) andattributes modify<TT>mk's</TT>evaluation of the dependency.</P><P>Normally the target is a file that dependson one or more prerequisite files.<TT>Mk</TT>compares the modification times of each targetand each prerequisite; a target is considered out of datewhen it does not exist or when a prerequisite has been modifiedmore recently.When a target is out of date,<TT>mk</TT>executes therecipe to bring it up to date.When the recipe completes,the modification time of the target is checked andused in later dependency evaluations.If the recipe does not update the target,evaluation continues with the out of date target.</P><P>A prerequisite of one rulemay be the target of another.  Whenthis happens, the rules cascadeto define a multi-step procedure.For example,an executable target depends on prerequisiteobject files, each of which is a targetin a rule with a C source file as the prerequisite.<TT>Mk</TT>follows a chain of dependencies until it encountersa prerequisite that is not a target of another ruleor it finds a target thatis up to date.  It thenexecutes the recipes in reverse order to producethe desired target.</P><P>The rule header is evaluated when the rule is read.Variables are replaced by their values, namelists aregenerated, andcommands are replaced by theiroutput at this time.</P><P>Most attributes modify<TT>mk's</TT>evaluation of a rule.An attribute is usually a single letter but someare more complicated.This paper only discusses commonly used attributes;see<A href="/magic/man2html/1/mk"><I>mk</I>(1)</A>for a complete list.</P><P>The<TT>V</TT>attribute identifies a<I>virtual</I>target;that is, a target that is not a file.For example,<DL><DT><DD><TT><PRE>clean:V:	rm *.$O $O.out</PRE></TT></DL>removes executables and compiler intermediate files.The target is virtual because it does not refer to a file named<TT>clean</TT>.Without the attribute, the recipe would not beexecuted if a file named<TT>clean</TT>

Lines 1–500 of 1594.