1*46439007SCharles.Forsyth.TL 2*46439007SCharles.ForsythMaintaining Files on Plan 9 with Mk 3*46439007SCharles.Forsyth.AU 4*46439007SCharles.ForsythAndrew G. Hume 5*46439007SCharles.Forsythandrew@research.att.com 6*46439007SCharles.ForsythBob Flandrena 7*46439007SCharles.Forsythbobf@plan9.bell-labs.com 8*46439007SCharles.Forsyth.AB 9*46439007SCharles.Forsyth.PP 10*46439007SCharles.Forsyth.CW Mk 11*46439007SCharles.Forsythis a tool 12*46439007SCharles.Forsythfor describing and maintaining dependencies between 13*46439007SCharles.Forsythfiles. 14*46439007SCharles.ForsythIt is similar to the 15*46439007SCharles.ForsythUNIX program 16*46439007SCharles.Forsyth.CW make , 17*46439007SCharles.Forsythbut provides several new capabilities. 18*46439007SCharles.Forsyth.CW Mk\fR'\fPs 19*46439007SCharles.Forsythflexible rule specifications, implied 20*46439007SCharles.Forsythdependency derivation, and parallel 21*46439007SCharles.Forsythexecution of maintenance actions are 22*46439007SCharles.Forsythwell-suited to the Plan 9 environment. 23*46439007SCharles.ForsythAlmost all Plan 9 maintenance procedures 24*46439007SCharles.Forsythare automated using 25*46439007SCharles.Forsyth.CW mk . 26*46439007SCharles.Forsyth.AE 27*46439007SCharles.Forsyth.NH 1 28*46439007SCharles.ForsythIntroduction 29*46439007SCharles.Forsyth.PP 30*46439007SCharles.Forsyth.CW Mk 31*46439007SCharles.Forsythperforms the same task as 32*46439007SCharles.Forsyth.CW make 33*46439007SCharles.Forsyth[Feld79] but is different in many ways. 34*46439007SCharles.ForsythThis document describes 35*46439007SCharles.Forsyth.CW mk\fR'\fPs 36*46439007SCharles.Forsythcapabilities and discusses how they are 37*46439007SCharles.Forsythused in Plan 9. There are occasional references 38*46439007SCharles.Forsythto differences between 39*46439007SCharles.Forsyth.CW mk 40*46439007SCharles.Forsythand 41*46439007SCharles.Forsyth.CW make , 42*46439007SCharles.Forsythbut 43*46439007SCharles.Forsythan appendix summarizes the details. 44*46439007SCharles.Forsyth.PP 45*46439007SCharles.Forsyth.CW Mk 46*46439007SCharles.Forsythworks well in the Plan 9 environment. 47*46439007SCharles.ForsythIt supports program construction 48*46439007SCharles.Forsythin a heterogeneous environment and 49*46439007SCharles.Forsythexploits the power of multiprocessors by executing 50*46439007SCharles.Forsythmaintenance actions in parallel. 51*46439007SCharles.ForsythIt interacts seamlessly with the Plan 9 command 52*46439007SCharles.Forsythinterpreter 53*46439007SCharles.Forsyth.CW rc 54*46439007SCharles.Forsythand accepts pattern-based dependency specifications 55*46439007SCharles.Forsyththat are not limited to describing 56*46439007SCharles.Forsythrules for program construction. 57*46439007SCharles.ForsythThe result is a tool that is flexible enough to 58*46439007SCharles.Forsythperform many maintenance tasks including 59*46439007SCharles.Forsythdatabase maintenance, 60*46439007SCharles.Forsythhardware design, and document production. 61*46439007SCharles.Forsyth.PP 62*46439007SCharles.ForsythThis document begins by discussing 63*46439007SCharles.Forsyththe syntax of the input file, 64*46439007SCharles.Forsyththe pattern matching capabilities, and 65*46439007SCharles.Forsyththe special rules for maintaining archives. 66*46439007SCharles.ForsythA brief description of 67*46439007SCharles.Forsyth.CW mk\fR'\fPs 68*46439007SCharles.Forsythalgorithm for deriving dependencies 69*46439007SCharles.Forsythis followed by a discussion 70*46439007SCharles.Forsythof the conventions used to resolve ambiguous 71*46439007SCharles.Forsythspecifications. The final sections 72*46439007SCharles.Forsythdescribe parallel execution 73*46439007SCharles.Forsythand special features. 74*46439007SCharles.Forsyth.PP 75*46439007SCharles.ForsythAn earlier paper [Hume87] 76*46439007SCharles.Forsythprovides a detailed discussion of 77*46439007SCharles.Forsyth.CW mk\fR'\fPs 78*46439007SCharles.Forsythdesign. 79*46439007SCharles.Forsyth.NH 1 80*46439007SCharles.ForsythThe \f(CWMkfile\fP 81*46439007SCharles.Forsyth.PP 82*46439007SCharles.Forsyth.CW Mk 83*46439007SCharles.Forsythreads a file describing relationships among files 84*46439007SCharles.Forsythand executes commands to bring the files up to date. 85*46439007SCharles.ForsythThe specification file, called a 86*46439007SCharles.Forsyth.CW mkfile , 87*46439007SCharles.Forsythcontains three types of statements: 88*46439007SCharles.Forsythassignments, includes, and rules. 89*46439007SCharles.ForsythAssignment and include statements are similar 90*46439007SCharles.Forsythto those in C. 91*46439007SCharles.ForsythRules specify dependencies between a 92*46439007SCharles.Forsyth.I target 93*46439007SCharles.Forsythand its 94*46439007SCharles.Forsyth.I prerequisites . 95*46439007SCharles.ForsythWhen the target and prerequisites are files, their 96*46439007SCharles.Forsythmodification times determine if they 97*46439007SCharles.Forsythare out of date. Rules often contain a 98*46439007SCharles.Forsyth.I recipe , 99*46439007SCharles.Forsythan 100*46439007SCharles.Forsyth.I rc (1) 101*46439007SCharles.Forsythscript that produces the target from 102*46439007SCharles.Forsyththe prerequisites. 103*46439007SCharles.Forsyth.PP 104*46439007SCharles.ForsythThis simple 105*46439007SCharles.Forsyth.CW mkfile 106*46439007SCharles.Forsythproduces an executable 107*46439007SCharles.Forsythfrom a C source file: 108*46439007SCharles.Forsyth.P1 109*46439007SCharles.ForsythCC=pcc 110*46439007SCharles.Forsythf1: f1.c 111*46439007SCharles.Forsyth $CC -o f1 f1.c 112*46439007SCharles.Forsyth.P2 113*46439007SCharles.ForsythThe first line assigns the name of the portable ANSI/POSIX compiler 114*46439007SCharles.Forsythto the 115*46439007SCharles.Forsyth.CW mk 116*46439007SCharles.Forsythvariable 117*46439007SCharles.Forsyth.CW CC ; 118*46439007SCharles.Forsythsubsequent references of the form 119*46439007SCharles.Forsyth.CW $CC 120*46439007SCharles.Forsythselect this compiler. 121*46439007SCharles.ForsythThe only rule specifies a dependence between the target file 122*46439007SCharles.Forsyth.CW f1 123*46439007SCharles.Forsythand the prerequisite file 124*46439007SCharles.Forsyth.CW f1.c . 125*46439007SCharles.ForsythIf the target does not exist or if the 126*46439007SCharles.Forsythprerequisite has been modified more recently than 127*46439007SCharles.Forsyththe target, 128*46439007SCharles.Forsyth.CW mk 129*46439007SCharles.Forsythpasses the recipe to 130*46439007SCharles.Forsyth.CW rc 131*46439007SCharles.Forsythfor execution. Here, 132*46439007SCharles.Forsyth.CW f1.c 133*46439007SCharles.Forsythis compiled and loaded to produce 134*46439007SCharles.Forsyth.CW f1 . 135*46439007SCharles.Forsyth.PP 136*46439007SCharles.ForsythThe native Plan 9 environment 137*46439007SCharles.Forsythrequires executables for 138*46439007SCharles.Forsythall architectures, not only the current one. 139*46439007SCharles.ForsythThe Plan 9 version of the same 140*46439007SCharles.Forsyth.CW mkfile 141*46439007SCharles.Forsythlooks like: 142*46439007SCharles.Forsyth.P1 143*46439007SCharles.Forsyth</$objtype/mkfile 144*46439007SCharles.ForsythCFLAGS=-w 145*46439007SCharles.Forsyth 146*46439007SCharles.Forsythf1: f1.$O 147*46439007SCharles.Forsyth $LD $LDFLAGS -o f1 f1.$O 148*46439007SCharles.Forsythf1.$O: f1.c 149*46439007SCharles.Forsyth $CC $CFLAGS f1.c 150*46439007SCharles.Forsyth.P2 151*46439007SCharles.ForsythThe first line is an include statement 152*46439007SCharles.Forsyththat replaces itself with the contents of the file 153*46439007SCharles.Forsyth.CW /$objtype/mkfile . 154*46439007SCharles.ForsythThe variable 155*46439007SCharles.Forsyth.CW $objtype 156*46439007SCharles.Forsythis inherited from the environment and 157*46439007SCharles.Forsythcontains the name of the target architecture. 158*46439007SCharles.ForsythThe prototype 159*46439007SCharles.Forsyth.CW mkfile 160*46439007SCharles.Forsythfor that architecture defines architecture-specific variables: 161*46439007SCharles.Forsyth.CW CC 162*46439007SCharles.Forsythand 163*46439007SCharles.Forsyth.CW LD 164*46439007SCharles.Forsythare the names of the compiler and loader, 165*46439007SCharles.Forsyth.CW O 166*46439007SCharles.Forsythis the code character of the architecture. 167*46439007SCharles.ForsythThe rules compile the source file into an object 168*46439007SCharles.Forsythfile and invoke the loader to produce 169*46439007SCharles.Forsyth.CW f1 . 170*46439007SCharles.ForsythInvoking 171*46439007SCharles.Forsyth.CW mk 172*46439007SCharles.Forsythfrom the command line as follows 173*46439007SCharles.Forsyth.P1 174*46439007SCharles.Forsyth% objtype=sparc mk 175*46439007SCharles.Forsythkc -w f1.c 176*46439007SCharles.Forsythkl $LDFLAGS -o f1 f1.k 177*46439007SCharles.Forsyth% 178*46439007SCharles.Forsyth.P2 179*46439007SCharles.Forsythproduces the 180*46439007SCharles.Forsyth.CW sparc 181*46439007SCharles.Forsythexecutable of program 182*46439007SCharles.Forsyth.CW f1 183*46439007SCharles.Forsythregardless of the current architecture type. 184*46439007SCharles.Forsyth.PP 185*46439007SCharles.ForsythWe can extend the 186*46439007SCharles.Forsyth.CW mkfile 187*46439007SCharles.Forsythto build two programs: 188*46439007SCharles.Forsyth.P1 189*46439007SCharles.Forsyth</$objtype/mkfile 190*46439007SCharles.ForsythCFLAGS=-w 191*46439007SCharles.ForsythALL=f1 f2 192*46439007SCharles.Forsyth 193*46439007SCharles.Forsythall:V: $ALL 194*46439007SCharles.Forsyth 195*46439007SCharles.Forsythf1: f1.$O 196*46439007SCharles.Forsyth $LD $LDFLAGS -o f1 f1.$O 197*46439007SCharles.Forsythf1.$O: f1.c 198*46439007SCharles.Forsyth $CC $CFLAGS f1.c 199*46439007SCharles.Forsythf2: f2.$O 200*46439007SCharles.Forsyth $LD $LDFLAGS -o f2 f2.$O 201*46439007SCharles.Forsythf2.$O: f2.c 202*46439007SCharles.Forsyth $CC $CFLAGS f2.c 203*46439007SCharles.Forsyth.P2 204*46439007SCharles.ForsythThe target 205*46439007SCharles.Forsyth.CW all , 206*46439007SCharles.Forsythmodified by the 207*46439007SCharles.Forsyth.I attribute 208*46439007SCharles.Forsyth.CW V , 209*46439007SCharles.Forsythbuilds both programs. 210*46439007SCharles.ForsythThe attribute identifies 211*46439007SCharles.Forsyth.CW all 212*46439007SCharles.Forsythas a dummy target that is 213*46439007SCharles.Forsythnot related to a file of the same name; 214*46439007SCharles.Forsythits precise effect is explained later. 215*46439007SCharles.ForsythThis example describes cascading dependencies: 216*46439007SCharles.Forsyththe first target depends on another which depends on a third and 217*46439007SCharles.Forsythso on. 218*46439007SCharles.ForsythHere, individual rules build each 219*46439007SCharles.Forsythprogram; later we'll see how to do this with a 220*46439007SCharles.Forsythgeneral rule. 221*46439007SCharles.Forsyth.NH 1 222*46439007SCharles.ForsythVariables and the environment 223*46439007SCharles.Forsyth.PP 224*46439007SCharles.Forsyth.CW Mk 225*46439007SCharles.Forsythdoes not distinguish between its 226*46439007SCharles.Forsythvariables and 227*46439007SCharles.Forsyth.CW rc 228*46439007SCharles.Forsythvariables in the environment. 229*46439007SCharles.ForsythWhen 230*46439007SCharles.Forsyth.CW mk 231*46439007SCharles.Forsythstarts, it imports each environment variable into a 232*46439007SCharles.Forsyth.CW mk 233*46439007SCharles.Forsythvariable of the same name. Before executing a recipe, 234*46439007SCharles.Forsyth.CW mk 235*46439007SCharles.Forsythexports all variables, including those 236*46439007SCharles.Forsythinherited from the environment, 237*46439007SCharles.Forsythto the environment in which 238*46439007SCharles.Forsyth.CW rc 239*46439007SCharles.Forsythexecutes the recipe. 240*46439007SCharles.Forsyth.PP 241*46439007SCharles.ForsythThere are several ways for a 242*46439007SCharles.Forsythvariable to take a value. 243*46439007SCharles.ForsythIt can be set with an assignment statement, 244*46439007SCharles.Forsythinherited from the environment, or specified 245*46439007SCharles.Forsython the command line. 246*46439007SCharles.Forsyth.CW Mk 247*46439007SCharles.Forsythalso maintains several internal variables; 248*46439007SCharles.Forsyththese variables are described in 249*46439007SCharles.Forsyth.I mk (1). 250*46439007SCharles.ForsythAssignments have the following decreasing order of precedence: 251*46439007SCharles.Forsyth.LP 252*46439007SCharles.Forsyth.in .7i 253*46439007SCharles.Forsyth1) Command line assignment 254*46439007SCharles.Forsyth.br 255*46439007SCharles.Forsyth2) Assignment statement 256*46439007SCharles.Forsyth.br 257*46439007SCharles.Forsyth3) Imported from the environment 258*46439007SCharles.Forsyth.br 259*46439007SCharles.Forsyth4) Implicitly set by \f(CWmk\fP 260*46439007SCharles.Forsyth.in 0 261*46439007SCharles.Forsyth.LP 262*46439007SCharles.ForsythFor example, a command line assignment overrides 263*46439007SCharles.Forsytha value imported from the environment. 264*46439007SCharles.Forsyth.PP 265*46439007SCharles.ForsythAll variable values are strings. They can be 266*46439007SCharles.Forsythused for pattern matching and 267*46439007SCharles.Forsythcomparison but not for arithmetic. 268*46439007SCharles.ForsythA 269*46439007SCharles.Forsyth.I list 270*46439007SCharles.Forsythis a string containing several values separated by 271*46439007SCharles.Forsythwhite space. Each member is 272*46439007SCharles.Forsythhandled individually during pattern matching, 273*46439007SCharles.Forsythtarget selection, and prerequisite evaluation. 274*46439007SCharles.Forsyth.PP 275*46439007SCharles.ForsythA 276*46439007SCharles.Forsyth.I namelist 277*46439007SCharles.Forsythis a list produced by 278*46439007SCharles.Forsythtransforming the members of an existing list. 279*46439007SCharles.ForsythThe transform applies a pattern to each member, 280*46439007SCharles.Forsythreplacing each matched string with a new string, 281*46439007SCharles.Forsythmuch as in the substitute command in 282*46439007SCharles.Forsyth.I sam (1) 283*46439007SCharles.Forsythor 284*46439007SCharles.Forsyth.I ed (1). 285*46439007SCharles.ForsythThe syntax is 286*46439007SCharles.Forsyth.P1 287*46439007SCharles.Forsyth${\fIvar\fP:A%B=C%D} 288*46439007SCharles.Forsyth.P2 289*46439007SCharles.Forsythwhere 290*46439007SCharles.Forsyth.I var 291*46439007SCharles.Forsythis a variable. 292*46439007SCharles.ForsythThe pattern 293*46439007SCharles.Forsyth.CW A%B 294*46439007SCharles.Forsythmatches a member beginning with the string 295*46439007SCharles.Forsyth.I A 296*46439007SCharles.Forsythand ending with the string 297*46439007SCharles.Forsyth.I B 298*46439007SCharles.Forsythwith any string in between; 299*46439007SCharles.Forsythit behaves like the regular expression 300*46439007SCharles.Forsyth.CW A.*B . 301*46439007SCharles.ForsythWhen a member of the 302*46439007SCharles.Forsyth.I var 303*46439007SCharles.Forsythlist 304*46439007SCharles.Forsythmatches this pattern, 305*46439007SCharles.Forsyththe string 306*46439007SCharles.Forsyth.I C 307*46439007SCharles.Forsythreplaces 308*46439007SCharles.Forsyth.I A , 309*46439007SCharles.Forsyth.I D 310*46439007SCharles.Forsythreplaces 311*46439007SCharles.Forsyth.I B , 312*46439007SCharles.Forsythand the matched string replaces itself. 313*46439007SCharles.ForsythAny of 314*46439007SCharles.Forsyth.I A , 315*46439007SCharles.Forsyth.I B , 316*46439007SCharles.Forsyth.I C , 317*46439007SCharles.Forsythor 318*46439007SCharles.Forsyth.I D 319*46439007SCharles.Forsythmay be the empty string. In effect, a namelist is 320*46439007SCharles.Forsythgenerated by applying the 321*46439007SCharles.Forsyth.I ed (1) 322*46439007SCharles.Forsythsubstitute command 323*46439007SCharles.Forsyth.P1 324*46439007SCharles.Forsyth s/\fIA\fP(.*)\fIB\fP/\fIC\fP\e1\fID\fP/ 325*46439007SCharles.Forsyth.P2 326*46439007SCharles.Forsythto each member of a variable. 327*46439007SCharles.Forsyth.PP 328*46439007SCharles.ForsythNamelists are useful for generating 329*46439007SCharles.Forsytha list based on a predictable transformation. 330*46439007SCharles.ForsythFor example, 331*46439007SCharles.Forsyth.P1 332*46439007SCharles.Forsyth SRC=a.c b.c c.c 333*46439007SCharles.Forsyth OBJ=${SRC:%.c=%.v} 334*46439007SCharles.Forsyth.P2 335*46439007SCharles.Forsythassigns the list \f(CW(a.v b.v c.v)\fP to 336*46439007SCharles.Forsyth.CW OBJ . 337*46439007SCharles.ForsythA namelist may be used anywhere a variable is allowed 338*46439007SCharles.Forsythexcept in a recipe. 339*46439007SCharles.Forsyth.PP 340*46439007SCharles.ForsythCommand output is assigned to a variable 341*46439007SCharles.Forsythusing the normal 342*46439007SCharles.Forsyth.CW rc 343*46439007SCharles.Forsythsyntax: 344*46439007SCharles.Forsyth.P1 345*46439007SCharles.Forsyth var=`{rc command} 346*46439007SCharles.Forsyth.P2 347*46439007SCharles.ForsythThe command executes in an environment populated 348*46439007SCharles.Forsythwith previously assigned variables, including those 349*46439007SCharles.Forsythinherited from 350*46439007SCharles.Forsyth.CW mk\fR'\fPs 351*46439007SCharles.Forsythexecution environment. 352*46439007SCharles.ForsythThe command may 353*46439007SCharles.Forsythbe arbitrarily complex; for example, 354*46439007SCharles.Forsyth.P1 355*46439007SCharles.Forsyth TARG=`{ls -d *.[cyl] | sed 's/..$//'} 356*46439007SCharles.Forsyth.P2 357*46439007SCharles.Forsythassigns a list of the C, yacc, and Alef source files in the current 358*46439007SCharles.Forsythdirectory, stripped of their suffix, to the variable 359*46439007SCharles.Forsyth.CW TARG . 360*46439007SCharles.Forsyth.NH 1 361*46439007SCharles.ForsythThe include statement 362*46439007SCharles.Forsyth.PP 363*46439007SCharles.ForsythThe include statement 364*46439007SCharles.Forsythreplaces itself with the contents of a file. 365*46439007SCharles.ForsythIt is functionally similar to the C 366*46439007SCharles.Forsyth.CW #include 367*46439007SCharles.Forsythstatement but uses a different syntax: 368*46439007SCharles.Forsyth.P1 369*46439007SCharles.Forsyth <\fIfilename\fP 370*46439007SCharles.Forsyth.P2 371*46439007SCharles.ForsythThe contents of the file are evaluated 372*46439007SCharles.Forsythas they are read. 373*46439007SCharles.ForsythAn include statement may be used anywhere except 374*46439007SCharles.Forsythin a recipe. 375*46439007SCharles.Forsyth.PP 376*46439007SCharles.ForsythUnlike 377*46439007SCharles.Forsyth.CW make , 378*46439007SCharles.Forsyth.CW mk 379*46439007SCharles.Forsythhas no built-in rules. Instead, 380*46439007SCharles.Forsyththe include statement allows generic rules 381*46439007SCharles.Forsythto be imported from a prototype 382*46439007SCharles.Forsyth.CW mkfile ; 383*46439007SCharles.Forsythmost Plan 9 384*46439007SCharles.Forsyth.CW mkfiles 385*46439007SCharles.Forsythuse this approach [Flan95]. 386*46439007SCharles.Forsyth.NH 1 387*46439007SCharles.ForsythRules 388*46439007SCharles.Forsyth.PP 389*46439007SCharles.ForsythA rule has four elements: targets, 390*46439007SCharles.Forsythprerequisites, attributes, and a recipe. 391*46439007SCharles.ForsythIt has the form: 392*46439007SCharles.Forsyth.P1 393*46439007SCharles.Forsyth\fItargets\fP:\fIattributes\fP:\fIprerequisites\fP 394*46439007SCharles.Forsyth \fIrecipe\fP 395*46439007SCharles.Forsyth.P2 396*46439007SCharles.ForsythThe first line, containing the 397*46439007SCharles.Forsythtargets, attributes, and prerequisites is 398*46439007SCharles.Forsyththe 399*46439007SCharles.Forsyth.I "rule header" ; 400*46439007SCharles.Forsythit 401*46439007SCharles.Forsythmust begin at the left margin. 402*46439007SCharles.ForsythThe recipe contains zero or more lines, 403*46439007SCharles.Forsytheach of which begins with white space. 404*46439007SCharles.ForsythOne or more targets must be specified but the 405*46439007SCharles.Forsythattributes, prerequisites, and recipe are optional. 406*46439007SCharles.ForsythA rule specifies 407*46439007SCharles.Forsytha dependency between the targets and the prerequisites; 408*46439007SCharles.Forsyththe recipe brings the targets 409*46439007SCharles.Forsythup to date with the prerequisites. 410*46439007SCharles.ForsythAttributes modify 411*46439007SCharles.Forsyth.CW mk\fR'\fPs 412*46439007SCharles.Forsythevaluation of a rule. 413*46439007SCharles.Forsyth.PP 414*46439007SCharles.ForsythNormally the target is a file that depends 415*46439007SCharles.Forsython one or more prerequisite files. 416*46439007SCharles.Forsyth.CW Mk 417*46439007SCharles.Forsythcompares the modification times of each target 418*46439007SCharles.Forsythand each prerequisite; a target is considered out of date 419*46439007SCharles.Forsythwhen it does not exist or when a prerequisite has been modified 420*46439007SCharles.Forsythmore recently. 421*46439007SCharles.ForsythWhen a target is out of date, 422*46439007SCharles.Forsyth.CW mk 423*46439007SCharles.Forsythexecutes the 424*46439007SCharles.Forsythrecipe to bring it up to date. 425*46439007SCharles.ForsythWhen the recipe completes, 426*46439007SCharles.Forsyththe modification time of the target is checked and 427*46439007SCharles.Forsythused in later dependency evaluations. 428*46439007SCharles.ForsythIf the recipe does not update the target, 429*46439007SCharles.Forsythevaluation continues with the out of date target. 430*46439007SCharles.Forsyth.PP 431*46439007SCharles.ForsythA prerequisite of one rule 432*46439007SCharles.Forsythmay be the target of another. When 433*46439007SCharles.Forsyththis happens, the rules cascade 434*46439007SCharles.Forsythto define a multi-step procedure. 435*46439007SCharles.ForsythFor example, 436*46439007SCharles.Forsythan executable target depends on prerequisite 437*46439007SCharles.Forsythobject files, each of which is a target 438*46439007SCharles.Forsythin a rule with a C source file as the prerequisite. 439*46439007SCharles.Forsyth.CW Mk 440*46439007SCharles.Forsythfollows a chain of dependencies until it encounters 441*46439007SCharles.Forsytha prerequisite that is not a target of another rule 442*46439007SCharles.Forsythor it finds a target that 443*46439007SCharles.Forsythis up to date. It then 444*46439007SCharles.Forsythexecutes the recipes in reverse order to produce 445*46439007SCharles.Forsyththe desired target. 446*46439007SCharles.Forsyth.PP 447*46439007SCharles.ForsythThe rule header is evaluated when the rule is read. 448*46439007SCharles.ForsythVariables are replaced by their values, namelists are 449*46439007SCharles.Forsythgenerated, and 450*46439007SCharles.Forsythcommands are replaced by their 451*46439007SCharles.Forsythoutput at this time. 452*46439007SCharles.Forsyth.PP 453*46439007SCharles.ForsythMost attributes modify 454*46439007SCharles.Forsyth.CW mk\fR'\fPs 455*46439007SCharles.Forsythevaluation of a rule. 456*46439007SCharles.ForsythAn attribute is usually a single letter but some 457*46439007SCharles.Forsythare more complicated. 458*46439007SCharles.ForsythThis paper only discusses commonly used attributes; 459*46439007SCharles.Forsythsee 460*46439007SCharles.Forsyth.I mk (1) 461*46439007SCharles.Forsythfor a complete list. 462*46439007SCharles.Forsyth.PP 463*46439007SCharles.ForsythThe 464*46439007SCharles.Forsyth.CW V 465*46439007SCharles.Forsythattribute identifies a 466*46439007SCharles.Forsyth.I virtual 467*46439007SCharles.Forsythtarget; 468*46439007SCharles.Forsyththat is, a target that is not a file. 469*46439007SCharles.ForsythFor example, 470*46439007SCharles.Forsyth.P1 471*46439007SCharles.Forsythclean:V: 472*46439007SCharles.Forsyth rm *.$O $O.out 473*46439007SCharles.Forsyth.P2 474*46439007SCharles.Forsythremoves executables and compiler intermediate files. 475*46439007SCharles.ForsythThe target is virtual because it does not refer to a file named 476*46439007SCharles.Forsyth.CW clean . 477*46439007SCharles.ForsythWithout the attribute, the recipe would not be 478*46439007SCharles.Forsythexecuted if a file named 479*46439007SCharles.Forsyth.CW clean 480*46439007SCharles.Forsythexisted. 481*46439007SCharles.ForsythThe 482*46439007SCharles.Forsyth.CW Q 483*46439007SCharles.Forsythsilences the default printing of a recipe before 484*46439007SCharles.Forsythit is executed. 485*46439007SCharles.ForsythIt is useful when the output of a recipe is 486*46439007SCharles.Forsythsimilar to the recipe: 487*46439007SCharles.Forsyth.P1 488*46439007SCharles.Forsythdefault:QV: 489*46439007SCharles.Forsyth echo 'No default target; use mk all or mk install' 490*46439007SCharles.Forsyth.P2 491*46439007SCharles.Forsyth.PP 492*46439007SCharles.ForsythA recipe is an 493*46439007SCharles.Forsyth.CW rc 494*46439007SCharles.Forsythscript. The recipe is optional; when it is 495*46439007SCharles.Forsythmissing, the rule is handled specially, as described later. 496*46439007SCharles.ForsythUnlike 497*46439007SCharles.Forsyth.CW make , 498*46439007SCharles.Forsyth.CW mk 499*46439007SCharles.Forsythexecutes recipes without interpretation. 500*46439007SCharles.ForsythAfter 501*46439007SCharles.Forsythstripping the first white space character from each line 502*46439007SCharles.Forsythit passes the entire recipe to 503*46439007SCharles.Forsyth.CW rc 504*46439007SCharles.Forsython standard input. 505*46439007SCharles.ForsythSince 506*46439007SCharles.Forsyth.CW mk 507*46439007SCharles.Forsythdoes not interpret a recipe, 508*46439007SCharles.Forsythescape conventions are exactly those of 509*46439007SCharles.Forsyth.CW rc . 510*46439007SCharles.ForsythScripts for 511*46439007SCharles.Forsyth.CW awk 512*46439007SCharles.Forsythand 513*46439007SCharles.Forsyth.CW sed 514*46439007SCharles.Forsythcommands can be embedded just as they would 515*46439007SCharles.Forsythbe specified from the command line. 516*46439007SCharles.Forsyth.CW Mk 517*46439007SCharles.Forsythinvokes 518*46439007SCharles.Forsyth.CW rc 519*46439007SCharles.Forsythwith the 520*46439007SCharles.Forsyth.CW -e 521*46439007SCharles.Forsythflag, which causes 522*46439007SCharles.Forsyth.CW rc 523*46439007SCharles.Forsythto stop if any command 524*46439007SCharles.Forsythin the recipe exits with a non-zero status; the 525*46439007SCharles.Forsyth.CW E 526*46439007SCharles.Forsythattribute overrides this behavior and allows 527*46439007SCharles.Forsyth.CW rc 528*46439007SCharles.Forsythto continue executing in the face of errors. 529*46439007SCharles.ForsythBefore a recipe is executed, variables are exported 530*46439007SCharles.Forsythto the environment where 531*46439007SCharles.Forsyth.CW rc 532*46439007SCharles.Forsythcan see them. 533*46439007SCharles.ForsythRecipe commands may not read from 534*46439007SCharles.Forsythstandard input because 535*46439007SCharles.Forsyth.CW mk 536*46439007SCharles.Forsythuses it internally. 537*46439007SCharles.Forsyth.PP 538*46439007SCharles.ForsythReferences to a variable can yield different 539*46439007SCharles.Forsythvalues depending on the location of the 540*46439007SCharles.Forsythreference in the 541*46439007SCharles.Forsyth.CW mkfile . 542*46439007SCharles.Forsyth.CW Mk 543*46439007SCharles.Forsythresolves variable references 544*46439007SCharles.Forsythin assignment statements and rule headers 545*46439007SCharles.Forsythwhen the statement is read. Variable references 546*46439007SCharles.Forsythin recipes are evaluated by 547*46439007SCharles.Forsyth.CW rc 548*46439007SCharles.Forsythwhen the recipe is executed; this 549*46439007SCharles.Forsythhappens after the entire 550*46439007SCharles.Forsyth.CW mkfile 551*46439007SCharles.Forsythhas been read. The value of a variable in a recipe 552*46439007SCharles.Forsythis the last value assigned in the file. For example, 553*46439007SCharles.Forsyth.P1 554*46439007SCharles.ForsythSTRING=all 555*46439007SCharles.Forsyth 556*46439007SCharles.Forsythall:VQ: 557*46439007SCharles.Forsyth echo $STRING 558*46439007SCharles.ForsythSTRING=none 559*46439007SCharles.Forsyth.P2 560*46439007SCharles.Forsythproduces the message 561*46439007SCharles.Forsyth.CW none . 562*46439007SCharles.ForsythA variable assignment in a recipe 563*46439007SCharles.Forsythdoes not affect the value of the variable in the 564*46439007SCharles.Forsyth.CW mkfile 565*46439007SCharles.Forsythfor two reasons. 566*46439007SCharles.ForsythFirst, 567*46439007SCharles.Forsyth.CW mk 568*46439007SCharles.Forsythdoes not import values from 569*46439007SCharles.Forsyththe environment when a recipe completes; 570*46439007SCharles.Forsythone recipe cannot pass a value through 571*46439007SCharles.Forsyththe environment to another recipe. 572*46439007SCharles.ForsythSecond, no recipe is executed until 573*46439007SCharles.Forsyth.CW mk 574*46439007SCharles.Forsythhas completed its evaluation, so even if a variable 575*46439007SCharles.Forsythwere changed, 576*46439007SCharles.Forsythit would not affect the dependency evaluation. 577*46439007SCharles.Forsyth.NH 1 578*46439007SCharles.ForsythMetarules 579*46439007SCharles.Forsyth.PP 580*46439007SCharles.ForsythA 581*46439007SCharles.Forsyth.I metarule 582*46439007SCharles.Forsythis a rule based on a pattern. 583*46439007SCharles.ForsythThe pattern selects a class of target and 584*46439007SCharles.Forsythidentifies related prerequisites. 585*46439007SCharles.Forsyth.CW Mk 586*46439007SCharles.Forsythmetarules may select targets and prerequisites 587*46439007SCharles.Forsythbased on any criterion that can be described by a pattern, not just 588*46439007SCharles.Forsyththe suffix transformations associated with program 589*46439007SCharles.Forsythconstruction. 590*46439007SCharles.Forsyth.PP 591*46439007SCharles.Forsyth.CW Mk 592*46439007SCharles.Forsythhas two types of patterns: 593*46439007SCharles.Forsyth.I intrinsic 594*46439007SCharles.Forsythpatterns or regular expressions conforming to the 595*46439007SCharles.Forsythsyntax of 596*46439007SCharles.Forsyth.I regexp (6). 597*46439007SCharles.ForsythThe intrinsic patterns are shorthand 598*46439007SCharles.Forsythfor common regular expressions. 599*46439007SCharles.ForsythThe intrinsic pattern 600*46439007SCharles.Forsyth.CW % 601*46439007SCharles.Forsythmatches one or more of anything; it is equivalent to 602*46439007SCharles.Forsyththe regular expression 603*46439007SCharles.Forsyth.CW `.+' . 604*46439007SCharles.ForsythThe other intrinsic pattern, 605*46439007SCharles.Forsyth.CW & , 606*46439007SCharles.Forsythmatches one or more of any characters except \f(CW`/'\fP 607*46439007SCharles.Forsythand \f(CW`.'\fP. 608*46439007SCharles.ForsythIt matches a portion of a path and is 609*46439007SCharles.Forsythequivalent to the regular expression 610*46439007SCharles.Forsyth.CW `[^./]+' . 611*46439007SCharles.ForsythAn intrinsic pattern in a prerequisite references 612*46439007SCharles.Forsyththe string matched by the same intrinsic pattern in the target. 613*46439007SCharles.ForsythFor example, the rule 614*46439007SCharles.Forsyth.P1 615*46439007SCharles.Forsyth %.v: %.c 616*46439007SCharles.Forsyth.P2 617*46439007SCharles.Forsythsays that a file ending in 618*46439007SCharles.Forsyth.CW .v 619*46439007SCharles.Forsythdepends on a file of the same name with a 620*46439007SCharles.Forsyth.CW .c 621*46439007SCharles.Forsythsuffix: 622*46439007SCharles.Forsyth.CW foo.v 623*46439007SCharles.Forsythdepends on 624*46439007SCharles.Forsyth.CW foo.c , 625*46439007SCharles.Forsyth.CW bar.v 626*46439007SCharles.Forsythdepends on 627*46439007SCharles.Forsyth.CW bar.c , 628*46439007SCharles.Forsythand so on. 629*46439007SCharles.ForsythThe string matched by an intrinsic pattern in the target 630*46439007SCharles.Forsythis supplied to the recipe in the variable 631*46439007SCharles.Forsyth.CW $stem . 632*46439007SCharles.ForsythThus the rule 633*46439007SCharles.Forsyth.P1 634*46439007SCharles.Forsyth%.$O: %.c 635*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 636*46439007SCharles.Forsyth.P2 637*46439007SCharles.Forsythcreates an object file for the target architecture from 638*46439007SCharles.Forsytha similarly named C source file. If several object 639*46439007SCharles.Forsythfiles are out of date, the rule is applied repeatedly and 640*46439007SCharles.Forsyth.CW $stem 641*46439007SCharles.Forsythrefers to each file in turn. 642*46439007SCharles.ForsythSince there is only one 643*46439007SCharles.Forsyth.CW stem 644*46439007SCharles.Forsythvariable, there can only be one 645*46439007SCharles.Forsyth.CW % 646*46439007SCharles.Forsythor 647*46439007SCharles.Forsyth.CW & 648*46439007SCharles.Forsythpattern in a target; 649*46439007SCharles.Forsyththe pattern 650*46439007SCharles.Forsyth.CW %-%.c 651*46439007SCharles.Forsythis illegal. 652*46439007SCharles.Forsyth.PP 653*46439007SCharles.ForsythMetarules simplify the 654*46439007SCharles.Forsyth.CW mkfile 655*46439007SCharles.Forsythfor building programs 656*46439007SCharles.Forsyth.CW f1 657*46439007SCharles.Forsythand 658*46439007SCharles.Forsyth.CW f2 : 659*46439007SCharles.Forsyth.P1 660*46439007SCharles.Forsyth</$objtype/mkfile 661*46439007SCharles.ForsythCFLAGS=-w 662*46439007SCharles.ForsythALL=f1 f2 663*46439007SCharles.Forsyth 664*46439007SCharles.Forsythall:V: $ALL 665*46439007SCharles.Forsyth 666*46439007SCharles.Forsyth%: %.$O 667*46439007SCharles.Forsyth $LD -o $target $prereq 668*46439007SCharles.Forsyth%.$O: %.c 669*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 670*46439007SCharles.Forsythclean:V: 671*46439007SCharles.Forsyth rm -f $ALL *.[$OS] 672*46439007SCharles.Forsyth.P2 673*46439007SCharles.Forsyth(The variable 674*46439007SCharles.Forsyth.CW $OS 675*46439007SCharles.Forsythis a list of code characters for all architectures.) 676*46439007SCharles.ForsythHere, metarules specify 677*46439007SCharles.Forsythcompile and load steps for all files. 678*46439007SCharles.ForsythThe loader rule relies on two internal variables 679*46439007SCharles.Forsythset by 680*46439007SCharles.Forsyth.CW mk 681*46439007SCharles.Forsythduring evaluation of the rule: 682*46439007SCharles.Forsyth.CW $target 683*46439007SCharles.Forsythis the name of the target and 684*46439007SCharles.Forsyth.CW $prereq 685*46439007SCharles.Forsyththe name of all prerequisites. 686*46439007SCharles.ForsythMetarules allow this 687*46439007SCharles.Forsyth.CW mkfile 688*46439007SCharles.Forsythto be easily extended; a new program 689*46439007SCharles.Forsythis supported by adding its name to the third line. 690*46439007SCharles.Forsyth.PP 691*46439007SCharles.ForsythA regular expression metarule must have an 692*46439007SCharles.Forsyth.CW R 693*46439007SCharles.Forsythattribute. 694*46439007SCharles.ForsythPrerequisites may reference matching substrings in 695*46439007SCharles.Forsyththe target using the form 696*46439007SCharles.Forsyth.CW \e\fIn\fP 697*46439007SCharles.Forsythwhere 698*46439007SCharles.Forsyth.I n 699*46439007SCharles.Forsythis a digit from 1 to 9 specifying the 700*46439007SCharles.Forsyth.I n th 701*46439007SCharles.Forsythparenthesized sub-expression. In a recipe, 702*46439007SCharles.Forsyth.CW $stem\fIn\fP 703*46439007SCharles.Forsythis the equivalent reference. 704*46439007SCharles.ForsythFor example, a compile rule could be 705*46439007SCharles.Forsythspecified using regular expressions: 706*46439007SCharles.Forsyth.P1 707*46439007SCharles.Forsyth(.+)\e.$O:R: \e1.c 708*46439007SCharles.Forsyth $CC $CFLAGS $stem1.c 709*46439007SCharles.Forsyth.P2 710*46439007SCharles.ForsythHere, 711*46439007SCharles.Forsyth.CW \e1 712*46439007SCharles.Forsythand 713*46439007SCharles.Forsyth.CW $stem1 714*46439007SCharles.Forsythrefer to the name of the target object file without the 715*46439007SCharles.Forsythsuffix. The variable 716*46439007SCharles.Forsyth.CW $stem 717*46439007SCharles.Forsythassociated with an intrinsic pattern is undefined 718*46439007SCharles.Forsythin a regular expression metarule. 719*46439007SCharles.Forsyth.NH 1 720*46439007SCharles.ForsythArchives 721*46439007SCharles.Forsyth.PP 722*46439007SCharles.Forsyth.CW Mk 723*46439007SCharles.Forsythprovides a special mechanism for maintaining an archive. 724*46439007SCharles.ForsythAn archive member is referenced using the form 725*46439007SCharles.Forsyth.CW \fIlib\fP(\fIfile\fP) 726*46439007SCharles.Forsythwhere 727*46439007SCharles.Forsyth.I lib 728*46439007SCharles.Forsythis the name of the archive and 729*46439007SCharles.Forsyth.I file 730*46439007SCharles.Forsythis the name of the member. Two rules define the 731*46439007SCharles.Forsythdependency between an object file and its membership 732*46439007SCharles.Forsythin an archive: 733*46439007SCharles.Forsyth.P1 734*46439007SCharles.Forsyth$LIB(foo.v):N: foo.v 735*46439007SCharles.Forsyth$LIB: $LIB(foo.v) 736*46439007SCharles.Forsyth ar rv $LIB foo.v 737*46439007SCharles.Forsyth.P2 738*46439007SCharles.ForsythThe first rule establishes a dependency between the 739*46439007SCharles.Forsytharchive member and the object file. 740*46439007SCharles.ForsythNormally, 741*46439007SCharles.Forsyth.CW mk 742*46439007SCharles.Forsythdetects an error when a target does not exist and the rule 743*46439007SCharles.Forsythcontains no recipe; the 744*46439007SCharles.Forsyth.CW N 745*46439007SCharles.Forsythattribute overrides this behavior because the subsequent rule 746*46439007SCharles.Forsythupdates the member. 747*46439007SCharles.ForsythThe second 748*46439007SCharles.Forsythrule establishes the dependency between the member and 749*46439007SCharles.Forsyththe archive; its recipe inserts the member 750*46439007SCharles.Forsythinto the archive. 751*46439007SCharles.ForsythThis two-step specification allows the archive 752*46439007SCharles.Forsythto represent the state of its members. Other rules 753*46439007SCharles.Forsythcan then specify the archive as a prerequisite instead of 754*46439007SCharles.Forsythlisting each member. 755*46439007SCharles.Forsyth.PP 756*46439007SCharles.ForsythA metarule generalizes library maintenance: 757*46439007SCharles.Forsyth.P1 758*46439007SCharles.ForsythLIB=lib.a 759*46439007SCharles.ForsythOBJS=etoa.$O atoe.$O ebcdic.$O 760*46439007SCharles.Forsyth 761*46439007SCharles.Forsyth$LIB(%):N: % 762*46439007SCharles.Forsyth$LIB: ${OBJS:%=$LIB(%)} 763*46439007SCharles.Forsyth ar rv $LIB $OBJS 764*46439007SCharles.Forsyth.P2 765*46439007SCharles.ForsythThe namelist prerequisite of the 766*46439007SCharles.Forsyth.CW $LIB 767*46439007SCharles.Forsythtarget generates archive member names for each object file name; 768*46439007SCharles.Forsythfor example, 769*46439007SCharles.Forsyth.CW etoa.$O 770*46439007SCharles.Forsythbecomes 771*46439007SCharles.Forsyth.CW lib.a(etoa.$O) . 772*46439007SCharles.ForsythThis formulation always updates all members. 773*46439007SCharles.ForsythThis is acceptable for a small archive, but may 774*46439007SCharles.Forsythbe slow for a big one. 775*46439007SCharles.ForsythThe rule 776*46439007SCharles.Forsyth.P1 777*46439007SCharles.Forsyth$LIB: ${OBJS:%=$LIB(%)} 778*46439007SCharles.Forsyth ar rv $LIB `{membername $newprereq} 779*46439007SCharles.Forsyth.P2 780*46439007SCharles.Forsythonly updates out of date object files. 781*46439007SCharles.ForsythThe internal variable 782*46439007SCharles.Forsyth.CW $newprereq 783*46439007SCharles.Forsythcontains the names of the out of 784*46439007SCharles.Forsythdate prerequisites. The 785*46439007SCharles.Forsyth.CW rc 786*46439007SCharles.Forsythscript 787*46439007SCharles.Forsyth.CW membername 788*46439007SCharles.Forsythtransforms an archive member specification into a file name: 789*46439007SCharles.Forsythit translates 790*46439007SCharles.Forsyth.CW lib.a(etoa.$O) 791*46439007SCharles.Forsythinto 792*46439007SCharles.Forsyth.CW etoa.$O . 793*46439007SCharles.Forsyth.PP 794*46439007SCharles.ForsythThe 795*46439007SCharles.Forsyth.CW mkfile 796*46439007SCharles.Forsyth.P1 797*46439007SCharles.Forsyth</$objtype/mkfile 798*46439007SCharles.ForsythLIB=lib.a 799*46439007SCharles.ForsythOBJS=etoa.$O atoe.$O ebcdic.$O 800*46439007SCharles.Forsyth 801*46439007SCharles.Forsythprog: main.$O $LIB 802*46439007SCharles.Forsyth $LD -o $target $prereq 803*46439007SCharles.Forsyth 804*46439007SCharles.Forsyth$LIB(%):N: % 805*46439007SCharles.Forsyth$LIB: ${OBJS:%=$LIB(%)} 806*46439007SCharles.Forsyth ar rv $LIB $OBJS 807*46439007SCharles.Forsyth.P2 808*46439007SCharles.Forsythbuilds a program by loading it with a library. 809*46439007SCharles.Forsyth.NH 1 810*46439007SCharles.ForsythEvaluation algorithm 811*46439007SCharles.Forsyth.PP 812*46439007SCharles.ForsythFor each target of interest, 813*46439007SCharles.Forsyth.CW mk 814*46439007SCharles.Forsythuses the rules in a 815*46439007SCharles.Forsyth.CW mkfile 816*46439007SCharles.Forsythto build a data 817*46439007SCharles.Forsythstructure called a dependency graph. The nodes of 818*46439007SCharles.Forsyththe graph represent targets and prerequisites; 819*46439007SCharles.Forsytha directed arc 820*46439007SCharles.Forsythfrom one node to another indicates that 821*46439007SCharles.Forsyththe file associated with the first node depends 822*46439007SCharles.Forsython the file associated with the second. 823*46439007SCharles.ForsythWhen the 824*46439007SCharles.Forsyth.CW mkfile 825*46439007SCharles.Forsythhas been completely read, the graph is analyzed. 826*46439007SCharles.ForsythIn the first step, implied dependencies are resolved by 827*46439007SCharles.Forsythcomputing the 828*46439007SCharles.Forsyth.I "transitive closure" 829*46439007SCharles.Forsythof the graph. 830*46439007SCharles.ForsythThis calculation extends the graph to include all 831*46439007SCharles.Forsythtargets that are potentially 832*46439007SCharles.Forsythderivable from the rules in the 833*46439007SCharles.Forsyth.CW mkfile . 834*46439007SCharles.ForsythNext the graph is checked for cycles; 835*46439007SCharles.Forsyth.CW make 836*46439007SCharles.Forsythaccepts cyclic dependencies, but 837*46439007SCharles.Forsyth.CW mk 838*46439007SCharles.Forsythdoes not allow them. 839*46439007SCharles.ForsythSubsequent steps 840*46439007SCharles.Forsythprune subgraphs that are irrelevant for producing the 841*46439007SCharles.Forsythdesired target and verify that there is only one way 842*46439007SCharles.Forsythto build it. 843*46439007SCharles.ForsythThe recipes associated with the 844*46439007SCharles.Forsythnodes on the longest path between the 845*46439007SCharles.Forsythtarget and an out of date prerequisite 846*46439007SCharles.Forsythare then executed in reverse order. 847*46439007SCharles.Forsyth.PP 848*46439007SCharles.ForsythThe transitive closure calculation is sensitive to 849*46439007SCharles.Forsythmetarules; the patterns often select many potential targets 850*46439007SCharles.Forsythand cause the graph to grow rapidly. 851*46439007SCharles.ForsythFortunately, 852*46439007SCharles.Forsythdependencies associated with the desired target 853*46439007SCharles.Forsythusually form a small part of the graph, so, after 854*46439007SCharles.Forsythpruning, analysis is tractable. 855*46439007SCharles.ForsythFor example, the rules 856*46439007SCharles.Forsyth.P1 857*46439007SCharles.Forsyth%: x.% 858*46439007SCharles.Forsyth recipe1 859*46439007SCharles.Forsythx.%: %.k 860*46439007SCharles.Forsyth recipe2 861*46439007SCharles.Forsyth%.k: %.f 862*46439007SCharles.Forsyth recipe3 863*46439007SCharles.Forsyth.P2 864*46439007SCharles.Forsythproduce a graph with four nodes for each file in the 865*46439007SCharles.Forsythcurrent directory. 866*46439007SCharles.ForsythIf the desired target is 867*46439007SCharles.Forsyth.CW foo , 868*46439007SCharles.Forsyth.CW mk 869*46439007SCharles.Forsythdetects the dependency between it 870*46439007SCharles.Forsythand the original file 871*46439007SCharles.Forsyth.CW foo.f 872*46439007SCharles.Forsyththrough intermediate dependencies on 873*46439007SCharles.Forsyth.CW foo.k 874*46439007SCharles.Forsythand 875*46439007SCharles.Forsyth.CW x.foo . 876*46439007SCharles.ForsythNodes associated with other files are deleted during pruning because 877*46439007SCharles.Forsyththey are irrelevant to the production of 878*46439007SCharles.Forsyth.CW foo . 879*46439007SCharles.Forsyth.PP 880*46439007SCharles.Forsyth.CW Mk 881*46439007SCharles.Forsythavoids infinite cycles by evaluating 882*46439007SCharles.Forsytheach metarule once. 883*46439007SCharles.ForsythThus, the rule 884*46439007SCharles.Forsyth.P1 885*46439007SCharles.Forsyth%: %.z 886*46439007SCharles.Forsyth cp $prereq $prereq.z 887*46439007SCharles.Forsyth.P2 888*46439007SCharles.Forsythcopies the prerequisite file once. 889*46439007SCharles.Forsyth.NH 1 890*46439007SCharles.ForsythConventions for evaluating rules 891*46439007SCharles.Forsyth.PP 892*46439007SCharles.ForsythThere must be only one 893*46439007SCharles.Forsythway to build each target. However, during evaluation 894*46439007SCharles.Forsythmetarule patterns often select potential targets that 895*46439007SCharles.Forsythconflict with the 896*46439007SCharles.Forsythtargets of other rules. 897*46439007SCharles.Forsyth.CW Mk 898*46439007SCharles.Forsythuses several conventions to resolve ambiguities 899*46439007SCharles.Forsythand to select the proper dependencies. 900*46439007SCharles.Forsyth.PP 901*46439007SCharles.ForsythWhen a target selects more than one rule, 902*46439007SCharles.Forsyth.CW mk 903*46439007SCharles.Forsythchooses a regular rule 904*46439007SCharles.Forsythover a metarule. 905*46439007SCharles.ForsythFor example, the 906*46439007SCharles.Forsyth.CW mkfile 907*46439007SCharles.Forsyth.P1 908*46439007SCharles.Forsyth</$objtype/mkfile 909*46439007SCharles.ForsythCFLAGS=-w 910*46439007SCharles.ForsythFILES=f1.$O f2.$O f3.$O 911*46439007SCharles.Forsyth 912*46439007SCharles.Forsythprog: $FILES 913*46439007SCharles.Forsyth $LD -o $target $prereq 914*46439007SCharles.Forsyth 915*46439007SCharles.Forsyth%.$O: %.c 916*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 917*46439007SCharles.Forsyth 918*46439007SCharles.Forsythf2.$O: f2.c 919*46439007SCharles.Forsyth $CC f2.c 920*46439007SCharles.Forsyth.P2 921*46439007SCharles.Forsythcontains two rules that could build 922*46439007SCharles.Forsyth.CW f2.$O . 923*46439007SCharles.Forsyth.CW Mk 924*46439007SCharles.Forsythselects the last rule because its target, 925*46439007SCharles.Forsyth.CW f2.$O , 926*46439007SCharles.Forsythis explicitly specified, while the 927*46439007SCharles.Forsyth.CW %.$O 928*46439007SCharles.Forsythrule is a metarule. In effect, 929*46439007SCharles.Forsyththe explicit rule for 930*46439007SCharles.Forsyth.CW f2.$O 931*46439007SCharles.Forsythoverrides the general rule for building object files from 932*46439007SCharles.ForsythC source files. 933*46439007SCharles.Forsyth.PP 934*46439007SCharles.ForsythWhen a rule has a target and prerequisites but no recipe, 935*46439007SCharles.Forsyththose prerequisites are added to all other rules with 936*46439007SCharles.Forsythrecipes that have the same target. 937*46439007SCharles.ForsythAll prerequisites, regardless of where they were specified, are 938*46439007SCharles.Forsythavailable in the recipe in variable 939*46439007SCharles.Forsyth.CW $prereq . 940*46439007SCharles.ForsythFor example, in 941*46439007SCharles.Forsyth.P1 942*46439007SCharles.Forsyth</$objtype/mkfile 943*46439007SCharles.ForsythCFLAGS=-w 944*46439007SCharles.ForsythFILES=f1.$O f2.$O f3.$O 945*46439007SCharles.Forsyth 946*46439007SCharles.Forsythprog: $FILES 947*46439007SCharles.Forsyth $LD -o $target $prereq 948*46439007SCharles.Forsyth 949*46439007SCharles.Forsyth%.$O: hdr.h 950*46439007SCharles.Forsyth 951*46439007SCharles.Forsyth%.$O: %.c 952*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 953*46439007SCharles.Forsyth.P2 954*46439007SCharles.Forsyththe second rule adds 955*46439007SCharles.Forsyth.CW hdr.h 956*46439007SCharles.Forsythas a prerequisite of the compile metarule; 957*46439007SCharles.Forsythan object file produced from a C source file 958*46439007SCharles.Forsythdepends on 959*46439007SCharles.Forsyth.CW hdr.h 960*46439007SCharles.Forsythas well as the source file. Notice that the recipe of 961*46439007SCharles.Forsyththe compile rule uses 962*46439007SCharles.Forsyth.CW $stem.c 963*46439007SCharles.Forsythinstead of 964*46439007SCharles.Forsyth.CW $prereq 965*46439007SCharles.Forsythbecause the latter specification would attempt to compile 966*46439007SCharles.Forsyth.CW hdr.h . 967*46439007SCharles.Forsyth.PP 968*46439007SCharles.ForsythWhen a target is virtual and there is no other rule with 969*46439007SCharles.Forsyththe same target, 970*46439007SCharles.Forsyth.CW mk 971*46439007SCharles.Forsythevaluates each prerequisite. 972*46439007SCharles.ForsythFor example, adding the rule 973*46439007SCharles.Forsyth.P1 974*46439007SCharles.Forsythall:V: prog 975*46439007SCharles.Forsyth.P2 976*46439007SCharles.Forsythto the preceding example builds the executable 977*46439007SCharles.Forsythwhen either 978*46439007SCharles.Forsyth.CW prog 979*46439007SCharles.Forsythor 980*46439007SCharles.Forsyth.CW all 981*46439007SCharles.Forsythis the specified target. In effect, the 982*46439007SCharles.Forsyth.CW all 983*46439007SCharles.Forsythtarget is an alias for 984*46439007SCharles.Forsyth.CW prog . 985*46439007SCharles.Forsyth.PP 986*46439007SCharles.ForsythWhen two rules have identical rule headers and both have 987*46439007SCharles.Forsythrecipes, the later rule replaces the former one. 988*46439007SCharles.ForsythFor example, 989*46439007SCharles.Forsythif a file named 990*46439007SCharles.Forsyth.CW mkrules 991*46439007SCharles.Forsythcontains 992*46439007SCharles.Forsyth.P1 993*46439007SCharles.Forsyth$O.out: $OFILES 994*46439007SCharles.Forsyth $LD $LFLAGS $OFILES 995*46439007SCharles.Forsyth%.$O: %.c 996*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 997*46439007SCharles.Forsyth.P2 998*46439007SCharles.Forsyththe 999*46439007SCharles.Forsyth.CW mkfile 1000*46439007SCharles.Forsyth.P1 1001*46439007SCharles.ForsythOFILES=f1.$O f2.$O f3.$O 1002*46439007SCharles.Forsyth 1003*46439007SCharles.Forsyth<mkrules 1004*46439007SCharles.Forsyth 1005*46439007SCharles.Forsyth$O.out: $OFILES 1006*46439007SCharles.Forsyth $LD $LFLAGS -l $OFILES -lbio -lc 1007*46439007SCharles.Forsyth.P2 1008*46439007SCharles.Forsythoverrides the general loader rule with a special 1009*46439007SCharles.Forsythrule using a non-standard library search sequence. 1010*46439007SCharles.ForsythA rule is neutralized by overriding it with a rule 1011*46439007SCharles.Forsythwith a null recipe: 1012*46439007SCharles.Forsyth.P1 1013*46439007SCharles.Forsyth<mkrules 1014*46439007SCharles.Forsyth 1015*46439007SCharles.Forsyth$O.out:Q: $OFILES 1016*46439007SCharles.Forsyth ; 1017*46439007SCharles.Forsyth.P2 1018*46439007SCharles.ForsythThe 1019*46439007SCharles.Forsyth.CW Q 1020*46439007SCharles.Forsythattribute suppresses the printing of the semicolon. 1021*46439007SCharles.Forsyth.PP 1022*46439007SCharles.ForsythWhen a rule has no prerequisites, the recipe is executed 1023*46439007SCharles.Forsythonly when the target does not exist. For example, 1024*46439007SCharles.Forsyth.P1 1025*46439007SCharles.Forsythmarker: 1026*46439007SCharles.Forsyth touch $target 1027*46439007SCharles.Forsyth.P2 1028*46439007SCharles.Forsythdefines a rule to manage a marker file. 1029*46439007SCharles.ForsythIf the file exists, it is considered up to date 1030*46439007SCharles.Forsythregardless of its modification time. 1031*46439007SCharles.ForsythWhen a virtual target has no prerequisites the 1032*46439007SCharles.Forsythrecipe is always executed. 1033*46439007SCharles.ForsythThe 1034*46439007SCharles.Forsyth.CW clean 1035*46439007SCharles.Forsythrule is of this type: 1036*46439007SCharles.Forsyth.P1 1037*46439007SCharles.Forsythclean:V: 1038*46439007SCharles.Forsyth rm -f [$OS].out *.[$OS] 1039*46439007SCharles.Forsyth.P2 1040*46439007SCharles.ForsythWhen a rule without prerequisites has multiple targets, the 1041*46439007SCharles.Forsythextra targets are aliases for the rule. 1042*46439007SCharles.ForsythFor example, in 1043*46439007SCharles.Forsyth.P1 1044*46439007SCharles.Forsythclean tidy nuke:V: 1045*46439007SCharles.Forsyth rm -f [$OS].out *.[$OS] 1046*46439007SCharles.Forsyth.P2 1047*46439007SCharles.Forsyththe 1048*46439007SCharles.Forsythrule can be invoked by any of three names. 1049*46439007SCharles.ForsythThe first rule in a 1050*46439007SCharles.Forsyth.CW mkfile 1051*46439007SCharles.Forsythis handled specially: 1052*46439007SCharles.Forsythwhen 1053*46439007SCharles.Forsyth.CW mk 1054*46439007SCharles.Forsythis invoked without a command line target 1055*46439007SCharles.Forsythall targets of the first non-metarule are built. 1056*46439007SCharles.ForsythWhen that rule has multiple targets, the recipe 1057*46439007SCharles.Forsythis executed once for each target; normally, the recipe 1058*46439007SCharles.Forsythof a rule with multiple targets is only executed once. 1059*46439007SCharles.Forsyth.PP 1060*46439007SCharles.ForsythA rule applies to a target only when its prerequisites 1061*46439007SCharles.Forsythexist or can be derived. More than one rule may have the 1062*46439007SCharles.Forsythsame target as long as only one rule with a recipe 1063*46439007SCharles.Forsythremains applicable after the dependency evaluation completes. 1064*46439007SCharles.ForsythFor example, consider a program built from C 1065*46439007SCharles.Forsythand assembler source files. Two rules produce 1066*46439007SCharles.Forsythobject files: 1067*46439007SCharles.Forsyth.P1 1068*46439007SCharles.Forsyth%.$O: %.c 1069*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 1070*46439007SCharles.Forsyth%.$O: %.s 1071*46439007SCharles.Forsyth $AS $AFLAGS $stem.s 1072*46439007SCharles.Forsyth.P2 1073*46439007SCharles.ForsythAs long as there are not two source files with names like 1074*46439007SCharles.Forsyth.CW \fIfoo\fP.c 1075*46439007SCharles.Forsythand 1076*46439007SCharles.Forsyth.CW \fIfoo\fP.s , 1077*46439007SCharles.Forsyth.CW mk 1078*46439007SCharles.Forsythcan unambiguously select the proper rule. 1079*46439007SCharles.ForsythIf both files exist, 1080*46439007SCharles.Forsyththere are ambiguous rules to produce 1081*46439007SCharles.Forsyth.CW \fIfoo\fP.$O , 1082*46439007SCharles.Forsythand 1083*46439007SCharles.Forsyth.CW mk 1084*46439007SCharles.Forsythexits with an error message. 1085*46439007SCharles.Forsyth.PP 1086*46439007SCharles.ForsythIn Plan 9, many programs consist of portable code stored 1087*46439007SCharles.Forsythin one directory and architecture-specific source stored in 1088*46439007SCharles.Forsythanother. 1089*46439007SCharles.ForsythFor example, the 1090*46439007SCharles.Forsyth.CW mkfile 1091*46439007SCharles.Forsyth.P1 1092*46439007SCharles.Forsyth</$objtype/mkfile 1093*46439007SCharles.ForsythCFLAGS=-w 1094*46439007SCharles.ForsythFILES=f1.$O f2.$O f3.$O f3.$O 1095*46439007SCharles.Forsyth 1096*46439007SCharles.Forsythprog: $FILES 1097*46439007SCharles.Forsyth $LD -o $target $prereq 1098*46439007SCharles.Forsyth 1099*46439007SCharles.Forsyth%.$O: %.$c 1100*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 1101*46439007SCharles.Forsyth 1102*46439007SCharles.Forsyth%.$O: ../port/%.c 1103*46439007SCharles.Forsyth $CC $CFLAGS ../port/$stem.c 1104*46439007SCharles.Forsyth.P2 1105*46439007SCharles.Forsythbuilds the program named 1106*46439007SCharles.Forsyth.CW prog 1107*46439007SCharles.Forsythusing portable code in directory 1108*46439007SCharles.Forsyth.CW ../port 1109*46439007SCharles.Forsythand architecture-specific code in the current directory. 1110*46439007SCharles.ForsythAs long as the 1111*46439007SCharles.Forsythnames of the C source files in 1112*46439007SCharles.Forsyth.CW ../port 1113*46439007SCharles.Forsythdo not conflict with the names of files in the current directory, 1114*46439007SCharles.Forsyth.CW mk 1115*46439007SCharles.Forsythselects the appropriate rule. 1116*46439007SCharles.ForsythIf like-named files exist in both directories, the 1117*46439007SCharles.Forsythspecification is ambiguous and results in an error. 1118*46439007SCharles.ForsythAn explicit target resolves the ambiguity. 1119*46439007SCharles.ForsythFor example, 1120*46439007SCharles.Forsythadding the rule 1121*46439007SCharles.Forsyth.P1 1122*46439007SCharles.Forsythf2.$O: f2.c 1123*46439007SCharles.Forsyth $CC $CFLAGS $f2.c 1124*46439007SCharles.Forsyth.P2 1125*46439007SCharles.Forsythto the previous 1126*46439007SCharles.Forsyth.CW mkfile 1127*46439007SCharles.Forsythuses the architecture-specific version of 1128*46439007SCharles.Forsyth.CW f2.c 1129*46439007SCharles.Forsythinstead of the portable one. 1130*46439007SCharles.ForsythHere, the explicit rule 1131*46439007SCharles.Forsythdocuments which of the 1132*46439007SCharles.Forsythlike-named source files is used to build the program. 1133*46439007SCharles.Forsyth.PP 1134*46439007SCharles.Forsyth.CW Mk\fR'\fP s 1135*46439007SCharles.Forsythheuristics can produce unintended results 1136*46439007SCharles.Forsythwhen rules are not carefully specified. 1137*46439007SCharles.ForsythFor example, the rules that build 1138*46439007SCharles.Forsythobject files from C or assembler source files 1139*46439007SCharles.Forsyth.P1 1140*46439007SCharles.Forsyth%.$O: %.c 1141*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 1142*46439007SCharles.Forsyth%.$O: %.s 1143*46439007SCharles.Forsyth $AS $AFLAGS $stem.s 1144*46439007SCharles.Forsyth.P2 1145*46439007SCharles.Forsythillustrate a subtle pratfall. 1146*46439007SCharles.ForsythAdding a header file dependency to the compile rule 1147*46439007SCharles.Forsyth.P1 1148*46439007SCharles.Forsyth%.$O: %.c hdr.h 1149*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 1150*46439007SCharles.Forsyth.P2 1151*46439007SCharles.Forsythproduces the error message 1152*46439007SCharles.Forsyth.P1 1153*46439007SCharles.Forsyth.CW "don't know how to make '\fIfile\fP.c'" 1154*46439007SCharles.Forsyth.P2 1155*46439007SCharles.Forsythwhen \fIfile\fP.s is an assembler 1156*46439007SCharles.Forsythsource file. 1157*46439007SCharles.ForsythThis occurs because 1158*46439007SCharles.Forsyth.CW \fIfile\fP.s 1159*46439007SCharles.Forsythsatisfies the assemble rule and 1160*46439007SCharles.Forsyth.CW hdr.h 1161*46439007SCharles.Forsythsatisfies the compile rule, so 1162*46439007SCharles.Forsytheither rule can potentially produce the target. 1163*46439007SCharles.ForsythWhen a prerequisite exists or can be 1164*46439007SCharles.Forsythderived, 1165*46439007SCharles.Forsythall other prerequisites in that 1166*46439007SCharles.Forsythrule header must exist or be derivable; here, 1167*46439007SCharles.Forsyththe existence of 1168*46439007SCharles.Forsyth.CW hdr.h 1169*46439007SCharles.Forsythforces the evaluation of a C source file. 1170*46439007SCharles.ForsythSpecifying the dependencies in different 1171*46439007SCharles.Forsythrules avoids this interpretation: 1172*46439007SCharles.Forsyth.P1 1173*46439007SCharles.Forsyth%.$O: hdr.h 1174*46439007SCharles.Forsyth%.$O: %.c 1175*46439007SCharles.Forsyth $CC $CFLAGS $stem.c 1176*46439007SCharles.Forsyth.P2 1177*46439007SCharles.ForsythAlthough 1178*46439007SCharles.Forsyth.CW hdr.h 1179*46439007SCharles.Forsythis an additional prerequisite of the compile rule, 1180*46439007SCharles.Forsyththe two rules are evaluated independently and 1181*46439007SCharles.Forsyththe existence of the C source file is not linked 1182*46439007SCharles.Forsythto the existence of the header file. 1183*46439007SCharles.ForsythHowever, this specification describes a different 1184*46439007SCharles.Forsythdependency. Originally, only object 1185*46439007SCharles.Forsythfiles derived from C files depended on 1186*46439007SCharles.Forsyth.CW hdr.h ; 1187*46439007SCharles.Forsythnow all object files, including those built 1188*46439007SCharles.Forsythfrom assembler source, depend on the header file. 1189*46439007SCharles.Forsyth.PP 1190*46439007SCharles.ForsythMetarule patterns should be as restrictive as possible to 1191*46439007SCharles.Forsythprevent conflicts with other rules. 1192*46439007SCharles.ForsythConsider the 1193*46439007SCharles.Forsyth.CW mkfile 1194*46439007SCharles.Forsyth.P1 1195*46439007SCharles.Forsyth</$objtype/mkfile 1196*46439007SCharles.ForsythBIN=/$objtype/bin 1197*46439007SCharles.ForsythPROG=foo 1198*46439007SCharles.Forsyth 1199*46439007SCharles.Forsythinstall:V: $BIN/$PROG 1200*46439007SCharles.Forsyth 1201*46439007SCharles.Forsyth%: %.c 1202*46439007SCharles.Forsyth $CC $stem.c 1203*46439007SCharles.Forsyth $LD -o $target $stem.$O 1204*46439007SCharles.Forsyth 1205*46439007SCharles.Forsyth$BIN/%: % 1206*46439007SCharles.Forsyth mv $stem $target 1207*46439007SCharles.Forsyth.P2 1208*46439007SCharles.ForsythThe first target builds an executable 1209*46439007SCharles.Forsythin the local directory; the second 1210*46439007SCharles.Forsythinstalls it in the directory 1211*46439007SCharles.Forsythof executables for the architecture. 1212*46439007SCharles.ForsythInvoking 1213*46439007SCharles.Forsyth.CW mk 1214*46439007SCharles.Forsythwith the 1215*46439007SCharles.Forsyth.CW install 1216*46439007SCharles.Forsythtarget produces: 1217*46439007SCharles.Forsyth.P1 0 1218*46439007SCharles.Forsythmk: ambiguous recipes for /mips/bin/foo: 1219*46439007SCharles.Forsyth/mips/bin/foo <-(mkfile:8)- /mips/bin/foo.c <-(mkfile:12)- foo.c 1220*46439007SCharles.Forsyth/mips/bin/foo <-(mkfile:12)- foo <-(mkfile:8)- foo.c 1221*46439007SCharles.Forsyth.P2 1222*46439007SCharles.ForsythThe prerequisite of the 1223*46439007SCharles.Forsyth.CW install 1224*46439007SCharles.Forsythrule, 1225*46439007SCharles.Forsyth.CW $BIN/$PROG , 1226*46439007SCharles.Forsythmatches both metarules because the 1227*46439007SCharles.Forsyth.CW % 1228*46439007SCharles.Forsythpattern matches everything. 1229*46439007SCharles.ForsythThe 1230*46439007SCharles.Forsyth.CW & 1231*46439007SCharles.Forsythpattern restricts the compile rule to files in the 1232*46439007SCharles.Forsythcurrent directory and avoids the conflict: 1233*46439007SCharles.Forsyth.P1 1234*46439007SCharles.Forsyth&: &.c 1235*46439007SCharles.Forsyth $CC $stem.c 1236*46439007SCharles.Forsyth $LD -o $target $stem.$O 1237*46439007SCharles.Forsyth.P2 1238*46439007SCharles.Forsyth.NH 1 1239*46439007SCharles.ForsythMissing intermediates 1240*46439007SCharles.Forsyth.PP 1241*46439007SCharles.Forsyth.CW Mk 1242*46439007SCharles.Forsythdoes not build a missing intermediate file if a target 1243*46439007SCharles.Forsythis up to date with the prerequisites of the intermediate. 1244*46439007SCharles.ForsythFor example, 1245*46439007SCharles.Forsythwhen an executable is up to date with its source file, 1246*46439007SCharles.Forsyth.CW mk 1247*46439007SCharles.Forsythdoes not compile the source to create a missing object file. 1248*46439007SCharles.ForsythThe evaluation only applies 1249*46439007SCharles.Forsythwhen a target is considered up to date by pretending that the 1250*46439007SCharles.Forsythintermediate exists. Thus, it does not apply 1251*46439007SCharles.Forsythwhen the intermediate is a command line target 1252*46439007SCharles.Forsythor when it has no prerequisites. 1253*46439007SCharles.Forsyth.PP 1254*46439007SCharles.ForsythThis capability is useful for 1255*46439007SCharles.Forsythmaintaining archives. We can modify the archive 1256*46439007SCharles.Forsythupdate recipe to remove object files after 1257*46439007SCharles.Forsyththey are archived: 1258*46439007SCharles.Forsyth.P1 1259*46439007SCharles.Forsyth$LIB(%):N: % 1260*46439007SCharles.Forsyth$LIB: ${OBJS:%=$LIB(%)} 1261*46439007SCharles.Forsyth names=`{membername $newprereq} 1262*46439007SCharles.Forsyth ar rv $LIB $names 1263*46439007SCharles.Forsyth rm -f $names 1264*46439007SCharles.Forsyth.P2 1265*46439007SCharles.ForsythA subsequent 1266*46439007SCharles.Forsyth.CW mk 1267*46439007SCharles.Forsythdoes not remake the object files as long as the members 1268*46439007SCharles.Forsythof the archive remain up to date with the source files. 1269*46439007SCharles.ForsythThe 1270*46439007SCharles.Forsyth.CW -i 1271*46439007SCharles.Forsythcommand line option overrides this behavior 1272*46439007SCharles.Forsythand causes all intermediates to be built. 1273*46439007SCharles.Forsyth.NH 1 1274*46439007SCharles.ForsythAlternative out-of-date determination 1275*46439007SCharles.Forsyth.PP 1276*46439007SCharles.ForsythSometimes the modification time is not useful 1277*46439007SCharles.Forsythfor deciding when a target and prerequisite are out of date. 1278*46439007SCharles.ForsythThe 1279*46439007SCharles.Forsyth.CW P 1280*46439007SCharles.Forsythattribute replaces the default mechanism with the result of 1281*46439007SCharles.Forsytha command. The command immediately follows the attribute 1282*46439007SCharles.Forsythand is repeatedly executed with each 1283*46439007SCharles.Forsythtarget and each prerequisite as its arguments; 1284*46439007SCharles.Forsythif its exit status is non-zero, they are considered out of date 1285*46439007SCharles.Forsythand the recipe is executed. Consider the 1286*46439007SCharles.Forsyth.CW mkfile 1287*46439007SCharles.Forsyth.P1 1288*46439007SCharles.Forsythfoo.ref:Pcmp -s: foo 1289*46439007SCharles.Forsyth cp $prereq $target 1290*46439007SCharles.Forsyth.P2 1291*46439007SCharles.ForsythThe command 1292*46439007SCharles.Forsyth.P1 1293*46439007SCharles.Forsythcmp -s foo.ref foo 1294*46439007SCharles.Forsyth.P2 1295*46439007SCharles.Forsythis executed and if 1296*46439007SCharles.Forsyth.CW foo.ref 1297*46439007SCharles.Forsythdiffers from 1298*46439007SCharles.Forsyth.CW foo , 1299*46439007SCharles.Forsyththe latter file is copied to the former. 1300*46439007SCharles.Forsyth.NH 1 1301*46439007SCharles.ForsythParallel processing 1302*46439007SCharles.Forsyth.PP 1303*46439007SCharles.ForsythWhen possible, 1304*46439007SCharles.Forsyth.CW mk 1305*46439007SCharles.Forsythexecutes recipes in parallel. 1306*46439007SCharles.ForsythThe variable 1307*46439007SCharles.Forsyth.CW $NPROC 1308*46439007SCharles.Forsythspecifies the maximum number of simultaneously executing 1309*46439007SCharles.Forsythrecipes. 1310*46439007SCharles.ForsythNormally it is imported from the environment, 1311*46439007SCharles.Forsythwhere the system has set it to the number of available processors. 1312*46439007SCharles.ForsythIt can be decreased by assigning a new 1313*46439007SCharles.Forsythvalue and can be set to 1 to force single-threaded recipe execution. 1314*46439007SCharles.ForsythThis is necessary when several targets access 1315*46439007SCharles.Forsytha common resource such as 1316*46439007SCharles.Forsytha status file or data base. 1317*46439007SCharles.ForsythWhen there is no dependency between targets, 1318*46439007SCharles.Forsyth.CW mk 1319*46439007SCharles.Forsythassumes the 1320*46439007SCharles.Forsythrecipes can be 1321*46439007SCharles.Forsythexecuted concurrently. 1322*46439007SCharles.ForsythNormally, this allows 1323*46439007SCharles.Forsythmultiple prerequisites to be built simultaneously; 1324*46439007SCharles.Forsythfor example, the object file prerequisites of 1325*46439007SCharles.Forsytha load rule can be produced by compiling the source files in parallel. 1326*46439007SCharles.Forsyth.CW Mk 1327*46439007SCharles.Forsythdoes not define the order of execution of independent recipes. 1328*46439007SCharles.ForsythWhen the prerequisites of a rule are not independent, 1329*46439007SCharles.Forsyththe dependencies between them should be specified in a rule or the 1330*46439007SCharles.Forsyth.CW mkfile 1331*46439007SCharles.Forsythshould be single-threaded. 1332*46439007SCharles.ForsythFor example, the archive update rules 1333*46439007SCharles.Forsyth.P1 1334*46439007SCharles.Forsyth$LIB(%):N: % 1335*46439007SCharles.Forsyth$LIB: ${OBJS:%=$LIB(%)} 1336*46439007SCharles.Forsyth ar rv $LIB `{membername $newprereq} 1337*46439007SCharles.Forsyth.P2 1338*46439007SCharles.Forsythcompile source files in parallel but update 1339*46439007SCharles.Forsythall members of the archive at once. 1340*46439007SCharles.ForsythIt is a mistake to merge the two rules 1341*46439007SCharles.Forsyth.P1 1342*46439007SCharles.Forsyth$LIB(%): % 1343*46439007SCharles.Forsyth ar rv $LIB $stem 1344*46439007SCharles.Forsyth.P2 1345*46439007SCharles.Forsythbecause an 1346*46439007SCharles.Forsyth.CW ar 1347*46439007SCharles.Forsythcommand is executed for every 1348*46439007SCharles.Forsythmember of the library. Not only is this 1349*46439007SCharles.Forsythinefficient, but the archive is updated 1350*46439007SCharles.Forsythin parallel, making interference likely. 1351*46439007SCharles.Forsyth.PP 1352*46439007SCharles.ForsythThe 1353*46439007SCharles.Forsyth.CW $nproc 1354*46439007SCharles.Forsythenvironment variable contains a number associated 1355*46439007SCharles.Forsythwith the processor executing a recipe. 1356*46439007SCharles.ForsythIt can be used to create unique 1357*46439007SCharles.Forsythnames when the 1358*46439007SCharles.Forsythrecipe may be executing simultaneously on several processors. 1359*46439007SCharles.ForsythOther maintenance tools provide mechanisms to control recipe 1360*46439007SCharles.Forsythscheduling explicitly [Cmel86], but 1361*46439007SCharles.Forsyth.CW mk\fR'\fPs 1362*46439007SCharles.Forsythgeneral rules are sufficient for all but the most unusual cases. 1363*46439007SCharles.Forsyth.NH 1 1364*46439007SCharles.ForsythDeleting target files on errors 1365*46439007SCharles.Forsyth.PP 1366*46439007SCharles.ForsythThe 1367*46439007SCharles.Forsyth.CW D 1368*46439007SCharles.Forsythattribute 1369*46439007SCharles.Forsythcauses 1370*46439007SCharles.Forsyth.CW mk 1371*46439007SCharles.Forsythto remove the target file when a 1372*46439007SCharles.Forsythrecipe terminates prematurely. 1373*46439007SCharles.ForsythThe error message describing the 1374*46439007SCharles.Forsythtermination condition warns 1375*46439007SCharles.Forsythof the deletion. 1376*46439007SCharles.ForsythA partially built file is doubly dangerous: 1377*46439007SCharles.Forsythit is not only wrong, but is also 1378*46439007SCharles.Forsythconsidered to be up to date so 1379*46439007SCharles.Forsytha subsequent 1380*46439007SCharles.Forsyth.CW mk 1381*46439007SCharles.Forsythwill not rebuild it. For example, 1382*46439007SCharles.Forsyth.P1 1383*46439007SCharles.Forsythpic.out:D: mk.ms 1384*46439007SCharles.Forsyth pic $prereq | tbl | troff -ms > $target 1385*46439007SCharles.Forsyth.P2 1386*46439007SCharles.Forsythproduces the message 1387*46439007SCharles.Forsyth.P1 1388*46439007SCharles.Forsyth.CW "mk: pic mk.ms | ... : exit status=rc 685: deleting 'pic.out'" 1389*46439007SCharles.Forsyth.P2 1390*46439007SCharles.Forsythif any program in the recipe exits with an error status. 1391*46439007SCharles.Forsyth.NH 1 1392*46439007SCharles.ForsythUnspecified dependencies 1393*46439007SCharles.Forsyth.PP 1394*46439007SCharles.ForsythThe 1395*46439007SCharles.Forsyth.CW -w 1396*46439007SCharles.Forsythcommand line flag forces the 1397*46439007SCharles.Forsythfiles following the flag to be treated 1398*46439007SCharles.Forsythas if they were just modified. 1399*46439007SCharles.ForsythWe can use this flag with a command that selects files 1400*46439007SCharles.Forsythto force a build based on the selection criterion. 1401*46439007SCharles.ForsythFor example, if the declaration of 1402*46439007SCharles.Forsytha global variable named 1403*46439007SCharles.Forsyth.I var 1404*46439007SCharles.Forsythis changed in a header file, 1405*46439007SCharles.Forsythall source files that reference 1406*46439007SCharles.Forsythit can be rebuilt with the command 1407*46439007SCharles.Forsyth.P1 1408*46439007SCharles.Forsyth$ mk -w`{grep -l \fIvar\fP *.[cyl]} 1409*46439007SCharles.Forsyth.P2 1410*46439007SCharles.Forsyth.NH 1 1411*46439007SCharles.ForsythConclusion 1412*46439007SCharles.Forsyth.PP 1413*46439007SCharles.ForsythThere are many programs related to 1414*46439007SCharles.Forsyth.CW make , 1415*46439007SCharles.Forsytheach choosing a different balance between 1416*46439007SCharles.Forsythspecialization and generality. 1417*46439007SCharles.Forsyth.CW Mk 1418*46439007SCharles.Forsythemphasizes generality but allows 1419*46439007SCharles.Forsythcustomization through its pattern specifications and 1420*46439007SCharles.Forsythinclude facilities. 1421*46439007SCharles.Forsyth.PP 1422*46439007SCharles.ForsythPlan 9 presents a difficult problem, particularly 1423*46439007SCharles.Forsythbecause of its heterogeneous collection of 1424*46439007SCharles.Forsytharchitectures and languages. 1425*46439007SCharles.Forsyth.CW Mk\fR'\fPs 1426*46439007SCharles.Forsythflexible specification language and simple 1427*46439007SCharles.Forsythinteraction with 1428*46439007SCharles.Forsyth.CW rc 1429*46439007SCharles.Forsythwork well in this environment. 1430*46439007SCharles.Forsyth.PP 1431*46439007SCharles.ForsythAs a result, 1432*46439007SCharles.ForsythPlan 9 relies on 1433*46439007SCharles.Forsyth.CW mk 1434*46439007SCharles.Forsythto automate almost all maintenance. 1435*46439007SCharles.ForsythTasks as diverse as updating the 1436*46439007SCharles.Forsythnetwork data base, producing the manual, 1437*46439007SCharles.Forsythor building a release are expressed as 1438*46439007SCharles.Forsyth.CW mk 1439*46439007SCharles.Forsythprocedures. 1440*46439007SCharles.Forsyth.NH 1 1441*46439007SCharles.ForsythReferences 1442*46439007SCharles.Forsyth.LP 1443*46439007SCharles.Forsyth[Cmel86] R. F. Cmelik, 1444*46439007SCharles.Forsyth``Concurrent Make: A Distributed Program in Concurrent C'', 1445*46439007SCharles.ForsythAT&T Bell Laboratories Technical Report, 1986. 1446*46439007SCharles.Forsyth.LP 1447*46439007SCharles.Forsyth[Feld79] S. I. Feldman, 1448*46439007SCharles.Forsyth``Make \(em a program for maintaining computer programs'', 1449*46439007SCharles.Forsyth.I 1450*46439007SCharles.ForsythSoftware Practice & Experience , 1451*46439007SCharles.Forsyth.R 1452*46439007SCharles.Forsyth1979 1453*46439007SCharles.ForsythVol 9 #4, 1454*46439007SCharles.Forsythpp. 255-266. 1455*46439007SCharles.Forsyth.LP 1456*46439007SCharles.Forsyth[Flan95] Bob Flandrena, 1457*46439007SCharles.Forsyth``Plan 9 Mkfiles'', 1458*46439007SCharles.Forsyththis volume. 1459*46439007SCharles.Forsyth.LP 1460*46439007SCharles.Forsyth[Hume87] A. G. Hume, 1461*46439007SCharles.Forsyth``Mk: A Successor to Make'', 1462*46439007SCharles.Forsyth.I 1463*46439007SCharles.ForsythUSENIX Summer Conf. Proc., 1464*46439007SCharles.Forsyth.R 1465*46439007SCharles.ForsythPhoenix, Az. 1466*46439007SCharles.Forsyth.NH 1 1467*46439007SCharles.ForsythAppendix: Differences between 1468*46439007SCharles.Forsyth.CW make 1469*46439007SCharles.Forsythand 1470*46439007SCharles.Forsyth.CW mk 1471*46439007SCharles.Forsyth.PP 1472*46439007SCharles.ForsythThe differences between 1473*46439007SCharles.Forsyth.CW mk 1474*46439007SCharles.Forsythand 1475*46439007SCharles.Forsyth.CW make 1476*46439007SCharles.Forsythare: 1477*46439007SCharles.Forsyth.IP \(bu 3n 1478*46439007SCharles.Forsyth.CW Make 1479*46439007SCharles.Forsythbuilds targets when it needs them, allowing systematic use of side effects. 1480*46439007SCharles.Forsyth.CW Mk 1481*46439007SCharles.Forsythconstructs the entire dependency graph before building any target. 1482*46439007SCharles.Forsyth.IP \(bu 1483*46439007SCharles.Forsyth.CW Make 1484*46439007SCharles.Forsythsupports suffix rules and 1485*46439007SCharles.Forsyth.CW % 1486*46439007SCharles.Forsythmetarules. 1487*46439007SCharles.Forsyth.CW Mk 1488*46439007SCharles.Forsythsupports 1489*46439007SCharles.Forsyth.CW % 1490*46439007SCharles.Forsythand regular expression metarules. 1491*46439007SCharles.Forsyth(Older versions of 1492*46439007SCharles.Forsyth.CW make 1493*46439007SCharles.Forsythsupport only suffix rules.) 1494*46439007SCharles.Forsyth.IP \(bu 1495*46439007SCharles.Forsyth.CW Mk 1496*46439007SCharles.Forsythperforms transitive closure on metarules, 1497*46439007SCharles.Forsyth.CW make 1498*46439007SCharles.Forsythdoes not. 1499*46439007SCharles.Forsyth.IP \(bu 1500*46439007SCharles.Forsyth.CW Make 1501*46439007SCharles.Forsythsupports cyclic dependencies, 1502*46439007SCharles.Forsyth.CW mk 1503*46439007SCharles.Forsythdoes not. 1504*46439007SCharles.Forsyth.IP \(bu 1505*46439007SCharles.Forsyth.CW Make 1506*46439007SCharles.Forsythevaluates recipes one line at a time, replacing variables by their values and 1507*46439007SCharles.Forsythexecuting some commands internally. 1508*46439007SCharles.Forsyth.CW Mk 1509*46439007SCharles.Forsythpasses the entire recipe to the shell without 1510*46439007SCharles.Forsythinterpretation or internal execution. 1511*46439007SCharles.Forsyth.IP \(bu 1512*46439007SCharles.Forsyth.CW Make 1513*46439007SCharles.Forsythsupports parallel execution of single-line recipes when building 1514*46439007SCharles.Forsyththe prerequisites for specified targets. 1515*46439007SCharles.Forsyth.CW Mk 1516*46439007SCharles.Forsythsupports parallel execution of all recipes. 1517*46439007SCharles.Forsyth(Older versions of 1518*46439007SCharles.Forsyth.CW make 1519*46439007SCharles.Forsythdid not support parallel execution.) 1520*46439007SCharles.Forsyth.IP \(bu 1521*46439007SCharles.Forsyth.CW Make 1522*46439007SCharles.Forsythuses special targets (beginning with a period) 1523*46439007SCharles.Forsythto indicate special processing. 1524*46439007SCharles.Forsyth.CW Mk 1525*46439007SCharles.Forsythuses attributes to modify rule evaluation. 1526*46439007SCharles.Forsyth.IP \(bu 1527*46439007SCharles.Forsyth.CW Mk 1528*46439007SCharles.Forsythsupports virtual 1529*46439007SCharles.Forsythtargets that are independent of the file system. 1530*46439007SCharles.Forsyth.IP \(bu 1531*46439007SCharles.Forsyth.CW Mk 1532*46439007SCharles.Forsythallows non-standard out-of-date determination, 1533*46439007SCharles.Forsyth.CW make 1534*46439007SCharles.Forsythdoes not. 1535*46439007SCharles.Forsyth.PP 1536*46439007SCharles.ForsythIt is usually easy to convert a 1537*46439007SCharles.Forsyth.CW makefile 1538*46439007SCharles.Forsythto or from an equivalent 1539*46439007SCharles.Forsyth.CW mkfile . 1540