man(1) Manual page archive


     MK(1)                                                       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, `mkfile'
          is tried.  Other options are:

          -a      Assume all targets to be out of date.  Thus, every-
                  thing gets made.
          -d[egp] Produce debugging output (p is for parsing, g for
                  graph building, 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 tar-
                  gets, without 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 cur-
                  rent 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 modi-
                  fied.)

          Mkconv attempts to convert a make(1) makefile to a mkfile on
          standard output.  The conversion is not likely to be faith-
          ful.

          The shell script membername extracts member names (see
          `Aggregates' below) from its arguments.

        Definitions

     MK(1)                                                       MK(1)

          A mkfile consists of assignments (described under `Environ-
          ment') and rules. A rule contains targets and a tail. A tar-
          get 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 target with % replaced by an arbitrary
          string, called the stem. In interpreting a metarule, the
          stem is substituted for all occurrences of % in the prereq-
          uisite names.  A metarule may be marked as using regular
          expressions (described under `Syntax').  In this case, % has
          no special meaning; the target is interpreted according to
          regexp(3). The dependencies 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 con-
          sists of a label and a set of arcs leading to prerequisite
          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 gener-
          ate 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 sub-
          dags containing 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 associated with the arcs leading from the node asso-
          ciated with the ready label.  The P attribute can be used to
          generalize mk's notion of determining if prerequisites pre-
          date a label.  Rather than comparing date stamps, it

     MK(1)                                                       MK(1)

          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 initially zero and upon being
          made is set to the most recent date stamp of its prerequi-
          sites.  Otherwise, if a label is nonexistent (does not exist
          as a file), its date stamp is set to the most recent date
          stamp of its prerequisites, or zero if it has no prerequi-
          sites.  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 prereq-
          uisite 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.  Otherwise, l is
          made in the normal fashion.

          Two recipes are called identical if they arose by distribu-
          tion 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
          restrictions.

          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 satis-
                        fies 0≦$nproc<$NPROC, where $NPROC is the max-
                        imum 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

     MK(1)                                                       MK(1)

                        `stem0', ..., `stem9' are set to the corre-
                        sponding 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 execution with recognizable shell variables
          expanded.  To see the commands print as they execute,
          include a `set -x' in your rule.  Commands returning nonzero
          status (see intro(1)) cause mk to terminate.

        Aggregates
          Names of the form a(b) refer to member b of the aggregate a.
          Currently, 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 substi-
          tuting 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' below.  The environment is exported to recipe exe-
          cutions.  Variable values are taken from (in increasing
          order of precedence) the default values below, the environ-
          ment, the mkfiles, and any command line assignment.  A vari-
          able 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=

     MK(1)                                                       MK(1)

          The builtin rules are obtained from the variable BUILTINS
          after all input 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 pro-
          cessed by substituting for `cmd` and then substituting for
          variable references.  Finally, the filename metacharacters
          []*? 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 < followed by a filename.

          Assignments and rule header lines are distinguished by the
          first unquoted occurrence of : (rule header) or = (assign-
          ment).

          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
          prerequisites.  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 modified by the
          following attributes

          <    The standard output of the recipe is read by mk as an
               additional mkfile.  Assignments take effect immedi-
               ately.  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.

     MK(1)                                                       MK(1)

          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 distinct 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

     MK(1)                                                       MK(1)

               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 target.
          Seemingly appropriate input like CFLAGS=-DHZ=60 is parsed as
          an erroneous attribute; correct it by inserting a space
          after the first `='.