Man Linux: Main Page and Category List

NAME

       dmake - maintain program groups, or interdependent files

SYNOPSIS

       dmake     [-P#]     [-{f|C|K}     file]     [-{w|W}     target     ...]
       [macro[[!][*][+][:]]=value       ...]         [-ABcdeEghiknpqrsStTuVxX]
       [-v[cdfimrtw]] [-m[trae]] [target ...]

DESCRIPTION

       dmake  is a re-implementation of the UNIX Make utility with significant
       enhancements.  dmake executes commands found in an external file called
       a  makefile to update one or more target names.  Each target may depend
       on  zero  or  more  prerequisite  targets.   If  any  of  the  target’s
       prerequisites is newer than the target or if the target itself does not
       exist, then dmake will attempt to make the target.

       If no -f command line option is present  then  dmake  searches  for  an
       existing  makefile  from  the  list  of prerequisites specified for the
       special target .MAKEFILES (see the STARTUP section for  more  details).
       If "-" is the name of the file specified to the -f flag then dmake uses
       standard input as the source of the makefile text.

       Any macro definitions (arguments with embedded "=" signs)  that  appear
       on  the  command line are processed first and supercede definitions for
       macros of the same name found within the makefile.  In  general  it  is
       impossible  for  definitions  found  inside  the makefile to redefine a
       macro  defined  on  the  command  line,  see  the  MACROS  section  for
       exceptions.

       If  no  target names are specified on the command line, then dmake uses
       the first non-special target found  in  the  makefile  as  the  default
       target.   See  the  SPECIAL  TARGETS  section  for  the list of special
       targets and  their  function.   Makefiles  written  for  most  previous
       versions of Make will be handled correctly by dmake.  Known differences
       between  dmake  and  other  versions  of  make  are  discussed  in  the
       COMPATIBILITY section found at the end of this document.  dmake returns
       0 if no errors  were  detected  and  a  non-zero  result  if  an  error
       occurred.

OPTIONS

       -A     Enable  AUGMAKE  special inference rule transformations (see the
              "PERCENT(%) RULES" and "AUGMAKE META RULES" sections), these are
              set to off by default.

       -B     Enable  the  use  of  spaces  instead  of <tabs> to begin recipe
              lines.  This flag equivalent to the .NOTABS special macro and is
              further described below.

       -c     Use  non-standard  comment  stripping.   If  you specify -c then
              dmake will treat any # character as a start of comment character
              wherever it may appear unless it is escaped by a \.

       -C [+]file
              This  option  writes  to  file  a  copy  of  standard output and
              standard error from any  child  processes  and  from  the  dmake
              process  itself.  If you specify a + prior to the file name then
              the text is appended to the previous  contents  of  file.   This
              option is active in the MSDOS implementation only and is ignored
              by non-MSDOS versions of dmake.

       -d     Disable the use of the directory cache.  Normally  dmake  caches
              directories  as  it checks file timestamps.  Giving this flag is
              equivalent to the .DIRCACHE attribute or macro being set to  no.

       -E     Read  the  environment  and  define  all  strings  of  the  form
              ’ENV-VAR=evalue’ defined within as macros whose name is ENV-VAR,
              and whose value is ’evalue’.  The environment is processed prior
              to processing  the  user  specified  makefile  thereby  allowing
              definitions  in  the  makefile  to  override  definitions in the
              environment.

       -e     Same as -E, except that the environment is processed  after  the
              user  specified makefile has been processed (thus definitions in
              the environment override definitions in the makefile).   The  -e
              and  -E  options  are mutually exclusive.  If both are given the
              latter takes effect.

       -f file
              Use file as the source for  the  makefile  text.   Only  one  -f
              option is allowed.

       -g     Globally   disable  group  recipe  parsing,  equivalent  to  the
              .IGNOREGROUP attribute or macro being set to yes at the start of
              the makefile.

       -h     Print the command summary for dmake.

       -i     Tells dmake to ignore errors, and continue making other targets.
              This is equivalent to the .IGNORE attribute or macro.

       -K file
              Turns on .KEEP_STATE state tracking and tells dmake to use  file
              as the state file.

       -k     Causes dmake to ignore errors caused by command execution and to
              make all targets not depending on  targets  that  could  not  be
              made.  Ordinarily dmake stops after a command returns a non-zero
              status, specifying -k causes  dmake  to  ignore  the  error  and
              continue to make as much as possible.

       -m[trae]
              Measure  timing  information. Print the time when targets and/or
              recipes are started and finished to stdout. The following format
              is used:

              {s|e} {target|recipe} time maketarget

              s  or e stands for started or ended, target or recipe denotes if
              this line refers to the  whole  target  or  a  recipe.  time  is
              displayed  in Unix time format, i.e. the number of seconds since
              an epoch.  (Since 1970-01-01T00:00:00Z).   maketarget  obviously
              represents  the target the timing information is given for.  The
              optional flags [trae] can be used to change the information that
              is displayed.  If no optional flags are given only the t flag is
              assumed to be selected, ie. -mt.  The optional flags stand for:

              t      Display the start and end time of each target.

              r      Display the start and end time of each recipe.

              a      Display the target as an absolute path, i.e. prepend  the
                     current working directory.

              e      Also  display  the  start  and  end  time  of the $(shell
                     command) function (aka. shell escape) macros.

       -n     Causes dmake to print out what it would have executed, but  does
              not  actually execute the commands.  A special check is made for
              the string "$(MAKE)" inside a recipe line, if it is  found,  the
              line  is  expanded and invoked, thereby enabling recursive makes
              to give a full description of all that they will do.  This check
              is disabled inside group recipes.

       -p     Print  out  a version of the digested makefile in human readable
              form.  (useful for debugging, but cannot be re-read by dmake)

       -P#    On systems that support multi-processing cause dmake  to  use  #
              concurrent  child  processes  to  make  targets.  See the "MULTI
              PROCESSING" section for more information.

       -q     Check and see if the target is up to date.  Exits with code 0 if
              up to date, 1 otherwise.

       -r     Tells  dmake  not  to  read  the  initial  startup makefile, see
              STARTUP section for more details.

       -s     Tells dmake to do  all  its  work  silently  and  not  echo  the
              commands  it  is executing to stdout (also suppresses warnings).
              This  is equivalent to the .SILENT attribute or macro.

       -S     Force sequential execution of  recipes  on  architectures  which
              support  concurrent  makes.  For backward compatibility with old
              makefiles that have nasty side-effect prerequisite dependencies.
              (Implies -P1)

       -t     Causes  dmake  to  touch  the  targets and bring them up to date
              without executing any commands.  Note that targets will  not  be
              created if they do not already exist.

       -T     Tells  dmake  to not perform transitive closure on the inference
              graph.

       -u     Force an unconditional update.  (ie. do everything that would be
              done if everything that a target depended on was out of date)

       -v[cdfimrtw]
              Verbose  flag,  when  making targets print to stdout what we are
              going to make and what we think its time stamp is.  The optional
              flags [cdfimrtw] can be used to restrict the information that is
              displayed.  In the absence of any optional flags all are assumed
              to  be given (ie. -v is equivalent to -vcdfimrtw).  The meanings
              of the optional flags are:

              c      Notify of directory cache operations only.

              d      Notify of change directory operations only.

              f      Notify of file I/O operations only.

              i      Notify of inference algorithm operation only.

              m      Notify of target update operations only.

              r      Force output  of  recipe  lines,  warnings  and  executed
                     commands. This switch is usefull when debugging makefiles
                     that disable the output using the @ or  @@  property  for
                     recipe  lines  or  the .SILENT target/attribute.  It also
                     overrides the -s flag.

              t      Keep any  temporary  files  created;  normally  they  are
                     automatically deleted.

              w      Notify  of non-essential warnings (these are historical).

       -V     Print the version of dmake, and values of builtin macros.

       -W target
              Run dmake pretending that target is out of date.

       -w target
              What if? Show what would be made if target were out of date.

       -x     Upon processing the  user  makefile  export  all  non-internally
              defined  macros to the user’s environment.  This option together
              with the -e  option  allows  SYSV  AUGMAKE  recursive  makes  to
              function as expected.

       -X     Inhibit  the  execution  of #! lines found at the beginning of a
              makefile.  The use of  this  flag  prevents  non-termination  of
              recursive make invocations.

INDEX

       Here  is  a list of the sections that follow and a short description of
       each.  Perhaps you won’t have to read the entire man page to find  what
       you need.

       STARTUP            Describes dmake initialization.

       SYNTAX             Describes the syntax of makefile expressions.

       ATTRIBUTES         Describes  the notion of attributes and how they are
                          used when making targets.

       MACROS             Defining and expanding macros.

       RULES AND TARGETS  How to define targets and their prerequisites.

       RECIPES            How to tell dmake how to make a target.

       BUILTIN COMMANDS   Internal dmake commands.

       TEXT DIVERSIONS    How to use text  diversions  in  recipes  and  macro
                          expansions.

       VIRTUAL TARGETS    Targets  that  only  enforce dependencies, but which
                          can not create a target file.

       SPECIAL TARGETS    Some targets are special.

       SPECIAL MACROS     Macros used by dmake to alter the processing of  the
                          makefile, and those defined by dmake for the user.

       CONTROL MACROS     Itemized list of special control macros.

       RUNTIME MACROS     Discussion of special run-time macros such as $@ and
                          $<.

       FUNCTION MACROS    Description of functional macros.

       CONDITIONAL MACROS Target specific conditional macros.

       DYNAMIC PREREQUISITES
                          Processing  of  prerequisites  which  contain  macro
                          expansions in their name.

       BINDING TARGETS    The  rules  that  dmake  uses to bind a target to an
                          existing file in the file system.

       PERCENT(%) RULES   Specification of recipes to be used by the inference
                          algorithm.

       MAKING INFERENCES  The rules that dmake uses when inferring how to make
                          a target which has no explicit recipe.  This and the
                          previous  section are really a single section in the
                          text.

       AUGMAKE META RULES A subclass of the PERCENT(%) RULES.

       MAKING TARGETS     How dmake makes targets other than libraries.

       MAKING LIBRARIES   How dmake makes libraries.

       KEEP STATE         A discussion of how .KEEP_STATE works.

       MULTI PROCESSING   Discussion of dmakes parallel make  facilities  for
                          architectures that support them.

       CONDITIONALS       Conditional expressions which control the processing
                          of the makefile.

       EXAMPLES           Some hopefully useful examples.

       COMPATIBILITY      How dmake compares with previous versions of make.

       LIMITS             Limitations of dmake.

       PORTABILITY        Comments on writing portable makefiles.

       FILES              Files used by dmake.

       SEE ALSO           Other related programs, and man pages.

       AUTHOR             The guy responsible for this thing.

       BUGS               Hope not.

STARTUP

       When dmake begins execution it first processes  the  command  line  and
       then  processes  an  initial  startup-makefile.  This is followed by an
       attempt to locate and process a user supplied  makefile.   The  startup
       file  defines the default values of all required control macros and the
       set of default rules for making targets and inferences.  When searching
       for  the  startup  makefile, dmake searches the following locations, in
       the order specified, until a startup file is located:

              1.     The location given as the value of the macro  MAKESTARTUP
                     defined on the command line.

              2.     The  location  given  as  the  value  of  the environment
                     variable MAKESTARTUP defined in the current  environment.

              3.     The  location given as the value of the macro MAKESTARTUP
                     defined internally within dmake.  In  this  version,  the
                     internal      definition      of      MAKESTARTUP      is
                     "$(DMAKEROOT)/startup.mk", so you can set the environment
                     variable  DMAKEROOT  to  the  location  of  your  startup
                     directory.

                     If DMAKEROOT is not changed,  for  native  Windows  dmake
                     versions  its  value defaults to "$(ABSMAKECMD:d)startup"
                     (see definition of ABSMAKECMD  for  details).   For  unix
                     like  versions  build  with the autotools build system it
                     defaults to the  value  of  "${prefix}/share/startup"  at
                     build  time.  The  actual  value,  usually something like
                     /usr/local/share/startup  can  be  checked  with  the  -V
                     command line switch.

       The above search is disabled by specifying the -r option on the command
       line.  An error is issued if a startup makefile cannot be found and the
       -r  option  was  not specified.  A user may substitute a custom startup
       file by defining the MAKESTARTUP environment variable or by  redefining
       the  MAKESTARTUP  macro  on the command line.  To determine where dmake
       looks for the default startup file, check your environment or issue the
       command "dmake -V".

       A similar search is performed to locate a default user makefile when no
       -f command line option is specified.  By default, the prerequisite list
       of  the  special  target  .MAKEFILES  specifies  the  names of possible
       makefiles and the search order that dmake should use  to  determine  if
       one exists.  A typical definition for this target is:

              .MAKEFILES : makefile.mk Makefile makefile

       dmake  will  first  look  for  makefile.mk  and  then the others.  If a
       prerequisite cannot be found dmake will try to make it before going  on
       to  the next prerequisite.  For example, makefile.mk can be checked out
       of an RCS file if the proper rules for doing  so  are  defined  in  the
       startup file.

       If the first line of the user makefile is of the form:

              #!command command_args

       then  dmake  will  expand  and  run  the  command  prior to reading any
       additional input.  If the return code of the command is zero then dmake
       will  continue on to process the remainder of the user makefile, if the
       return code is non-zero then dmake will exit.

       dmake builds  the  internal  dependency  graph  as  it  parses  a  user
       specified  makefile.   The graph is rooted at the special target .ROOT.
       .ROOT is the top level target that dmake builds when it starts to build
       targets.   All  user  specified targets (those from the command line or
       taken as defaults from the makefile)  are  made  prerequisites  of  the
       special  target  .TARGETS.   dmake  by default creates the relationship
       that .ROOT depends on .TARGETS and as  a  result  everything  is  made.
       This  approach allows the user to customize, within their makefile, the
       order and which, target, is  built  first.   For  example  the  default
       makefiles come with settings for .ROOT that specify:

              .ROOT .PHONY .NOSTATE .SEQUENTIAL : .INIT .TARGETS .DONE

       with .INIT and .DONE defined as:

              .INIT .DONE .PHONY:;

       which  nicely  emulates  the  behaviour  of Sun’s make extensions.  The
       building of .ROOT’s prerequisites is always forced  to  be  sequential.
       However,   this  definition  is  trivially  changed  by  supplying  the
       definition:

              .ROOT : .TARGETS

       which skips the preamble and postamble phases of building .TARGETS.

       Please note that even though .INIT and .DONE  are  special  exceptions,
       see  section  SPECIAL TARGETS, the use of self defined targets starting
       with ‘.’ should be avoided as they would be handled as  .<suffix>  meta
       targets.  The  target  names  _INIT  and  _DONE  for example would work
       equally well without the .<suffix> drawback.

SYNTAX

       This section is a summary of the syntax of  makefile  statements.   The
       description is given in a style similar to BNF, where { } enclose items
       that may appear zero or more times, and [  ]  enclose  items  that  are
       optional.   Alternative  productions for a left hand side are indicated
       by ’→’, and newlines are significant.  All symbols  in  bold  type  are
       text or names representing text supplied by the user.

              Makefile → { Statement }

              Statement → Macro-Definition
                        → Conditional-Macro-Definition
                        → Conditional
                        → Rule-Definition
                        → Attribute-Definition

              Macro-Definition → MACRO = LINEMACRO [!]*= LINE
                               → MACRO [!]:= LINE
                               → MACRO [!]*:= LINE
                               → MACRO [!]+= LINE
                               → MACRO [!]+:= LINE

              Conditional-Macro-DefinitionTARGET ?= Macro-Definition

              Conditional →  .IF expression
                                Makefile
                             [ .ELIF expression
                                Makefile ]
                             [ .ELSE
                                Makefile ]
                             .END

              expression → LINESTRING
                         → expression == expression
                         → expression != expression
                         → expression <= expression
                         → expression >= expression
                         → ( expression )
                         → expression || expression
                         → expression && expression

              Rule-Definition →  target-definition
                                    [ recipe ]

              target-definition → targets [attrs] op { PREREQUISITE } [; rcp-line]

              targets → target { targets }
                      → "target" { targets }

              target → special-target
                     → TARGET

              attrs → attribute { attrs }
                    → "attribute" { attrs }

              op → : { modifier }

              modifier → :^!-|

              recipe → { TAB rcp-line }
                     → [@[@]][%][-] [
                          { LINE }
                       ]

              rcp-line → [@[@]][%][-][+] LINE

              Attribute-Definition → attrs : targets

              attribute → .EPILOG.ERRREMOVE.EXECUTE.GROUP.IGNORE.IGNOREGROUP.LIBRARY.MKSARGS.NOINFER.NOSTATE.PHONY.PRECIOUS.PROLOG.SETDIR=path.SILENT.SEQUENTIAL.SWAP.USESHELL.SYMBOL.UPDATEALL.WINPATH

              special-target → .ERROR.EXIT.EXPORT.GROUPEPILOG.GROUPPROLOG.IMPORT.INCLUDE.INCLUDEDIRS.MAKEFILES.REMOVE.ROOT.SOURCE.SOURCE.suffix.SUFFIXES (deprecated).TARGETS.INIT.DONE
                             → .suffix
                             → .suffix1.suffix2

       Where, TAB represents a <tab> character, STRING represents an arbitrary
       sequence of characters, and LINE represents a possibly  empty  sequence
       of  characters terminated by a non-escaped (not immediately preceded by
       a backslash ’\’) new-line character.  MACRO, PREREQUISITE,  and  TARGET
       each  represent a string of characters not including space or tab which
       respectively form the name of a macro,  prerequisite  or  target.   The
       name  may  itself  be  a  macro  expansion  expression.   A LINE can be
       continued over several physical lines by terminating it with  a  single
       backslash  character.   Comments are initiated by the pound # character
       and extend to the end of line.  All comment text is  discarded,  a  ’#’
       may  be  placed  into the makefile text by escaping it with ’\’ (ie. \#
       translates to # when it is parsed).  An exception to this occurs when a
       #  is seen inside a recipe line that begins with a <tab> or is inside a
       group recipe.  If you specify the -c  command  line  switch  then  this
       behavior  is disabled and dmake will treat all # characters as start of
       comment indicators unless they are escaped by \.  A  set  of  continued
       lines  may  be  commented out by placing a single # at the start of the
       first line.  A continued line cannot span more than one makefile.

       white space is defined to be any combination of <space>, <tab>, and the
       sequence \<nl> when \<nl> is used to terminate a LINE. Note the special
       treatment of \<nl> in macro definion  and  recipe  lines  below.   When
       processing macro definition lines, any amount of white space is allowed
       on either side of the macro operator and white space is  stripped  from
       both  before  and  after  the macro value string. A \<nl> sequence in a
       macro definition is deleted from the macro value before assigning  this
       value.   During recipe expansion the sequence \<nl> is treated as white
       space but is deleted from the final recipe string.  You must escape the
       \<nl>  with  another  \  in  order to get a \ at the end of a recipe or
       macro definition line.

       When processing target definition lines, the recipe for a target  must,
       in  general,  follow  the first definition of the target (See the RULES
       AND TARGETS section for an exception), and  the  recipe  may  not  span
       across  multiple  makefiles.   Any targets and prerequisites found on a
       target definition line are taken to be white  space  separated  tokens.
       The  rule  operator  (op  in SYNTAX section) is also considered to be a
       token but does not require white space to precede or follow it.   Since
       the  rule  operator  begins with a ‘:’, traditional versions of make do
       not allow the ‘:’ character to form a valid target name.  dmake  allows
       ‘:’  to  be  present in target/prerequisite names as long as the entire
       target/prerequisite name is quoted.  For example:

       a:fred : test

       would be parsed as TARGET = a, PREREQUISITES={fred, :, test}, which  is
       not what was intended.  To fix this you must write:

       "a:fred" : test

       Which  will  be  parsed  as  expected.   Quoted target and prerequisite
       specifications may also contain white space thereby allowing the use of
       complex  function macro expressions..  See the EXAMPLES section for how
       to apply " quoting to a list of targets.

ATTRIBUTES

       dmake defines several target attributes.  Attributes may be assigned to
       a single target, a group of targets, or to all targets in the makefile.
       Attributes are used to modify dmake actions during target update.   The
       recognized attributes are:

       .EPILOG     Insert  shell  epilog  code  when  executing a group recipe
                   associated with any target having this attribute set.

       .ERRREMOVE  Always remove any target having this attribute if an  error
                   is  encountered  while making them.  Setting this attribute
                   overrides the .PRECIOUS attribute.

       .EXECUTE    If the -n flag was given then execute the recipe associated
                   with any target having this attribute set.

       .FIRST      Used   in   conjunction   with  .INCLUDE.   Terminates  the
                   inclusion   with   the    first    successfully    included
                   prerequisite.

       .GROUP      Force execution of a target’s recipe as a group recipe.

       .IGNORE     Ignore  an  error  when trying to make any target with this
                   attribute set.

       .IGNOREGROUP
                   Disable the special meaning of  ’[’  to  initiate  a  group
                   recipe.

       .LIBRARY    Target is a library.

       .MKSARGS    If  running  in  an MSDOS environment then use MKS extended
                   argument passing conventions to pass arguments to commands.
                   Non-MSDOS environments ignore this attribute.

       .NOINFER    Any target with this attribute set will not be subjected to
                   transitive closure if it is inferred as a prerequisite of a
                   target  whose  recipe and prerequisites are being inferred.
                   (i.e. the inference algorithm will not use any prerequisite
                   with  this  attribute  set,  as  a  target) If specified as
                   ’.NOINFER:’ (ie. with no prerequisites or targets) then the
                   effect  is equivalent to specifying -T on the command line.

       .NOSTATE    Any target with this attribute set will  not  have  command
                   line   flag   information  stored  in  the  state  file  if
                   .KEEP_STATE has been enabled.

       .PHONY      Any target with this attribute set  will  have  its  recipe
                   executed  each  time  the  target  is  made  even if a file
                   matching the target name can be located.  Any targets  that
                   have  a  .PHONY attributed target as a prerequisite will be
                   made each time the .PHONY attributed prerequisite is  made.

       .PRECIOUS   Do  not  remove  associated target under any circumstances.
                   Set by default for any targets  whose  corresponding  files
                   exist in the file system prior to the execution of dmake.

       .PROLOG     Insert  shell  prolog  code  when  executing a group recipe
                   associated with any target having this attribute set.

       .SEQUENTIAL Force  a  sequential  make  of  the   associated   target’s
                   prerequisites.  If  set  as a global attribute this implies
                   setting MAXPROCESS=1.

       .SETDIR     Change current working  directory  to  specified  directory
                   when  making  the  associated target.  You must specify the
                   directory at the time the attribute is  specified.   To  do
                   this  simply  give  .SETDIR=path as the attribute.  path is
                   expanded and the  result  is  used  as  the  value  of  the
                   directory to change to.  If path contains $$@ then the name
                   of the target to be built is used in computing the path  to
                   change  directory  to.   If  path  is  surrounded by single
                   quotes then path is not expanded, and is used literally  as
                   the   directory   name.   If  the  path  contains  any  ‘:’
                   characters then the entire attribute string must be  quoted
                   using  ".   If  a target having this attribute set also has
                   the .IGNORE  attribute  set  then  if  the  change  to  the
                   specified  directory fails it will be ignored, and no error
                   message will be issued.

       .SILENT     Do not echo the recipe lines when making  any  target  with
                   this attribute set, and do not issue any warnings.

       .SWAP       Under  MSDOS  when  making a target with this attribute set
                   swap the dmake executable to disk prior  to  executing  the
                   recipe  line.  Also see the ’%’ recipe line flag defined in
                   the RECIPES section.

       .SYMBOL     Target is a library member and is an  entry  point  into  a
                   module  in  the  library.  This attribute is used only when
                   searching a library for a  target.   Targets  of  the  form
                   lib((entry)) have this attribute set automatically.

       .USESHELL   Force  each  recipe line of a target to be executed using a
                   shell.   Specifying  this  attribute   is   equivalent   to
                   specifying the ’+’ character at the start of each line of a
                   non-group recipe.

       .UPDATEALL  Indicates that all the targets  listed  in  this  rule  are
                   updated  by  the  execution  of the accompanying recipe.  A
                   common example is the production of the y.tab.c and y.tab.h
                   files  by  yacc  when  it  is run on a grammar.  Specifying
                   .UPDATEALL in such a rule  prevents  the  running  of  yacc
                   twice,  once  for the y.tab.c file and once for the y.tab.h
                   file.  .UPDATEALL targets that are specified  in  a  single
                   rule  are treated as a single target and all timestamps are
                   updated whenever any target in the set is made.  As a side-
                   effect,  dmake  internally  sorts such targets in ascending
                   alphabetical order and the value of $@ is always the  first
                   target in the sorted set.

       .WINPATH    Switch  between  default  (POSIX)  and  Windows  style path
                   representation.  (This attribute  is  specific  for  cygwin
                   dmake  executables  and non-cygwin environments ignore this
                   attribute.)

                   Under Cygwin it can be useful  to  generate  Windows  style
                   paths  (with regular slashes) instead of the default cygwin
                   style  (POSIX)  paths  for  dmake’s  dynamic  macros.   The
                   affected  macros  are  $@,  $*,  $>,  $?,  $<,  $&,  $^ and
                   $(MAKEDIR), $(PWD), $(TMD), $(TMPFILE) and the $(mktmp ...)
                   function  macro.   This  feature  can be used to create DOS
                   style path parameters for native W32 programs from  dynamic
                   macros.

                   Note that the Windows style paths use regular slashes (’/’)
                   instead of the usual Windows backslash (’\’)  as  directory
                   separator  to avoid quoting problems (after all it is still
                   a cygwin dmake!) and cygwin, as  well  as  native  Windows,
                   programs  should  have  no problems using this (c:/foo/bar)
                   path representation.

                   Example: Assuming the current target  to  be  /tmp/mytarget
                   the $@ macro without .WINPATH active expands to:

                          /tmp/mytarget

                   With .WINPATH set it expands to:

                          C:/cygwin/tmp/mytarget

       All  attributes are user setable and except for .UPDATEALL and .MKSARGS
       may be used in one of two forms.  The .MKSARGS attribute is  restricted
       to  use  as a global attribute, and the use of the .UPDATEALL attribute
       is restricted to rules of the second form only.

       ATTRIBUTE_LIST : targets

       assigns the attributes specified by ATTRIBUTE_LIST to  each  target  in
       targets or

       targets ATTRIBUTE_LIST : ...

       assigns  the  attributes  specified by ATTRIBUTE_LIST to each target in
       targets.  In the first form if targets is empty (ie. a NULL list), then
       the  list of attributes will apply to all targets in the makefile (this
       is equivalent to the common Make construct of ".IGNORE :" but has  been
       modified  to  the  notion of an attribute instead of a special target).
       Not  all  of  the  attributes  have  global  meaning.   In  particular,
       .LIBRARY,  .NOSTATE,  .PHONY,  .SETDIR,  .SYMBOL and .UPDATEALL have no
       assigned global meaning.

       Any attribute may be used  with  any  target,  even  with  the  special
       targets.   Some  combinations are useless (e.g. .INCLUDE .PRECIOUS: ...
       ), while others are useful (e.g. .INCLUDE .IGNORE : "file.mk" will  not
       complain  if  file.mk  cannot  be  found  using the include file search
       rules, see  the  section  on  SPECIAL  TARGETS  for  a  description  of
       .INCLUDE).   If a specified attribute will not be used with the special
       target a warning is issued and the attribute is ignored.

MACROS

       dmake supports six forms of macro assignment.

        MACRO = LINE   This is the most common  and  familiar  form  of  macro
                       assignment.   It assigns LINE literally as the value of
                       MACRO.  Future expansions of MACRO  recursively  expand
                       its value.

        MACRO *= LINE  This  form  behaves exactly as the simple ’=’ form with
                       the exception that if MACRO already has  a  value  then
                       the assignment is not performed.

        MACRO := LINE  This  form  differs from the simple ’=’ form in that it
                       expands LINE prior to assigning  it  as  the  value  of
                       MACRO.   Future  expansions of MACRO do not recursively
                       expand its value.

        MACRO *:= LINE This form behaves exactly as the  ’:=’  form  with  the
                       exception  that  if  MACRO already has a value then the
                       assignment and expansion are not performed.

        MACRO += LINE  This form of macro assignment allows  macro  values  to
                       grow.   It  takes the literal value of LINE and appends
                       it to the previous value of MACRO separating the two by
                       a single space.  Future expansions of MACRO recursively
                       expand its value.

        MACRO +:= LINE This form is similar to the ’+=’ form except  that  the
                       value  of  LINE is expanded prior to being added to the
                       value of MACRO.

       Macro expressions specified on the command line allow the  macro  value
       to  be redefined within the makefile only if the macro is defined using
       the ’+=’ and ’+:=’ operators.  Other operators will define a macro that
       cannot be further modified.

       Each  of the preceeding macro assignment operators may be prefixed by !
       to indicate that the assignment should be forced and that  no  warnings
       should  be  issued.   Thus,  specifying  !  has  the effect of silently
       forcing the specified macro assignment.

       When dmake defines  a  non-environment  macro  it  strips  leading  and
       trailing  white  space  from the macro value.  Macros imported from the
       environment via either the .IMPORT  special  target  (see  the  SPECIAL
       TARGETS section), or the -e, or -E flags are an exception to this rule.
       Their values are always  taken  literally  and  white  space  is  never
       stripped.   In addition, named macros defined using the .IMPORT special
       target do not have their values expanded when they are  used  within  a
       makefile.  In contrast, environment macros that are imported due to the
       specification of the -e or -E flags are subject to expansion when used.

       To  specify  a macro expansion enclose the name in () or {} and precede
       it with a dollar sign $.  Thus $(TEST) represents an expansion  of  the
       macro variable named TEST.  If TEST is defined then $(TEST) is replaced
       by its expanded value.  If TEST is not defined then $(TEST) expands  to
       the  NULL  string (this is equivalent to defining a macro as ’TEST=’ ).
       A short form may be used for single character named  macros.   In  this
       case the parentheses are optional, and $(I) is equivalent to $I.  Macro
       expansion  is  recursive,  hence,  if  the  value  string  contains  an
       expression  representing a macro expansion, the expansion is performed.
       Circular macro expansions are detected and cause an error to be issued.

       When  defining  a  macro  the given macro name is first expanded before
       being used to define the macro.  Thus it is possible to  define  macros
       whose names depend on values of other macros.  For example, suppose CWD
       is defined as

       CWD = $(PWD:b)

       then the value of $(CWD) is the name of the  current  directory.   This
       can be used to define macros specific to this directory, for example:

       _$(CWD).prt = list of files to print...

       The  actual  name  of  the  defined  macro is a function of the current
       directory.  A construct such  as  this  is  useful  when  processing  a
       hierarchy  of  directories  using  .SETDIR  attributed  targets  and  a
       collection of small distributed makefile stubs.

       Macro variables may be defined within  the  makefile,  on  the  command
       line, or imported from the environment.

       dmake  supports  several non-standard macro expansions: The first is of
       the form:

              $(macro_name:modifier_list:modifier_list:...)

       where modifier_list may be a combination of:

              b or B - file (not including suffix) portion of path names
              d or D - directory portion of all path names
              e or E - suffix portion of path names
              f or F - file (including suffix) portion of path names
              i or I - inferred names of targets
              n or N - normalized path names
              l or L - macro value in lower case
              u or U - macro value in upper case
              1      - return the first white space separated token from value

       or a single one of:

              m or M - map escape codes found in macro to their ASCII value
              s or S - simple pattern substitution
              t or T - tokenization.
              ^      - prepend a prefix to each token
              +      - append a suffix to each token

       Thus if we have the example:
              test = d1/d2/d3/a.out f.out d1/k.out
       The following macro expansions produce the values on the right  of  ’→’
       after expansion.

              $(test:d)             → d1/d2/d3/ d1/
              $(test:b)             → a f k
              $(test:f)             → a.out f.out k.out
              ${test:db}            → d1/d2/d3/a f d1/k
              ${test:s/out/in/:f}   → a.in f.in k.in
              $(test:f:t"+")        → a.out+f.out+k.out
              $(test:e)             → .out .out .out
              $(test:u)             → D1/D2/D3/A.OUT F.OUT D1/K.OUT
              $(test:1)             → d1/d2/d3/a.out

       For this macro
              test = d1/d2/../a.out "d1/file name.ext"
       the following results are returned:

              $(test:n)             → d1/a.out "d1/file name.ext"

       If  a  token  ends  in  a  string  composed from the value of the macro
       DIRBRKSTR (ie. ends in a directory separator string, e.g. ’/’ in  UNIX)
       and  you  use  the :d modifier then the expansion returns the directory
       name less the final directory separator string.  Thus successive  pairs
       of :d modifiers each remove a level of directory in the token string.

       The  infered  names of targets :i modifier returnes the actual filename
       associated to the target, see BINDING TARGETS. If the value  is  not  a
       target  or  prerequisite  the  value  is  returned  unchanged.  For the
       following example:
              test = aprog bprog
       If aprog and bprog are targets or prerequisits and they  are  bound  to
       /tmp/aprog  and  bprog (see .SOURCE special target) the macro expansion
       has the following effect:

              $(test:i)             → /tmp/aprog bprog

       The normalized path names :n modifier honors the setting of .WINPATH to
       determine the output format of the result.

       The  map escape codes modifier changes the following escape codes \a =>
       <bel>, \b => <backspace>, \f => <formfeed>, \n => <nl>, \r => <cr>,  \t
       => <tab>, \v => <vertical tab>, \" => ", and \xxx => <xxx> where xxx is
       the octal representation of a character into  the  corresponding  ASCII
       value.

       The  tokenization,  prepend and append modifier may use the same escape
       codes that are supported by the map escape codes modifier in the string
       that  is inserted, prepended or added by the respective macro modifier.
       These modifiers may quote this string to include otherwise  problematic
       characters.  E.g. spaces, colons and parentheses.

       The  tokenization  modifier takes all white space separated tokens from
       the macro value and separates them by the separator string.   Thus  the
       expansion:

              $(test:f:t"+\n")
       produces:
              a.out+
              f.out+
              k.out

       The  prefix  operator ^ takes all white space separated tokens from the
       macro value and prepends string to each.

              $(test:f:^mydir/)
       produces:
              mydir/a.out mydir/f.out mydir/k.out

       The suffix operator + takes all white space separated tokens  from  the
       macro value and appends string to each.

              $(test:b:+.c)
       produces:
              a.c f.c k.c

       The  next  non-standard  form  of  macro expansion allows for recursive
       macros.  It is possible to specify  a  $(macro_name)  or  ${macro_name}
       expansion  where  macro_name  contains  more $( ... ) or ${ ... } macro
       expansions itself.

       For    example    $(CC$(_HOST)$(_COMPILER))    will    first     expand
       CC$(_HOST)$(_COMPILER)  to get a result and use that result as the name
       of the macro to expand.  This is useful for writing a makefile for more
       than  one  target  environment.   As  an example consider the following
       hypothetical case.  Suppose that _HOST and _COMPILER are imported  from
       the  environment and are set to represent the host machine type and the
       host compiler respectively.

              CFLAGS_VAX_CC = -c -O  # _HOST == "_VAX", _COMPILER == "_CC"
              CFLAGS_PC_MSC = -c -ML # _HOST == "_PC",  _COMPILER == "_MSC"

              # redefine CFLAGS macro as:

              CFLAGS := $(CFLAGS$(_HOST)$(_COMPILER))

       This causes  CFLAGS  to  take  on  a  value  that  corresponds  to  the
       environment in which the make is being invoked.

       The final non-standard macro expansion is of the form:

              string1{token_list}string2

       where  string1,  string2 and token_list are expanded.  After expansion,
       string1 is prepended to each token found in token_list and  string2  is
       appended  to  each  resulting token from the previous prepend.  string1
       and string2 are not delimited by white  space  whereas  the  tokens  in
       token_list  are.  A null token in the token list is specified using "".
       Thus using another example we have:

              test/{f1 f2}.o     --> test/f1.o test/f2.o
              test/ {f1 f2}.o    --> test/ f1.o f2.o
              test/{f1 f2} .o    --> test/f1 test/f2 .o
              test/{"f1"  ""}.o  --> test/f1.o test/.o

              and

              test/{d1 d2}/{f1 f2}.o --> test/d1/f1.o test/d1/f2.o
                                         test/d2/f1.o test/d2/f2.o

       This last expansion is activated only  when  the  first  characters  of
       token_list appear immediately after the opening ’{’ with no intervening
       white  space.   The  reason  for  this  restriction  is  the  following
       incompatibility with Bourne Shell recipes.  The line

              { echo hello;}

       is valid /bin/sh syntax; while

              {echo hello;}

       is  not.  Hence  the latter triggers the enhanced macro expansion while
       the former causes it to be suppressed.  See the SPECIAL MACROS  section
       for  a  description  of  the  special  macros  that  dmake  defines and
       understands.

RULES AND TARGETS

       A makefile contains a series  of  entries  that  specify  dependencies.
       Such  entries are called target/prerequisite or rule definitions.  Each
       rule definition is optionally followed by a set of lines that provide a
       recipe  for  updating  any targets defined by the rule.  Whenever dmake
       attempts to bring a target  up  to  date  and  an  explicit  recipe  is
       provided with a rule defining the target, that recipe is used to update
       the target.  A rule definition begins with a line having the  following
       syntax:

              <targets> [<attributes>] <ruleop> [<prerequisites>] [;<recipe>]

       targets  is  a  non-empty  list of targets.  If the target is a special
       target (see SPECIAL TARGETS section below) then it must appear alone on
       the rule line.  For example:

              .IMPORT .ERROR : ...

       is  not  allowed  since  both  .IMPORT  and .ERROR are special targets.
       Special targets are not used in  the  construction  of  the  dependency
       graph and will not be made.

       attributes  is  a  possibly  empty  list  of attributes.  Any attribute
       defined  in  the  ATTRIBUTES  section  above  may  be  specified.   All
       attributes  will  be  applied  to the list of named targets in the rule
       definition.  No other targets will be affected.

        NOTE:  As stated earlier, if both the  target  list  and  prerequisite
               list  are  empty  but  the  attributes  list  is  not, then the
               specified attributes affect all targets in the makefile.

       ruleop is a separator which is used to identify the  targets  from  the
       prerequisites.   Optionally  it  also provides a facility for modifying
       the way in which dmake handles the making of  the  associated  targets.
       In  its  simplest  form  the  operator is a single ’:’, and need not be
       separated  by  white  space  from  its  neighboring  tokens.   It   may
       additionally  be  followed  by  any of the modifiers { !, ^, -, :, | },
       where:

       !      says execute the recipe for the associated targets once for each
              out  of date prerequisite.  (The meaning of the runtime macro $?
              is changed, see below in the RUNTIME MACROS section.) Ordinarily
              the recipe is executed once for all out of date prerequisites at
              the same time.

       ^      says to insert the specified prerequisites, if any,  before  any
              other   prerequisites  already  associated  with  the  specified
              targets.  In general, it is not useful  to  specify  ^  with  an
              empty list of prerequisites.

       -      says  to  clear the previous list of prerequisites before adding
              the new prerequisites.  Thus,

              foo :
              foo : bar baz

              can be replaced by

              foo :- bar baz

              however the old form still works as expected.

       :      When the rule operator is not modified by a second ’:’ only  one
              set  of  rules  may  be specified for making a target.  Multiple
              definitions may be used to add to the list of prerequisites that
              a  target  depends on.  However, if a target is multiply defined
              only one definition may specify a recipe for making the  target.

              When  a  target’s  rule operator is modified by a second ’:’ (::
              for example) then this definition may not be the only definition
              with  a  recipe  for  the  target.  There may be other :: target
              definition lines that specify a different set  of  prerequisites
              with  a  different  recipe  for  updating  the target.  Any such
              target is made if any of the definitions find it to  be  out  of
              date   with   respect  to  the  related  prerequisites  and  the
              corresponding  recipe  is  used  to  update  the   target.    By
              definition all ’::’ recipes that are found to be out of date for
              are executed.

              In the following simple example, each rule has  a  ‘::’  ruleop.
              In  such an operator we call the first ‘:’ the operator, and the
              second ‘:’ the modifier.

              a.o :: a.c b.h
                 first recipe for making a.o

              a.o :: a.y b.h
                 second recipe for making a.o

              If a.o is found to be out of date with respect to a.c  then  the
              first  recipe  is  used to make a.o.  If it is found out of date
              with respect to a.y then the second recipe is used.  If  a.o  is
              out of date with respect to b.h then both recipes are invoked to
              make a.o.  In the last case the order of invocation  corresponds
              to  the  order  in  which  the  rule  definitions  appear in the
              makefile.

       |      Is defined only  for  PERCENT  rule  target  definitions.   When
              specified  it  indicates  that the following construct should be
              parsed using the old semantinc meaning:

              %.o :| %.c %.r %.f ; some rule

              is equivalent to:

              %.o : %.c ; some rule
              %.o : %.r ; some rule
              %.o : %.f ; some rule

       Targets defined using a single  ‘:’  operator  with  a  recipe  may  be
       redefined  again  with  a new recipe by using a ‘:’ operator with a ‘:’
       modifier.  This is equivalent to a target having been initially defined
       with a rule using a ‘:’ modifier.  Once a target is defined using a ‘:’
       modifier it may not be defined again with a recipe using only  the  ‘:’
       operator with no ‘:’ modifier.  In both cases the use of a ‘:’ modifier
       creates  a  new  list  of  prerequisites  and  makes  it  the   current
       prerequisite  list  for  the  target.   The ‘:’ operator with no recipe
       always modifies the current list of prerequisites.  Thus assuming  each
       of the following definitions has a recipe attached, then:

              joe :  fred ...     (1)
              joe :: more ...     (2)

              and

              joe :: fred ...     (3)
              joe :: more ...     (4)

       are  legal and mean:  add the recipe associated with (2), or (4) to the
       set of recipes for joe, placing them after existing recipes for  making
       joe.  The constructs:

              joe :: fred ...     (5)
              joe : more ... (6)

              and

              joe : fred ... (7)
              joe : more ... (8)

       are  errors since we have two sets of perfectly good recipes for making
       the target.

       prerequisites is a possibly empty list of targets that must be  brought
       up to date before making the current target.

       recipe  is  a  short  form  and  allows  the user to specify short rule
       definitions on a single line.  It is taken to be the first recipe  line
       in  a larger recipe if additional lines follow the rule definition.  If
       the semi-colon is present but  the  recipe  line  is  empty  (ie.  null
       string)  then  it  is taken to be an empty rule.  Any target so defined
       causes target to be treated as a virtual target,  see  VIRTUAL  TARGETS
       below.

RECIPES

       The traditional format used by most versions of Make defines the recipe
       lines as arbitrary strings that may  contain  macro  expansions.   They
       follow  a  rule  definition  line and may be spaced apart by comment or
       blank  lines.   The  list  of  recipe  lines  defining  the  recipe  is
       terminated  by  a new target definition, a macro definition, or end-of-
       file.  Each recipe line MUST begin with a <TAB> character  (or  spaces,
       see  .NOTABS)  which  may  optionally  be  followed with one or all the
       following recipe property characters @%+-  which  affect  the  recipe
       execution:

       ’-’    indicates  that  non-zero  exit  values  (ie.  errors) are to be
              ignored when this recipe line is executed.

       ’+’    indicates that the current recipe line is to be  executed  using
              the shell. Group recipes implicitely ignore this property.

       ’%’    indicates that dmake should swap itself out to secondary storage
              (MSDOS only) before running the recipe.

       ’@’    indicates that the recipe line  should  NOT  be  echoed  to  the
              terminal prior to being executed.

       ’@@’   is  a stronger version of the previous property. The recipe line
              and the output (stdout and stderr) of the  executed  recipe  are
              NOT shown on the terminal.

       Each   property   is  off  by  default  (ie.  by  default,  errors  are
       significant, commands are echoed, no swapping is done and  a  shell  is
       used only if the recipe line contains a character found in the value of
       the SHELLMETAS macro).  Global  settings  activated  via  command  line
       options  or  special  attribute  or  target names may also affect these
       settings.  An example recipe:

              target :
                     first recipe line
                     second recipe line, executed independent of first.
                     @a recipe line that is not echoed
                     -and one that has errors ignored
                     %and one that causes dmake to swap out
                     +and one that is executed using a shell.

       The second and new format of the recipe block begins the block with the
       character  ’[’  (the  open group character) in the last non-white space
       position of a line, and terminates the block  with  the  character  ’]’
       (the  close group character) in the first non-white space position of a
       line.  In this form each recipe line need not have a leading TAB.  This
       is called a recipe group.  Groups so defined are fed intact as a single
       unit to a shell for execution whenever the corresponding  target  needs
       to  be  updated.  If the open group character ’[’ is preceded by one or
       all of the recipe properties (-, %, @ and @@) then they  apply  to  the
       entire  group  in  the same way that they apply to single recipe lines.
       You may also specify ’+’ but it is redundant  as  a  shell  is  already
       being  used  to  run  the recipe.  See the MAKING TARGETS section for a
       description of how dmake invokes recipes.  Here  is  an  example  of  a
       group recipe:

              target :
              [
                 first recipe line
                 second recipe line
                 tall of these recipe lines are fed to a
                 single copy of a shell for execution.
              ]

BUILTIN COMMANDS

       dmake supports some builtin commands. An optional leading ’+’ describes
       that the builtin can be used  also  when  being  executed  in  a  shell
       otherwise it is only implemented when used directly. Remember that if a
       character of the recipe is found in the SHELLMETAS macro the  execution
       of the recipe in a shell is forced.

       [+]noop [something]
              The  noop internal command always returns success if used but it
              is not executed even though  the  rest  of  the  commandline  is
              evaluated.    This   command  can  be  used  to  evaluate  macro
              expansions at the runtime of the recipe without starting a  real
              commmand.

       [+]<empty recipe>
              If  an empty recipe line is encountered it is not executed. This
              sounds more trivial than it really is because the  recipe  could
              consist  of  macros  that  evaluated to empty or whitespace only
              strings.

       echo [-n] data
              This internal command prints data (with all  leading  whitespace
              removed,  but otherwise literally) to stdout. If the ’-n’ switch
              is given no trailing newline is printed. Note that no quoting is
              removed nor that escape sequences are handled.

       No   special  treatment  of  buildin  commands  for  group  recipes  is
       implemented even though the <empty recipe> will most propably also  not
       be  evaluated  by  most  shells  that  can be used to handle the recipe
       groups.

TEXT DIVERSIONS

       dmake supports the  notion  of  text  diversions.   If  a  recipe  line
       contains the macro expression

              $(mktmp[,[file][,text]] data)

       then  all  text  contained  in  the  data expression is expanded and is
       written to a temporary file.  The data  in  the  file  will  always  be
       terminated  from  a new line character.  The file parameter can be used
       to override the name of the temporary file. If its  expanded  value  is
       not  empty  it  will be used instead of the unique and thread safe file
       name that otherwise would be generated internally.  The return value of
       the  macro  is the name of the temporary file unless the text parameter
       is defined. In this case the return value  is  the  expanded  value  of
       text.

       data  can be any text and must be separated from the ’mktmp’ portion of
       the macro name by white-space.  The only restriction on the  data  text
       is  that  it  must contain a balanced number of parentheses of the same
       kind as are used to initiate the $(mktmp ...) expression.  For example:

              $(mktmp $(XXX))

       is legal and works as expected, but:

              $(mktmp text (to dump to file)

       is not legal.  You can achieve what you wish by either defining a macro
       that expands to ’(’ or by using {} in the macro expression; like this:

              ${mktmp text (to dump to file}

       Since the temporary file is opened when the macro containing  the  text
       diversion  expression  is  expanded,  diversions  may be nested and any
       diversions that are created as part of ’:=’  macro  expansions  persist
       for  the duration of the dmake run.  If the data text is to contain new
       lines the map escape codes macro expasion can be used.  For example the
       expression:

              mytext:=this is a\ntest of the text diversion
              all:
                   cat $(mktmp $(mytext:m))

       is replaced by:

              cat /tmp/mk12294AA

       where  the  temporary  file  contains  two  lines  both  of  which  are
       terminated by a new-line.  A second more illustrative example generates
       a response file to an MSDOS link command:

              OBJ = fred.obj mary.obj joe.obj
              all : $(OBJ)
                   link @$(mktmp $(^:t"+\n"))

       The result of making ‘all’ in the second example is the command:

              link @/tmp/mk02394AA

       where the temporary file contains:

              fred.obj+
              mary.obj+
              joe.obj

       The  last  line of the file is terminated by a new-line which is always
       inserted at the end of the data string.

       If the optional file specifier is present it can be used to specify the
       name  of the temporary file to create.  An example that would be useful
       for MSDOS users with a Turbo-C compiler

              $(mktmp,turboc.cfg $(CFLAGS))

       will place the contents of CFLAGS into a local  turboc.cfg  file.   The
       second optional argument, text, if present alters the name of the value
       returned by the $(mktmp ...) macro.

       Under MS-DOS text diversions may be a problem.  Many DOS tools  require
       that  path  names  which  contain  directories  use  the \ character to
       delimit the directories.  Some users however wish to  use  the  ’/’  to
       delimit  pathnames  and use environments that allow them to do so.  The
       macro USESHELL is set to "yes" if the current recipe is forced to use a
       shell via the .USESHELL or ’+’ directives, otherwise its value is "no".
       The dmake startup files define the macro DIVFILE whose value is  either
       the  value of TMPFILE or the value of TMPFILE edited to replace any ’/’
       characters to the appropriate value based  on  the  current  shell  and
       whether it will be used to execute the recipe.

       Previous  versions  of  dmake  defined  text  diversions  using  <+, +>
       strings, where <+ started a  text  diversion  and  +>  terminated  one.
       dmake  is backward compatible with this construct only if the <+ and +>
       appear literally on the same recipe line or in  the  same  macro  value
       string.  In such instances the expression:

       <+data+>

       is mapped to:

       $(mktmp data)

       which  is  fully  output compatible with the earlier construct.  <+, +>
       constructs whose text spans multiple lines must be converted by hand to
       use $(mktmp ...).

       If  the  environment variable TMPDIR is defined then the temporary file
       is placed into the directory specified by that  variable.   A  makefile
       can  modify  the  location of temporary files by defining a macro named
       TMPDIR and exporting it using the .EXPORT special target.

VIRTUAL TARGETS

       Dmake allows to define targets with  the  sole  purpose  to  enforce  a
       dependency  chain  that  are unable to create the target, hence virtual
       targets.  When dmake tries to make a target, but only  finds  a  target
       definition without recipe lines, it would normally issues a "Dont know
       how to make ..." error message, but if a target rule is terminated by a
       semicolon  and  has  no  following recipe lines, or if it has no recipe
       lines, but defines prerequisites, or if the  AUGMAKE  mode  is  enabled
       (see the COMPATIBILITY section for details), the target is treated as a
       virtual target and the error is suppressed. In addition to this, if the
       default  target  does  not  have  recipe  lines it is also treated as a
       virtual target.

       Virtual targets should not have a  corresponding  file  therefore  they
       inherit   the   time   of   their  newest  prerequisite  if  they  have
       prerequisites, otherwise they get the current time assigned when  being
       made.   If  the  virtual  target  has a corresponding file a warning is
       issued, but the time stamp of that file  is  taken  into  account.  The
       virtual  target  uses the time stamp of the corresponding file if it is
       newer than the one determined by the previous rule.

SPECIAL TARGETS

       This section describes the  special  targets  that  are  recognized  by
       dmake.  Some are affected by attributes and others are not.

       .ERROR        If defined then the recipe associated with this target is
                     executed whenever  an  error  condition  is  detected  by
                     dmake.   All  attributes  that can be used with any other
                     target may be used with this target.   Any  prerequisites
                     of  this  target  will  be  brought up to date during its
                     processing.  NOTE:  errors will be ignored  while  making
                     this  target,  in  extreme  cases  this  may  cause  some
                     problems.

       .EXIT         If this target is encountered while  parsing  a  makefile
                     then   the   parsing   of  the  makefile  is  immediately
                     terminated at that point.

       .EXPORT       All prerequisites associated with this target are assumed
                     to  correspond  to  macro names and they and their values
                     are exported to the environment as environment strings at
                     the  point  in the makefile at which this target appears.
                     Any attributes specified with this  target  are  ignored.
                     Only  macros  which  have  been  assigned  a value in the
                     makefile prior to  the  export  directive  are  exported,
                     macros  as  yet  undefined or macros whose value contains
                     any of the characters "+=:*" are not exported.

                     Note that macros that are not expanded during  the  macro
                     assignment  and contain other macros will be written into
                     the environment containing these other macros in the form
                     of $(macroname).

       .IMPORT       Prerequisite names specified for this target are searched
                     for in the environment and defined as macros  with  their
                     value  taken  from  the environment.  If the special name
                     .EVERYTHING is used  as  a  prerequisite  name  then  all
                     environment  variables  defined  in  the  environment are
                     imported.  The functionality of the -E flag can be forced
                     by  placing  the  construct  .IMPORT : .EVERYTHING at the
                     start of a makefile.  Similarly, by placing the construct
                     at  the end, one can emulate the effect of the -e command
                     line flag.  If a prerequisite name cannot be found in the
                     environment  an error message is issued.  .IMPORT accepts
                     the .IGNORE attribute.  When given, it  causes  dmake  to
                     ignore  the  above  error.   See the MACROS section for a
                     description of the processing of imported macro values.

       .INCLUDE      Parse another makefile just as if it had been located  at
                     the  point  of the .INCLUDE in the current makefile.  The
                     list of prerequisites gives the list of makefiles to  try
                     to  read.   If  the list contains multiple makefiles then
                     they are read in order from left to right.  The following
                     search rules are used when trying to locate the file.  If
                     the filename is surrounded by " or just by itself then it
                     is  searched  for in the current directory.  If it is not
                     found it is then searched for in each of the  directories
                     specified  as  prerequisites  of the .INCLUDEDIRS special
                     target.  If the file name is surrounded by < and >,  (ie.
                     <my_spiffy_new_makefile>) then it is searched for only in
                     the directories given by the .INCLUDEDIRS special target.
                     In  both cases if the file name is a fully qualified name
                     starting at the root of the file system then it  is  only
                     searched  for once, and the .INCLUDEDIRS list is ignored.
                     If .INCLUDE  fails  to  find  the  file  it  invokes  the
                     inference  engine to try to infer and hence make the file
                     to be included.  In this way the file can be checked  out
                     of  an  RCS repository for example.  .INCLUDE accepts the
                     .IGNORE,  .SETDIR,  and  .NOINFER  attributes.   If   the
                     .IGNORE  attribute  is given and the file cannot be found
                     then  dmake  continues  processing,  otherwise  an  error
                     message is generated.  If the .NOINFER attribute is given
                     and the file cannot be found then dmake will not  attempt
                     to infer and make the file.  The .SETDIR attribute causes
                     dmake to change directories to  the  specified  directory
                     prior  to attempting the include operation.  If all fails
                     dmake attempts to make  the  file  to  be  included.   If
                     making  the  file  fails then dmake terminates unless the
                     .INCLUDE directive also specified the .IGNORE  attribute.
                     If  .FIRST  is  specified  along with .INCLUDE then dmake
                     attempts to include  each  named  prerequisite  and  will
                     terminate  the inclusion with the first prerequisite that
                     results in a successful inclusion.

       .INCLUDEDIRS  The list  of  prerequisites  specified  for  this  target
                     defines  the  set of directories to search when trying to
                     include a makefile.

       .KEEP_STATE   This special target is a synonym for the macro definition

                     .KEEP_STATE := _state.mk

                     It’s  effect  is  to  turn on STATE keeping and to define
                     _state.mk as the state file.

       .MAKEFILES    The list of prerequisites is the set of files to  try  to
                     read  as the default makefile.  By default this target is
                     defined as:

                     .MAKEFILES : makefile.mk Makefile makefile

       .REMOVE       The recipe of this target is used whenever dmake needs to
                     remove  intermediate  targets  that  were made but do not
                     need to be kept around.  Such  targets  result  from  the
                     application  of  transitive  closure  on  the  dependency
                     graph.

       .ROOT         The internal root of the dependency  graph,  see  section
                     STARTUP for details.

       .SOURCE       The  prerequisite  list  of  this target defines a set of
                     directories to check when trying to locate a target  file
                     name.   See  the  section  on BINDING of targets for more
                     information.

       .SOURCE.suff  The same as .SOURCE, except that the .SOURCE.suff list is
                     searched  first when trying to locate a file matching the
                     a target whose name ends in the suffix .suff.

       .SUFFIXES     This deprecated special target has  no  special  meaning.
                     Avoid its use.

       .TARGETS      The  internal  targets  that all user defined targets are
                     prerequisites of, see section STARTUP for details.

       There are a few targets that are "slightly" special:

              .INIT
              .DONE

       These targets exist because of historical reasons,  see  the  usage  of
       .INIT  and  .DONE in section "STARTUP", they can be used and defined as
       ordinary targets but are special in the sense  that  even  though  they
       start  with a ‘.’  they are not treated as a .<suffix> meta target (See
       the AUGMAKE META RULES section for details).

       Please note that self defined targets shouldn’t use the prefix  ‘.’  as
       they would be handled as .<suffix> meta targets and dmake most propably
       would complain about this.

       In addition to the  special  targets  above,  several  other  forms  of
       targets are recognized and are considered special, their exact form and
       use is defined in the sections that follow.

SPECIAL MACROS

       dmake defines a number of special macros.  They are divided into  three
       classes:  control  macros,  run-time  macros, and function macros.  The
       control macros are used by dmake to configure its actions, and are  the
       preferred method of doing so.  In the case when a control macro has the
       same function as a special target or attribute they share the same name
       as  the  special  target or attribute.  The run-time macros are defined
       when dmake makes targets and may be used by the  user  inside  recipes.
       The  function  macros provide higher level functions dealing with macro
       expansion and diversion file processing.

CONTROL MACROS

       To use the control macros simply assign them  a  value  just  like  any
       other  macro.  The control macros are divided into three groups: string
       valued macros, character valued macros, and boolean valued macros.

       The following are all of  the  string  valued  macros.   This  list  is
       divided  into  two  groups.   The  first  group gives the string valued
       macros that are defined internally and cannot be directly  set  by  the
       user.

       ABSMAKECMD      Warning!  This macro’s value is differently defined for
                       a native Windows dmake  executable  (compiled  with  MS
                       Visual  C++  or  MinGW)  and  dmake for other operating
                       systems or build with other compilers.

                       In the first case its value is the absolute filename of
                       the  executable of the current dmake process, otherwise
                       it is defined as the NULL string.

       INCDEPTH        This macro’s value is a string of  digits  representing
                       the  current depth of makefile inclusion.  In the first
                       makefile level this value is zero.

       MFLAGS          Is the list of flags that were  given  on  the  command
                       line including a leading switch character.  The -f flag
                       is not included in this list.

       MAKECMD         Is the name with which dmake was invoked.

       MAKEDIR         Is the full path to  the  initial  directory  in  which
                       dmake was invoked.

       MAKEFILE        Contains  the  string  "-f makefile" where, makefile is
                       the name of initial user makefile that was first  read.

       MAKEFLAGS       Is  the  same  as  $(MFLAGS)  but has no leading switch
                       character. (ie. MFLAGS = -$(MAKEFLAGS))

       MAKEMACROS      Contains the complete list of  macro  expressions  that
                       were specified on the command line.

       MAKETARGETS     Contains  the  name(s)  of  the target(s), if any, that
                       were specified on the command line.

       MAKEVERSION     Contains a string indicating the current dmake  version
                       number.

       MAXPROCESSLIMIT Is  a numeric string representing the maximum number of
                       processes that dmake can use when making targets  using
                       parallel mode.

       NULL            Is  permanently defined to be the NULL string.  This is
                       useful when comparing a conditional  expression  to  an
                       NULL value.

       PWD             Is the full path to the current directory in which make
                       is executing.

       SPACECHAR       Is permanently defined to contain one space  character.
                       This  is useful when using space characters in function
                       macros, e.g. subst, that otherwise  would  get  deleted
                       (leading/trailing   spaces)  or  for  using  spaces  in
                       function macro parameters.

       TMPFILE         Is set to the name of the most  recent  temporary  file
                       opened  by  dmake.   Temporary  files are used for text
                       diversions and for group recipe processing.

       TMD             Stands for "To Make Dir", and  is  the  path  from  the
                       present  directory  (value  of $(PWD)) to the directory
                       that dmake was started up in (value of $(MAKEDIR)).  If
                       the  present  directory is the directory that dmake was
                       started up in TMD will be set to the relative path ".".
                       This   allows  to  create  valid  paths  by  prepending
                       $(TMD)$(DIRSEPSTR) to a relative path.  This  macro  is
                       modified  when  .SETDIR  attributes are processed.  TMD
                       will usually be a relative path with the following  two
                       exceptions.  If the relative path would go up until the
                       root directory or if different drive letters (DOS  file
                       system)  make  a  relative path impossible the absolute
                       path from MAKEDIR is used.

       USESHELL        The value of this macro is set to "yes" if the  current
                       recipe  is  forced to use a shell for its execution via
                       the .USESHELL or ’+’  directives,  its  value  is  "no"
                       otherwise.

       The second group of string valued macros control dmake behavior and may
       be set by the user.

       .DIRCACHE       If set to "yes" enables the directory  cache  (this  is
                       the  default).   If  set to "no" disables the directory
                       cache (equivalent to -d command-line flag).

       .DIRCACHERESPCASE
                       If set to "yes" causes the directory cache, if enabled,
                       to  respect  file case, if set to "no" files are cached
                       case insensitive.  By default it  is  set  to  "no"  on
                       Windows as the filesystems on this operating system are
                       case  insensitive  and  set  to  "yes"  for  all  other
                       operating  systems.  The  default  can be overriden, if
                       desired.

                       Note: Using case insensitive directory caching on  case
                       sensitive  file  systems is a BAD idea. If in doubt use
                       case  sensitive  directory   caching   even   on   case
                       insensitive  file  systems  as  the  worst case in this
                       scenario is that /foo/bar/  and  /foo/BAR/  are  cached
                       separately (with the same content) even though they are
                       the same directory. This would only happen if different
                       targets  use  different  upper/lower case spellings for
                       the same directory and that is never a good idea.

       NAMEMAX         Defines the maximum length  of  a  filename  component.
                       The  value of the variable is initialized at startup to
                       the value of the  compiled  macro  NAME_MAX.   On  some
                       systems  the value of NAME_MAX is too short by default.
                       Setting a new  value  for  NAMEMAX  will  override  the
                       compiled value.

       .NOTABS         When  set to "yes" enables the use of spaces as well as
                       <tabs> to begin recipe lines.  By default  a  non-group
                       recipe  is  terminated  by  a  line without any leading
                       white-space or by a line not  beggining  with  a  <tab>
                       character.   Enabling  this  mode  modifies  the  first
                       condition of the above termination rule to terminate  a
                       non-group   recipe  with  a  line  that  contains  only
                       white-space.  This mode does not effect the parsing  of
                       group recipes bracketed by [].

       AUGMAKE         If set to "yes" value will enable the transformation of
                       special  meta  targets  to  support   special   AUGMAKE
                       inferences   (See   the   "AUGMAKE   META   RULES"  and
                       "COMPATIBILITY" sections).

       DIRBRKSTR       Contains the string of chars used to terminate the name
                       of  a directory in a pathname.  Under UNIX its value is
                       "/", under MSDOS its value is "/\:".

       DIRSEPSTR       Contains the string that is used to separate  directory
                       components  when  path  names  are  constructed.  It is
                       defined with a default value at startup.

       DIVFILE         Is defined in the startup file and gives the name  that
                       should  be  returned  for  the diversion file name when
                       used in $(mktmp ...) expansions, see the TEXT DIVERSION
                       section for details.

       .KEEP_STATE     Assigning  this  macro  a value tells dmake the name of
                       the state file to use and turns on the keeping of state
                       information for any targets that are brought up to date
                       by the make.

       GROUPFLAGS      This macro gives the set of flags to pass to the  shell
                       when  invoking it to execute a group recipe.  The value
                       of the macro is the list of flags with a leading switch
                       indicator.  (ie. ‘-’ under UNIX)

       GROUPSHELL      This  macro  defines  the  full  path to the executable
                       image to be used as the  shell  when  processing  group
                       recipes.   This  macro must be defined if group recipes
                       are used.  It  is  assigned  a  default  value  in  the
                       startup makefile.  Under UNIX this value is /bin/sh.

       GROUPSUFFIX     If  defined,  this  macro  gives the string to use as a
                       suffix when creating group recipe files to be handed to
                       the command interpreter.  For example, if it is defined
                       as .sh, then all temporary files created by dmake  will
                       end  in  the  suffix .sh.  Under MSDOS if you are using
                       command.com as your GROUPSHELL, then this  suffix  must
                       be  set  to .bat in order for group recipes to function
                       correctly.  The setting of GROUPSUFFIX  and  GROUPSHELL
                       is done automatically for command.com in the startup.mk
                       files.

       MAKE            Is defined in the startup file by  default.   Initially
                       this  macro  is  defined  to have the value "$(MAKECMD)
                       $(MFLAGS)".  The  string  $(MAKE)  is  recognized  when
                       using the -n switch.

       MAKESTARTUP     This macro defines the full path to the initial startup
                       makefile.  Use the -V command line option  to  discover
                       its initial value.

       MAXLINELENGTH   This macro defines the maximum size of a single line of
                       makefile input  text.   The  size  is  specified  as  a
                       number,  the default value is defined internally and is
                       shown via the -V option.  A buffer of this size plus  2
                       is  allocated for reading makefile text.  The buffer is
                       freed before any targets  are  made,  thereby  allowing
                       files  containing  long  input  lines  to  be processed
                       without consuming memory during the actual make.   This
                       macro can only be used to extend the line length beyond
                       it’s default minimum value.

       MAXPROCESS      Specify the maximum number of child  processes  to  use
                       when  making  targets.  The default value of this macro
                       is "1" and its value cannot exceed  the  value  of  the
                       macro MAXPROCESSLIMIT.  Setting the value of MAXPROCESS
                       on the command line or in the makefile is equivalent to
                       supplying  a  corresponding value to the -P flag on the
                       command line. If the global  .SEQUENTIAL  attribute  is
                       set  (or  the -S command line switch is used) the value
                       of MAXPROCESS is fixed to "1" and cannot be changed.

       OOODMAKEMODE    This macro enables a special compatibility mode  needed
                       by  the OpenOffice.org build system. If set, the switch
                       disables the removal  of  leading  ’./’  path  elements
                       during   target  filename  normalization  (See  BINDING
                       TARGETS). If ’./’ appear in the pathname,  but  not  at
                       the  beginning  of  it,  they  are still removed by the
                       normalization. Please note that targets that are  given
                       on  the  command  line  are  going  to be registered as
                       default targets after the startup file is read.

       PREP            This macro defines  the  number  of  iterations  to  be
                       expanded   automatically   when   processing   %   rule
                       definitions of the form:

                       % : %.suff

                       See the sections on PERCENT(%) RULES for details on how
                       PREP is used.

       SHELL           This  macro  defines  the  full  path to the executable
                       image to be used as the shell  when  processing  single
                       line  recipes.   This  macro must be defined if recipes
                       requiring the shell for execution are to be  used.   It
                       is  assigned  a  default value in the startup makefile.
                       Under UNIX this value is /bin/sh.

       SHELLCMDQUOTE   This macro can be used  to  add  additional  characters
                       before  and  after the command string that is passed to
                       the shell defined by the SHELL macro.  If needed,  like
                       for  cmd.exe and command.com, it is assigned a value in
                       the startup file.

       SHELLFLAGS      This macro gives the set of flags to pass to the  shell
                       when  invoking it to execute a single line recipe.  The
                       value of the macro is the list of flags with a  leading
                       switch indicator.  (ie. ‘-’ under UNIX)

       SHELLMETAS      Each  time  dmake  executes a single recipe line (not a
                       group recipe) the line is searched for  any  occurrence
                       of  a character defined in the value of SHELLMETAS.  If
                       such a character is found the recipe line is defined to
                       require  a  shell  to ensure its correct execution.  In
                       such instances a shell is used  to  invoke  the  recipe
                       line.  If no match is found the recipe line is executed
                       without the use of a shell.

       There is only one character valued macro  defined  by  dmake:  SWITCHAR
       contains  the  switch  character  used  to introduce options on command
       lines.  For UNIX its value is ‘-’, and for MSDOS its value may  be  ‘/’
       or  ‘-’.  The macro is internally defined and is not user setable.  The
       MSDOS version of dmake attempts  to  first  extract  SWITCHAR  from  an
       environment  variable of the same name.  If that fails it then attempts
       to use the undocumented getswitchar system call, and returns the result
       of  that.   Under  MSDOS  version  4.0  you  must  set the value of the
       environment macro SWITCHAR to ’/’ to obtain predictable behavior.

       All boolean macros currently understood by dmake correspond directly to
       the  previously  defined attributes.  These macros provide a second way
       to apply global attributes, and represent the preferred method of doing
       so.   They  are  used by assigning them a value.  If the value is not a
       NULL string then the boolean condition is set to on.  If the value is a
       NULL  string  then  the  condition  is  set  to  off.   There  are five
       conditions defined and they correspond directly to  the  attributes  of
       the  same  name.   Their meanings are defined in the ATTRIBUTES section
       above.   The  macros  are:  .EPILOG,   .IGNORE,   .MKSARGS,   .NOINFER,
       .PRECIOUS,   .PROLOG,   .SEQUENTIAL,  .SILENT,  .SWAP,  and  .USESHELL.
       Assigning any  of  these  a  non  NULL  value  will  globally  set  the
       corresponding attribute to on.

RUNTIME MACROS

       These  macros are defined when dmake is making targets, and may take on
       different values for each target.  $@ is defined to be the full  target
       name, $? is the list of all out of date prerequisites, except for the !
       ruleop, in which case it is  set  to  the  current  build  prerequisite
       instead.   $&  is  the list of all prerequisites, $> is the name of the
       library if the current target is a library member, and $< is  the  list
       of  prerequisites specified in the current rule.  If the current target
       had a recipe inferred then $< is the name of the inferred  prerequisite
       even  if  the  target  had  a  list  of prerequisites supplied using an
       explicit rule that did not provide a recipe.   In  such  situations  $&
       gives the full list of prerequisites.

       $*  is defined as $(@:db) when making targets with explicit recipes and
       is defined as the value of % when making targets whose  recipe  is  the
       result  of  an inference.  In the first case $* is the target name with
       no suffix, and in the second case,  is  the  value  of  the  matched  %
       pattern  from  the  associated %-rule.  $^ expands to the set of out of
       date prerequisites taken from the current value of $<.  In addition  to
       these,  $$  expands  to  $,  {{  expands to {, }} expands to }, and the
       strings  <+  and  +>  are  recognized  as  respectively  starting   and
       terminating a text diversion when they appear literally together in the
       same input line.

       The difference between $? and $^ can best be illustrated by an example,
       consider:

              fred.out : joe amy hello
              rules for making fred

              fred.out : my.c your.h his.h her.h   # more prerequisites

       Assume joe, amy, and my.c are newer then fred.out.  When dmake executes
       the recipe for making fred.out the values of the following macros  will
       be:

              $@ --> fred.out
              $* --> fred
              $? --> joe amy my.c  # note output of $? vs $^
              $^ --> joe amy
              $< --> joe amy hello
              $& --> joe amy hello my.c your.h his.h her.h

FUNCTION MACROS

       dmake  supports  a  full  set  of functional macros.  One of these, the
       $(mktmp ...)  macro, is discussed  in  detail  in  the  TEXT  DIVERSION
       section  and  is  not  covered here.  The names of function macros must
       appear literally after the opening $( or ${. They are not recognized if
       they are the result of a recursive expansion.

       Note that some of these macros take comma separated parameters but that
       these parameters must not contain literal whitespaces.  Whitespaces  in
       macros used in these parameters are allowed.

              $(and macroterm ...)
                     expands each macroterm in turn until there are no more or
                     one of them returns an empty string.  If  all  expand  to
                     non-empty   strings  the  macro  returs  the  string  "t"
                     otherwise it returns an empty string.

              $(assign expression)
                     Causes expression to be  parsed  as  a  macro  assignment
                     expression  and results in the specified assignment being
                     made.  An error  is  issued  if  the  assignment  is  not
                     syntatically   correct.   expression  may  contain  white
                     space.  This is in  effect  a  dynamic  macro  assignment
                     facility  and  may  appear  anywhere  any other macro may
                     appear.  The result of  the  expanding  a  dynamic  macro
                     assignment  expression  is the name of the macro that was
                     assigned and $(NULL) if the expression  is  not  a  valid
                     macro assignment expression.  Some examples are:

                     $(assign foo := fred)
                     $(assign $(ind_macro_name) +:= $(morejunk))

              $(echo list)
                     Echo’s the value of list.  list is not expanded.

              $(eq,text_a,text_b true false)
                     expands text_a and text_b and compares their results.  If
                     equal it returns the result of the expansion of the  true
                     term,  otherwise  it  returns  the expansion of the false
                     term.

              $(!eq,text_a,text_b true false)
                     Behaves identically to the previous macro except that the
                     true  string  is  chosen  if  the  expansions  of the two
                     strings are not equal

              $(foreach,var,list data)
                     Implements iterative macro expansion over data using  var
                     as  the iterator taking on values from list. var and list
                     are expanded and  the  result  is  the  concatenation  of
                     expanding  data  with  var  being  set to each whitespace
                     separated token from list.  For example:

                             list = a b c
                             all :; echo [$(foreach,i,$(list) [$i])]

                     will output

                             [[a] [b] [c]]

                     The iterator variable is defined as a local  variable  to
                     this   foreach   instance.    The   following  expression
                     illustrates this:

                             $(foreach,i,$(foreach,i,$(sort c a b) root/$i) [$i/f.h])

                     when evaluated the result is:

                             [root/a/f.h] [root/b/f.h] [root/c/f.h]

                     The  specification  of  list  must  be  a   valid   macro
                     expression, such as:

                             $($(assign list=a b c))
                             $(sort d a b c)
                             $(echo a b c)

                     and  cannot  just  be  the  list  itself.   That  is, the
                     following foreach expression:

                             $(foreach,i,a b c [$i])

                     yields:

                             "b c [a]"

                     when evaluated.

              $(nil expression)
                     Always returns the value of $(NULL)  regardless  of  what
                     expression  is.   This  function  macro  can  be  used to
                     discard results of expanding macro expressions.

              $(normpath list)
                     Will return the normalized path names of all  white-space
                     separated tokens in list. Quotes can be used to normalize
                     path names that contain white-space characters. On cygwin
                     the  result  honors  the setting of .WINPATH to determine
                     the output format of the returned path names.

              $(normpath,para list)
                     Same as above except that the expanded value of  para  is
                     used to override the .WINPATH setting.

              $(not macroterm)
                     expands macroterm and returs the string "t" if the result
                     of the expansion  is  the  empty  string;  otherwise,  it
                     returns the empty string.

              $(null,text true false)
                     expands  the value of text.  If it is NULL then the macro
                     returns the value  of  the  expansion  of  true  and  the
                     expansion  of false otherwise.  The terms true, and false
                     must be strings containing no white-space.

              $(!null,text true false)
                     Behaves identically to the previous macro except that the
                     true  string  is  chosen  if the expansion of text is not
                     NULL.

              $(or macroterm ...)
                     expands each macroterm  in  turn  and  returs  the  empty
                     string   if  each  term  expands  to  the  empty  string;
                     otherwise, it returs the string "t".

              $(shell command)
                     is a shell escape macro. It runs command as  if  it  were
                     part  of  a  recipe  and  returns,  separated by a single
                     space, all the non-white space terms written to stdout by
                     the command.  For example:

                             $(shell ls *.c)

                     will  return  "a.c b.c c.c d.c" if the files exist in the
                     current directory.  The recipe modification flags  [+@%-]
                     are honored if they appear as the first characters in the
                     command.  For example:

                             $(shell +ls *.c)

                     will run the command using the current shell.

                     Note that if the macro is part of a  recipe  it  will  be
                     evaluated  after  all  previous  recipe  lines  have been
                     executed. For obvious reasons it will be evaluated before
                     the current recipe line or group recipe is executed.

              $(shell,expand command)
                     Is  an  extension  to the $(shell command) function macro
                     that expands the result of running command.

              $(sort list)
                     Will take all white-space separated tokens  in  list  and
                     will return their sorted equivalent list.

              $(strip data)
                     Will  replace  all  strings  of  white-space in data by a
                     single space.

              $(subst,pat,replacement data)
                     Will  search  for  pat  in  data  and  will  replace  any
                     occurrence  of  pat  with  the  replacement  string.  The
                     expansion

                     $(subst,.o,.c $(OBJECTS))

              is equivalent to:

                     $(OBJECTS:s/.o/.c/)

              $(uniq list)
                     Will take all white-space separated tokens  in  list  and
                     will  return  their  sorted equivalent list containing no
                     duplicates.

       For historic reasons dmake treats the following case slightly special:

              $(name something)

       If it encounters a macro with a whitespace after name and name  is  not
       literally  one  of  the above mentioned function macro identifiers then
       dmake will return the  recursively  expanded  value  of  $(name).   The
       remaining  something  part  will  be  expanded  but  the result will be
       discarded. The use of this special feature is deprecated and should not
       be used.

CONDITIONAL MACROS

       dmake  supports  conditional  macros.   These  allow  the definition of
       target specific macro values.  You can now say the following:

              target ?= MacroName MacroOp Value

       This creates a definition for MacroName whose value is Value only  when
       target  is  being  made.   You  may  use a conditional macro assignment
       anywhere that a regular macro assignment may appear, including  as  the
       value of a $(assign ...) macro.

       The  new  definition is associated with the most recent cell definition
       for target.  If no prior definition exists then one  is  created.   The
       implications of this are immediately evident in the following example:

              foo := hello

              all : cond;@echo "all done, foo=[$(foo)] bar=[$(bar)]"

              cond ?= bar := global decl

              cond .SETDIR=unix::;@echo $(foo) $(bar)
              cond ?= foo := hi

              cond .SETDIR=msdos::;@echo $(foo) $(bar)
                   cond ?= foo := hihi

       The  first  conditional  assignment creates a binding for ’bar’ that is
       activated  when  ’cond’  is  made.   The  bindings  following  the   ::
       definitions  are activated when their respective recipe rules are used.
       Thus the first binding serves to provide a global value for ’bar’ while
       any  of  the  cond  ::  rules are processed, and the local bindings for
       ’foo’ come into effect when their associated :: rule is processed.

       Conditionals for targets of .UPDATEALL are  all  activated  before  the
       target  group  is made.  Assignments are processed in order.  Note that
       the value of a conditional macro assignment is NOT AVAILABLE until  the
       associated target is made, thus the construct

              mytarget ?= bar := hello
              mytarget ?= foo := $(bar)

       results in $(foo) expanding to "", if you want the result to be "hello"
       you must use:

              mytarget ?= bar := hello
              mytarget ?= foo  = $(bar)

       Once a target is made any associated conditional macros are deactivated
       and their values are no longer available.  Activation occurrs after all
       inference, and .SETDIR directives have been processed and after  $@  is
       assigned,  but  before  prerequisites are processed; thereby making the
       values of conditional macro definitions available  during  construction
       of prerequisites.

       If  a  %-meta rule target has associated conditional macro assignments,
       and the rule is chosen by the inference algorithm then the  conditional
       macro assignments are inferred together with the associated recipe.

DYNAMIC PREREQUISITES

       dmake  looks  for  prerequisites  whose  names contain macro expansions
       during target processing.  Any such prerequisites are expanded and  the
       result  of  the  expansion  is  used  as  the prerequisite name.  As an
       example the line:

       fred : $$@.c

       causes the $$@ to be  expanded  when  dmake  is  making  fred,  and  it
       resolves  to the target fred.  This enables dynamic prerequisites to be
       generated.  The value of @ may be modified by any of  the  valid  macro
       modifiers.  So you can say for example:

       fred.out : $$(@:b).c

       where  the $$(@:b) expands to fred.  Note the use of $$ instead of $ to
       indicate the dynamic expansion, this is due to the fact that  the  rule
       line  is  expanded  when  it is initially parsed, and $$ then returns $
       which later triggers the dynamic prerequisite expansion.  Dynamic macro
       expansion  is  performed  in  all  user  defined rules, and the special
       targets .SOURCE*, and .INCLUDEDIRS.

       NOTE: The use of a $ as part  of  a  prerequisite  or  target  name  is
       strongly  discouraged as the runtime macros (like $@) are expanded when
       used in a recipe  line  so  that  the  $  is  interpreted  as  a  macro
       identifier  and  not  as a character of the filename leading to invalid
       runtime macros.  In addition to this no filename normalization is  done
       for  prerequisites and targets that contain $ characters.  Nevertheless
       it is possible to use $ in prerequisites by using $$$$ but this is  not
       recommended and can lead to surprising results.

       If  dynamic  macro  expansion results in multiple white space separated
       tokens then these are inserted into the prerequisite  list  inplace  of
       the  dynamic  prerequisite.   Due  to  the  recursive  nature  of macro
       expansion the prerequisite list is fully expanded even if  the  dynamic
       prerequisite contained other runtime macros.

BINDING TARGETS

       This operation takes a target name and binds it to an existing file, if
       possible.  dmake makes a distinction between the internal  target  name
       of a target and its associated external file name.  Thus it is possible
       for a target’s internal name and its external file name to differ.   To
       perform  the  binding, the following set of rules is used.  Assume that
       we are trying to bind a target whose name is of the form X.suff,  where
       .suff  is  the  suffix  and  X is the stem portion (ie. that part which
       contains the directory and the basename).  dmake takes this target name
       and  performs a series of search operations that try to find a suitably
       named file in the external file system.  The search operation  is  user
       controlled via the settings of the various .SOURCE targets.

              1.     If  target has the .SYMBOL attribute set then look for it
                     in the library.  If found, replace the target  name  with
                     the library member name and continue with step 2.  If the
                     name is not found then return.

              2.     Extract the suffix portion (that following  the  ‘.’)  of
                     the  target name.  If the suffix is not null, look up the
                     special target .SOURCE.<suff> (<suff> is the suffix).  If
                     the  special  target  exists  then  search each directory
                     given in the .SOURCE.<suff>  prerequisite  list  for  the
                     target.   If  the target’s suffix was null (ie. .suff was
                     empty) then perform the above search but use the  special
                     target  .SOURCE.NULL instead.  If at any point a match is
                     found then terminate the search.  If a directory  in  the
                     prerequisite  list is the special name ‘.NULL ’ perform a
                     search for the full target name  without  prepending  any
                     directory portion (ie. prepend the NULL directory).

              3.     The search in step 2. failed.  Repeat the same search but
                     this time use the special  target  .SOURCE.   (a  default
                     target  of  ’.SOURCE  :  .NULL’  is  defined  by dmake at
                     startup, and is user redefinable)

              4.     The search in step 3. failed.   If  the  target  has  the
                     library  member  attribute  (.LIBMEMBER)  set then try to
                     find the target in the library  which  was  passed  along
                     with  the  .LIBMEMBER attribute (see the MAKING LIBRARIES
                     section).  The bound file name assigned to a target which
                     is  successfully  located  in  a library is the same name
                     that would be assigned had the search failed (see 5.).

              5.     The search failed.  Either the target was  not  found  in
                     any  of  the  search directories or no applicable .SOURCE
                     special targets exist.   If  applicable  .SOURCE  special
                     targets  exist,  but the target was not found, then dmake
                     assigns the first name searched as the bound  file  name.
                     If  no applicable .SOURCE special targets exist, then the
                     full original target name becomes the bound file name.

       There is potential here for a lot of search operations.  The  trick  is
       to  define  .SOURCE.x special targets with short search lists and leave
       .SOURCE as short as possible.  The search algorithm has  the  following
       useful  side  effect.   When  a  target  having the .LIBMEMBER (library
       member) attribute is searched for, it  is  first  searched  for  as  an
       ordinary file.  When a number of library members require updating it is
       desirable to compile all of them first and to update the library at the
       end  in a single operation.  If one of the members does not compile and
       dmake stops, then the user may fix the error  and  make  again.   dmake
       will not remake any of the targets whose object files have already been
       generated as long  as  none  of  their  prerequisite  files  have  been
       modified as a result of the fix.

       When  dmake  constructs  target  (and  prerequisite) pathnames they are
       normalized  to the shortest (or most natural, see below for the  cygwin
       case) representation.  Substrings like ’./’ or of the form ’baz/..’ are
       removed and multiple slashes are collapsed to one unless  they  are  at
       the beginning of the pathname. Leading slashes are normalized according
       to POSIX rules, i.e. more than two leading slashes are reduced  to  one
       slash  and  a  leading ’//’ is kept as it might have a special meaning.
       For example "./foo", "bar/../foo" and foo are recognized  as  the  same
       file.   This  may  result  in  somewhat  unexpected values of the macro
       expansion of runtime macros like $@, but is infact the corect result.

       NOTE:  A cygwin dmake executable will accept DOS  like  pathnames  with
       drive  letters  and  cygwin POSIX pathnames and normalize them into its
       natural  POSIX  representation.   This  might  result  in   even   more
       surprising values of runtime macros.

       When defining .SOURCE and .SOURCE.x targets the construct

              .SOURCE :
              .SOURCE : fred gery

       is equivalent to

              .SOURCE :- fred gery

       dmake  correctly  handles  the UNIX Make variable VPATH.  By definition
       VPATH contains a list of  ’:’  separated  directories  to  search  when
       looking for a target.  dmake maps VPATH to the following special rule:

              .SOURCE :^ $(VPATH:s/:/ /)

       Which  takes  the  value  of  VPATH and sets .SOURCE to the same set of
       directories as specified in VPATH.

PERCENT(%) RULES AND MAKING INFERENCES

       When dmake makes a target, the target’s set of prerequisites  (if  any)
       must  exist  and  the  target must have a recipe which dmake can use to
       make it.  If the makefile does not specify an explicit recipe  for  the
       target  then dmake uses special rules to try to infer a recipe which it
       can use to make the target.  Previous versions  of  Make  perform  this
       task   by  using  rules  that  are  defined  by  targets  of  the  form
       .<suffix>.<suffix> (this is still supported, see "AUGMAKE META  RULES")
       or  by using the not supported by dmake .SUFFIXES list of suffixes (see
       "SPECIAL  TARGETS"  for  more  details  about  .SUFFIXES).   The  exact
       workings  of  this mechanism were sometimes difficult to understand and
       often limiting  in  their  usefulness.   Instead,  dmake  supports  the
       concept  of  %-meta  rules.   The  syntax  and semantics of these rules
       differ from standard rule lines as follows:

              <%-targets> [<attributes>] <ruleop> [<%-prereqs>] [;<recipe>]

       where %-targets are one or more targets containing exactly a single ‘%’
       sign,  attributes  is  a list (possibly empty) of attributes, ruleop is
       the standard set of rule operators, %-prereqs , if present, is  a  list
       of  prerequisites  containing  zero  or  more ‘%’ signs, and recipe, if
       present, is the first line of the recipe.

       If more than one %-target is present  this  line  is  equivalent  to  a
       repetition   of   the   whole   [<attributes>]  <ruleop>  [<%-prereqs>]
       [;<recipe>] sequence for each %-target, i.e. it is possible to  specify
       the  same  rule  for multiple %-targets. Because of this following only
       speaks  about  <%-target>  as  %-targets  are  divided  into   multiple
       definitions with a single %-target.

       NOTE:   As  multiple %-targets didn’t work reliably with dmake versions
       prior to 4.5 unless the rule operator ‘|:’ was used we currently  issue
       a warning stating that it now works.

       The  %-target  defines a pattern against which a target whose recipe is
       being inferred gets matched.  The pattern match goes as  follows:   all
       chars  are  matched  exactly from left to right up to but not including
       the % sign in the pattern, % then matches the longest string  from  the
       actual  target  name not ending in the suffix given after the % sign in
       the pattern.  Consider the following examples:

              %.c       matches fred.c but not joe.c.Z
              dir/%.c   matches dir/fred.c but not dd/fred.c
              fred/%    matches fred/joe.c but not f/joe.c
              %         matches anything

       In each case the part of the target name that matched  the  %  sign  is
       retained and is substituted for any % signs in the prerequisite list of
       the %-meta rule when the rule is selected during  inference  and  dmake
       constructs the new dependency.

       Please  note,  that  only  the first, non-indirect, prerequisite of the
       list is used for the inference mechanism. If more than one non-indirect
       prerequisite  is  given  a warning is issued and all but the first non-
       indirect prerequisites are ignored. See  below  for  a  description  of
       indirect prerequisites.

       As an example the following %-meta rules describe the following:

              %.c : %.y ; recipe...

       describes  how  to  make  any file ending in .c if a corresponding file
       ending in .y can be found.

              foo%.o : fee%.k ; recipe...

       is used to describe how to make fooxxxx.o from feexxxx.k.

              %.a :; recipe...

       describes how to make a file whose suffix is .a without  inferring  any
       prerequisites.

              %.c : %.y ’yaccsrc/%.y’ ; recipe...

       matches  the  corresponding  .y  file  as prerequisite and additionally
       another .y file in the yaccsrc subdirectory as  indirect  prerequisite.
       Another interesting example is:

              % : RCS/%,v ; co $<

       which  describes  how  to  take  any target and check it out of the RCS
       directory if the corresponding file exists in the RCS  directory.   The
       equivalent SCCS rule would be:

              % : s.% ; get $<

       The  previous RCS example defines an infinite rule, because it says how
       to make anything from RCS/%,v, and anything also includes RCS/fred.c,v.
       To  limit the size of the graph that results from such rules dmake uses
       the macro variable PREP (stands for  %  repetition).   By  default  the
       value of this variable is 0, which says that no repetitions of a %-rule
       are to be generated.  If it is set to something greater  than  0,  then
       that  many  repetitions  of any infinite %-rule are allowed.  If in the
       above example PREP  was  set  to  1,  then  dmake  would  generate  the
       dependency graph:

              % --> RCS/%,v --> RCS/RCS/%,v,v

       Where  each  link  is assigned the same recipe as the first link.  PREP
       should be used only in special cases, since it may result  in  a  large
       increase in the number of possible prerequisites tested.  dmake further
       assumes that any  target  that  has  no  suffix  can  be  made  from  a
       prerequisite that has at least one suffix.

       dmake  supports  dynamic  prerequisite  generation for prerequisites of
       %-meta rules.  This is best illustrated by an example.   The  RCS  rule
       shown  above can infer how to check out a file from a corresponding RCS
       file only if the target  is  a  simple  file  name  with  no  directory
       information.    That   is,  the  above  rule  can  infer  how  to  find
       RCS/fred.c,v from the target fred.c,  but  cannot  infer  how  to  find
       srcdir/RCS/fred.c,v  from  srcdir/fred.c  because  the  above rule will
       cause dmake to look  for  RCS/srcdir/fred.c,v;  which  does  not  exist
       (assume that srcdir has its own RCS directory as is the common case).

       A  more  versatile  formulation  of the above RCS check out rule is the
       following:

              % :  $$(@:d)RCS/$$(@:f),v : co $@

       This rule uses the dynamic macro $@ to specify the prerequisite to  try
       to  infer.   During  inference  of this rule the macro $@ is set to the
       value of the target of the %-meta rule and the appropriate prerequisite
       is generated by extracting the directory portion of the target name (if
       any), appending the string RCS/ to it, and appending  the  target  file
       name with a trailing ,v attached to the previous result.

       dmake  can  also  infer indirect prerequisites.  An inferred target can
       have a list of prerequisites added that will not show up in  the  value
       of  $<  but  will  show  up  in  the  value  of  $?  and  $&.  Indirect
       prerequisites are  specified  in  an  inference  rule  by  quoting  the
       prerequisite  with single quotes.  For example, if you had the explicit
       dependency:

              fred.o : fred.c ; rule to make fred.o
              fred.o : local.h

       then this can be inferred for fred.o from the following inference rule:

              %.o : %.c ’local.h’ ; makes a .o from a .c

       You  may  infer indirect prerequisites that are a function of the value
       of ’%’ in the current rule.  The meta-rule:

              %.o : %.c ’$(INC)/%.h’ ; rule to make a .o from a .c

       infers an indirect prerequisite found in the INC directory  whose  name
       is  the  same  as  the  expansion  of $(INC), and the prerequisite name
       depends on the base name of the current target.  The  set  of  indirect
       prerequisites  is attached to the meta rule in which they are specified
       and are inferred only if the rule is used  to  infer  a  recipe  for  a
       target.   They  do  not  play  an  active role in driving the inference
       algorithm.  The construct:

              %.o :| %.c %.f ’local.h’; recipe

       is equivalent to:

              %.o : %.c ’local.h’ ; recipe
              %.o : %.f ’local.h’ ; recipe

       If any of the attributes .EPILOG, .IGNORE, .LIBRARY, .NOSTATE,  .PHONY,
       .PRECIOUS, .PROLOG, .SETDIR, .SILENT, .SWAP, .USESHELL and .WINPATH are
       given for a %-rule then when that rule is bound  to  a  target  as  the
       result  of an inference, the target’s set of attributes is augmented by
       the attributes from the above set  that  are  specified  in  the  bound
       %-rule.   Other attributes specified for %-meta rules are not inherited
       by the target.  The .SETDIR attribute is treated in a special way.   If
       the  target  already  had a .SETDIR attribute set then dmake changes to
       that directory prior to performing the inference.  During inference any
       .SETDIR  attributes  for  the  inferred  prerequisite are honored.  The
       directories must exist for a %-meta rule to be selected as  a  possible
       inference  path.   If  the directories do not exist no error message is
       issued, instead the  corresponding  path  in  the  inference  graph  is
       rejected.

       dmake  bases  all  of its inferences on the inference graph constructed
       from the %-rules defined in  the  makefile.   It  knows  exactly  which
       targets  can  be made from which prerequisites by making queries on the
       inference graph.

       For a %-meta rule to be inferred as the rule whose recipe will be  used
       to  make  a  target, the target’s name must match the %-target pattern,
       and any inferred %-prerequisite must already exist or have an  explicit
       recipe  so  that  the  prerequisite  can  be  made.  Without transitive
       closure on the inference graph the above rule describes precisely  when
       an  inference  match  terminates  the search.  If transitive closure is
       enabled (the usual case), and a prerequisite does not exist  or  cannot
       be  made, then dmake invokes the inference algorithm recursively on the
       prerequisite to see if there  is  some  way  the  prerequisite  can  be
       manufactured.   For,  if  the prerequisite can be made then the current
       target can also be made using the current %-meta rule.  This means that
       there  is  no longer a need to give a rule for making a .o from a .y if
       you have already given a rule for making a .o from a .c and a .c from a
       .y.   In  such cases dmake can infer how to make the .o from the .y via
       the intermediary .c and will  remove  the  .c  when  the  .o  is  made.
       Transitive  closure  can  be  disabled  by  giving the -T switch on the
       command line.

       A word of caution.  dmake bases its transitive closure  on  the  %-meta
       rule  targets.   When  it  performs transitive closure it infers how to
       make a target from a prerequisite by performing a pattern match  as  if
       the potential prerequisite were a new target.  The set of rules:

              %.o : %.c ; rule for making .o from .c
              %.c : %.y ; rule for making .c from .y
              % : RCS/%,v ; check out of RCS file

       will,  by  performing  transitive  closure, allow dmake to infer how to
       make a .o from a .y using a  .c  as  an  intermediate  temporary  file.
       Additionally  it  will  be  able  to infer how to make a .y from an RCS
       file, as long as that RCS file is in the RCS directory and has  a  name
       which   ends  in  .y,v.   The  transitivity  computation  is  performed
       dynamically for each target that does not  have  a  recipe.   This  has
       potential to be costly if the %-meta rules are not carefully specified.
       The .NOINFER attribute is used to mark a %-meta node as being  a  final
       target  during inference.  Any node with this attribute set will not be
       used for subsequent inferences.  As an  example  the  node  RCS/%,v  is
       marked  as  a  final  node  since we know that if the RCS file does not
       exist there likely is no other way  to  make  it.   Thus  the  standard
       startup makefile contains an entry similar to:
              .NOINFER : RCS/%,v
       Thereby indicating that the RCS file is the end of the inference chain.
       Whenever the inference algorithm determines that a target can  be  made
       from  more  than  one prerequisite and the inference chains for the two
       methods are the same length the  algorithm  reports  an  ambiguity  and
       prints the ambiguous inference chains.

       dmake  tries  to  remove  intermediate  files resulting from transitive
       closure if the file is not marked as being PRECIOUS, or the -u flag was
       not given on the command line, and if the inferred intermediate did not
       previously exist.  Intermediate targets that  existed  prior  to  being
       made  are  never  removed.  This is in keeping with the philosophy that
       dmake should never remove things from the file system that it  did  not
       add.   If  the  special target .REMOVE is defined and has a recipe then
       dmake constructs a list of the intermediate files  to  be  removed  and
       makes  them  prerequisites  of  .REMOVE.  It then makes .REMOVE thereby
       removing the prerequisites if the recipe of .REMOVE says to.  Typically
       .REMOVE is defined in the startup file as:

              .REMOVE :; $(RM) $<

AUGMAKE META RULES

       As  a  subclass  of  the meta targets that is actually mapped to %-meta
       rules dmake understands several SYSV AUGMAKE  targets  transformations.
       This  .<suffix>  special target construct transforms into the following
       %-meta rules:

              .suff :; recipe

       gets mapped into:

              % : %.suff; recipe

       dmake also supports the old format special target .<suffix>.<suffix> by
       identifying  any rules of this form and mapping them to the appropriate
       %-rule.  So for example if an old makefile contains the construct:

              .c.o :; cc -c $< -o $@

       dmake maps this into the following %-rule:

              %.o : %.c; cc -c $< -o $@

       The following SYSV  AUGMAKE  special  targets  transformation  must  be
       enabled  by providing the -A flag on the command line or by setting the
       value of AUGMAKE to non-NULL.  The construct

              .c~.o :; recipe

       gets mapped into:

              %.o : s.%.c ; recipe

       In general, a special target of the form .<str>~  is  replaced  by  the
       %-rule  construct  s.%.<str>,  thereby providing support for the syntax
       used by SYSV AUGMAKE for providing SCCS support.  When  enabled,  these
       mappings   allow   processing   of   existing  SYSV  makefiles  without
       modifications.

MAKING TARGETS

       In order to update a target dmake must execute a recipe.  When a recipe
       needs  to  be  executed  it is first expanded so that any macros in the
       recipe text are expanded, and it is then either  executed  directly  or
       passed  to  a shell.  dmake supports two types of recipes.  The regular
       recipes and group recipes.

       When a regular recipe is invoked dmake executes each line of the recipe
       separately  using  a  new copy of a shell if a shell is required.  Thus
       effects of commands do not generally persist across recipe lines  (e.g.
       cd  requests  in  a  recipe  line  do not carry over to the next recipe
       line).  This is true even in environments such as  MSDOS,  where  dmake
       internally  sets the current working director to match the directory it
       was in before the command was executed.

       The decision on whether a shell is required to  execute  a  command  is
       based  on  the value of the macro SHELLMETAS or on the specification of
       ’+’ or .USESHELL for the current recipe or target respectively.  If any
       character  in  the  value of SHELLMETAS is found in the expanded recipe
       text-line or the use of a shell is  requested  explicitly  via  ’+’  or
       .USESHELL  then  the  command  is executed using a shell, otherwise the
       command is executed directly.  The shell that is used for execution  is
       given  by  the  value of the macro SHELL.  The flags that are passed to
       the shell are given by the value of SHELLFLAGS.  Thus dmake  constructs
       the command line:

       $(SHELL) $(SHELLFLAGS) $(expanded_recipe_command)

       If  the  $(SHELLCMDQUOTE) macro is set its value is inserted before and
       after the $(expanded_recipe_command) string.

       Normally dmake writes the command line that it is about  to  invoke  to
       standard output.  If the .SILENT attribute is set for the target or for
       the recipe line (via @), then the recipe line is not echoed.

       Group recipe processing is similar to that of regular  recipes,  except
       that  a shell is always invoked.  The shell that is invoked is given by
       the value of the macro GROUPSHELL, and its flags  are  taken  from  the
       value  of  the macro GROUPFLAGS.  If a target has the .PROLOG attribute
       set then dmake prepends to the shell script the recipe associated  with
       the special target .GROUPPROLOG, and if the attribute .EPILOG is set as
       well, then the recipe associated with the special  target  .GROUPEPILOG
       is  appended  to  the script file.  This facility can be used to always
       prepend a common header and common trailer  to  group  recipes.   Group
       recipes  are  echoed to standard output just like standard recipes, but
       are enclosed by lines beginning with [ and ].

       The recipe flags [+,-,%,@] are recognized at the start of a recipe line
       even if they appear in a macro.  For example:

              SH = +
              all:
              $(SH)echo hi

       is completely equivalent to writing

              SH = +
              all:
              +echo hi

       The  last  step  performed by dmake prior to running a recipe is to set
       the macro CMNDNAME to the name of the command to execute (determined by
       finding  the  first  white-space ending token in the command line).  It
       then sets the macro CMNDARGS to be the remainder of  the  line.   dmake
       then expands the macro COMMAND which by default is set to

              COMMAND = $(CMNDNAME) $(CMNDARGS)

       The  result  of  this  final  expansion  is  the  command  that will be
       executed.  The reason for this expansion is to allow  for  a  different
       interface to the argument passing facilities (esp. under DOS) than that
       provided by dmake.  You can for example define COMMAND to be

              COMMAND = $(CMNDNAME) @$(mktmp $(CMNDARGS))

       which dumps the arguments into a temporary file and runs the command

              $(CMNDNAME) @/tmp/ASAD23043

       which has a much shorter argument list.  It is now up to the command to
       use the supplied argument as the source for all other arguments.  As an
       optimization, if COMMAND is not defined  dmake  does  not  perform  the
       above  expansion.   On  systems, such as UNIX, that handle long command
       lines this provides a slight saving in processing the makefiles.

MAKING LIBRARIES

       Libraries are easy to maintain  using  dmake.   A  library  is  a  file
       containing  a  collection  of object files.  Thus to make a library you
       simply specify it as a target  with  the  .LIBRARY  attribute  set  and
       specify  its  list  of  prerequisites.  The prerequisites should be the
       object members that are to go into the library.  When dmake  makes  the
       library   target  it  uses  the  .LIBRARY  attribute  to  pass  to  the
       prerequisites the .LIBMEMBER attribute and the  name  of  the  library.
       This  enables  the file binding mechanism to look for the member in the
       library if an appropriate object  file  cannot  be  found.   dmake  now
       supports  Elf libraries on systems that support Elf and hence supports,
       on those systems,  long  member  file  names.   A  small  example  best
       illustrates this.

              mylib.a .LIBRARY : mem1.o mem2.o mem3.o
              rules for making library...
              # remember to remove .o’s when lib is made

              # equivalent to:  ’%.o : %.c ; ...’
              .c.o :; rules for making .o from .c say

       dmake  will  use  the  .c.o  rule  for  making  the  library members if
       appropriate .c files can be found using the search rules.  NOTE:   this
       is  not  specific  in any way to C programs, they are simply used as an
       example.

       dmake tries to handle the old library construct format  in  a  sensible
       way.   The  construct lib(member.o) is separated and the lib portion is
       declared as a library target.  The  new  target  is  defined  with  the
       .LIBRARY  attribute  set  and  the member.o portion of the construct is
       declared as a  prerequisite  of  the  lib  target.   If  the  construct
       lib(member.o)  appears  as  a prerequisite of a target in the makefile,
       that target has the new name of the lib assigned as  its  prerequisite.
       Thus the following example:

              a.out : ml.a(a.o) ml.a(b.o); $(CC) -o $@  $<

              .c.o :; $(CC) -c $(CFLAGS) -o $@  $<
              %.a:
                     ar rv $@ $?
                     ranlib $@
                     rm -rf $?

       constructs the following dependency graph.

              a.out : ml.a; $(CC) -o $@  $<
              ml.a .LIBRARY : a.o b.o

              %.o : %.c ; $(CC) -c $(CFLAGS) -o $@  $<
              %.a :
                     ar rv $@ $?
                     ranlib $@
                     rm -rf $?

       and making a.out then works as expected.

       The  same thing happens for any target of the form lib((entry)).  These
       targets have an additional feature in that the  entry  target  has  the
       .SYMBOL attribute set automatically.

       NOTE:  If the notion of entry points is supported by the archive and by
       dmake (currently not the case) then dmake will search the  archive  for
       the entry point and return not only the modification time of the member
       which defines the entry but also the name of  the  member  file.   This
       name  will  then  replace  entry and will be used for making the member
       file.  Once bound to an archive member the .SYMBOL attribute is removed
       from the target.  This feature is presently disabled as there is little
       standardization among archive formats,  and  we  have  yet  to  find  a
       makefile  utilizing  this  feature (possibly due to the fact that it is
       unimplemented in most versions of UNIX Make).

       Finally, when dmake looks for a library member it must first locate the
       library  file.  It does so by first looking for the library relative to
       the current directory and if it is not found it then looks relative  to
       the current value of $(TMD).  This allows commonly used libraries to be
       kept near the root of a source tree and to be easily found by dmake.

KEEP STATE

       dmake supports the keeping of state information  for  targets  that  it
       makes whenever the macro .KEEP_STATE is assigned a value.  The value of
       the macro should be the name of a state  file  that  will  contain  the
       state  information.   If state keeping is enabled then each target that
       does not poses the .NOSTATE attribute will have a record  written  into
       the state file indicating the target’s name, the current directory, the
       command used to update the target, and which, if any, :: rule is  being
       used.   When you make this target again if any of this information does
       not match the previous settings and the target is not out dated it will
       still  be  re-made.  The assumption is that one of the conditions above
       has changed and that we wish to remake the target.  For example,  state
       keeping  is  used in the maintenance of dmake to test compile different
       versions  of  the  source  using  different  compilers.   Changing  the
       compiler  causes  the  compilation  flags  to be modified and hence all
       sources to be recompiled.

       The state file is an ascii file and is portable, however it is  not  in
       human  readable  form  as  the entries represent hash keys of the above
       information.

       The Sun Microsystem’s Make construct

              .KEEP_STATE :

       is recognized and  is  mapped  to  .KEEP_STATE:=_state.mk.   The  dmake
       version  of  state keeping does not include scanning C source files for
       dependencies like Sun Make.  This is specific to C programs and it  was
       felt that it does not belong in make.  dmake instead provides the tool,
       cdepend, to scan C source files and to produce  depedency  information.
       Users  are  free  to  modify cdepend to produce other dependency files.
       (NOTE: cdepend does not come with the distribution at  this  time,  but
       will be available in a patch in the near future)

MULTI PROCESSING

       If  the  architecture  supports  it  then  dmake is capable of making a
       target’s prerequisites  in  parallel.   dmake  will  make  as  much  in
       parallel  as  it  can  and  use  a  number of child processes up to the
       maximum specified by MAXPROCESS or by the  value  supplied  to  the  -P
       command  line flag.  A parallel make is enabled by setting the value of
       MAXPROCESS (either directly or via -P option) to a value which is >  1.
       dmake guarantees that all dependencies as specified in the makefile are
       honored.  A target will not be made until all of its prerequisites have
       been  made.   Note that when you specify -P 4 then four child processes
       are run concurrently but dmake actually displays the fifth  command  it
       will  run  immediately upon a child process becomming free.  This is an
       artifact of the method used to traverse the dependency graph and cannot
       be  removed.   If a parallel make is being performed then the following
       restrictions on parallelism are enforced.

              1.     Individual  recipe  lines  in  a  non-group  recipe   are
                     performed  sequentially  in  the  order in which they are
                     specified within the makefile and in  parallel  with  the
                     recipes of other targets.

              2.     If  a target contains multiple recipe definitions (cf. ::
                     rules) then these are performed sequentially in the order
                     in  which  the :: rules are specified within the makefile
                     and in parallel with the recipes of other targets.

              3.     If a target rule contains  the  ‘!’  modifier,  then  the
                     recipe is performed sequentially for the list of outdated
                     prerequisites and in parallel with the recipes  of  other
                     targets.

              4.     If a target has the .SEQUENTIAL attribute set then all of
                     its prerequisites are made sequentially relative  to  one
                     another  (as if MAXPROCESS=1), but in parallel with other
                     targets in the makefile.

       Note:  If you specify a parallel make then the order of  target  update
       and  the  order  in  which  the associated recipes are invoked will not
       correspond to that displayed by the -n flag.

CONDITIONALS

       dmake supports a makefile construct called a  conditional.   It  allows
       the  user  to  conditionally select portions of makefile text for input
       processing and to discard other  portions.   This  becomes  useful  for
       writing  makefiles  that  are  intended  to  function for more than one
       target host and environment.  The conditional expression  is  specified
       as follows:

              .IF  expression
                 ... if text ...
              .ELIF  expression
                 ... if text ...
              .ELSE
                 ... else text ...
              .END

       The  .ELSE and .ELIF portions are optional, and the conditionals may be
       nested (ie.  the text may contain another  conditional).   .IF,  .ELSE,
       and  .END may appear anywhere in the makefile, but a single conditional
       expression may not span multiple makefiles.

       expression can be one of the following forms:

       String evaluation
       <text> | <text> == <text> | <text> != <text>

       Numeric evaluation
       <text> <= <text> | <text> >= <text>

       Boolean evaluation
       ( <text> ) | <text> || <text> | <text> && <text>

       where text is either text or a macro expression.  In any  case,  before
       the  comparison is made, the expression is expanded.  The text portions
       are then selected and compared.  In the case of the numeric comparisons
       enclosing  quotes  are  removed after expanding the expressions and the
       leading numerical parts are converted  to  an  integer  number.  If  no
       numerical part is found this results to 0 (zero). The string "12ab" for
       example evaluates to the number 12.  Expressions can be nested with  ()
       and  the use of || or &&.  White space at the start and end of the text
       portion is discarded before the comparison.  This means  that  a  macro
       that  evaluates  to  nothing but white space is considered a NULL value
       for the purpose of the comparison.  In the first  case  the  expression
       evaluates  TRUE  if  the text is not NULL otherwise it evaluates FALSE.
       The remaining two cases both evaluate the expression on the basis of  a
       string comparison.  If a macro expression needs to be equated to a NULL
       string then compare it to the value of the macro $(NULL).  You can  use
       the $(shell ...) macro to construct more complex test expressions.

EXAMPLES

              # A simple example showing how to use make
              #
              prgm : a.o b.o
                   cc a.o b.o -o prgm
              a.o : a.c g.h
                   cc a.c -o $@
              b.o : b.c g.h
                   cc b.c -o $@

       In the previous example prgm is remade only if a.o and/or b.o is out of
       date with respect to prgm.   These  dependencies  can  be  stated  more
       concisely  by using the inference rules defined in the standard startup
       file.  The default rule for making .o’s from .c’s looks something  like
       this:

       %.o : %.c; cc -c $(CFLAGS) -o $@ $<

       Since there exists a rule (defined in the startup file) for making .o’s
       from .c’s dmake will use that rule for manufacturing a .o from a .c and
       we can specify our dependencies more concisely.

              prgm : a.o b.o
                   cc -o prgm $<
              a.o b.o : g.h

       A  more  general  way  to  say the above using the new macro expansions
       would be:

              SRC = a b
              OBJ = {$(SRC)}.o

              prgm : $(OBJ)
                   cc -o $@ $<

              $(OBJ) : g.h

       If we want to keep the objects in a separate directory, called  objdir,
       then we would write something like this.

              SRC = a b
              OBJ = {$(SRC)}.o

              prgm : $(OBJ)
                   cc $< -o $@

              $(OBJ) : g.h
              %.o : %.c
                   $(CC) -c $(CFLAGS) -o $(@:f) $<
                   mv $(@:f) objdir

              .SOURCE.o : objdir   # tell dmake to look here for .o’s

       An  example  of  building library members would go something like this:
       (NOTE:  The same rules as above will be used to produce .o’s from .c’s)

              SRC= a b
              LIB= lib
              LIBm= { $(SRC) }.o

              prgm: $(LIB)
                   cc -o $@ $(LIB)

              $(LIB) .LIBRARY : $(LIBm)
                   ar rv $@ $<
                   rm $<

       Finally,  suppose that each of the source files in the previous example
       had the ‘:’ character in their target name.  Then we  would  write  the
       above example as:

              SRC= f:a f:b
              LIB= lib
              LIBm= "{ $(SRC) }.o"      # put quotes around each token

              prgm: $(LIB)
                   cc -o $@ $(LIB)

              $(LIB) .LIBRARY : $(LIBm)
                   ar rv $@ $<
                   rm $<

COMPATIBILITY

       There  are  two  notable  differences  between  dmake  and the standard
       version of BSD UNIX 4.2/4.3 Make.

              1. BSD UNIX 4.2/4.3 Make supports wild card  filename  expansion
                 for  prerequisite  names.   Thus if a directory contains a.h,
                 b.h and c.h, then a line like

                 target: *.h

                 will cause UNIX make to expand the *.h into  "a.h  b.h  c.h".
                 dmake does not support this type of filename expansion.

              2. Unlike  UNIX  make, touching a library member causes dmake to
                 search the library for the member  name  and  to  update  the
                 library  time  stamp.   This  is only implemented in the UNIX
                 version.  MSDOS and other versions may  not  have  librarians
                 that  keep  file  time  stamps, as a result dmake touches the
                 library file itself, and prints a warning.

       dmake is not compatible with GNU  Make.   In  particular  it  does  not
       understand GNU Make’s macro expansions that query the file system.

       dmake is fully compatible with SYSV AUGMAKE, and supports the following
       AUGMAKE features:

              1. GNU Make style  include,  and  if/else/endif  directives  are
                 allowed   in  non-group  recipes.   Thus,  the  word  include
                 appearing at the start of a line that is not part of a  gruop
                 recipe  will be mapped to the ".INCLUDE" directive that damke
                 uses.  Similarly, the words ifeq,ifneq,elif,else,  and  endif
                 are mapped to their corresponding dmake equivalents.

              2. The  macro modifier expression $(macro:str=sub) is understood
                 and is equivalent to the expression $(macro:s/str/sub),  with
                 the  restriction  that  str  must match the following regular
                 expression:

                 str[ |\t][ |\t]*

                 (ie. str only matches at the end of a token where  str  is  a
                 suffix  and  is terminated by a space, a tab, or end of line)
                 Normally sub is expanded before the substitution is made,  if
                 you  specify -A on the command line then sub is not expanded.

              3. The macro % is defined to be $@ (ie. $% expands to  the  same
                 value as $@).

              4. The AUGMAKE notion of libraries is handled correctly.

              5. Directories  are  always  made  if  you  specify -A.  This is
                 consistent with other UNIX versions of Make.

              6. Makefiles that utilize virtual targets  to  force  making  of
                 other  targets  work  as  expected  if AUGMAKE special target
                 handling is enabled.  For example:

                 FRC:
                 myprog.o : myprog.c $(FRC) ; ...

                 Works as expected if you issue the command

                 ’dmake -A FRC=FRC’

                 but fails with a ’don’t know how to make FRC’  error  message
                 if you do not specify AUGMAKE special target handling via the
                 -A flag (or by setting AUGMAKE:=yes internally).

LIMITS

       In some environments the length of an argument  string  is  restricted.
       (e.g.  MSDOS  command line arguments cannot be longer than 128 bytes if
       you are using the standard  command.com  command  interpreter  as  your
       shell, dmake text diversions may help in these situations.)

PORTABILITY

       To  write  makefiles  that can be moved from one environment to another
       requires some forethought.  In particular you must define as macros all
       those  things  that may be different in the new environment.  dmake has
       two  facilities  that  help  to  support  writing  portable  makefiles,
       recursive  macros  and  conditional expressions.  The recursive macros,
       allow one to define environment  configurations  that  allow  different
       environments  for  similar types of operating systems.  For example the
       same make script can be used for SYSV and BSD but with different  macro
       definitions.

       To  write  a  makefile that is portable between UNIX and MSDOS requires
       both features since in almost all cases you will  need  to  define  new
       recipes  for  making  targets.   The  recipes  will  probably  be quite
       different since the capabilities of  the  tools  on  each  machine  are
       different.   Different macros will be needed to help handle the smaller
       differences in the two environments.

FILES

       Makefile, makefile, startup.mk (use dmake -V  to  tell  you  where  the
       startup file is)

SEE ALSO

       sh(1), csh(1), touch(1), f77(1), pc(1), cc(1)
       S.I. Feldman  Make - A Program for Maintaining Computer Programs

AUTHOR

       Dennis Vadura, dvadura@wticorp.com
       Many  thanks  to  Carl Seger for his helpful suggestions, and to Trevor
       John Thompson for his many excellent ideas and informative bug reports.
       Many  thanks  also  go  to  those on the NET that have helped in making
       dmake one of the best Make tools available.

BUGS

       Some system commands return non-zero status  inappropriately.   Use  -i
       (‘-’ within the makefile) to overcome the difficulty.

       Some  systems  do  not  have  easily accessible time stamps for library
       members (MSDOS, AMIGA, etc) for these dmake uses the time stamp of  the
       library  instead  and prints a warning the first time it does so.  This
       is almost always ok, except when multiple  makefiles  update  a  single
       library  file.   In these instances it is possible to miss an update if
       one is not careful.

       This man page is way too long.

WARNINGS

       Rules supported by make(1) may not work if transitive closure is turned
       off (-T, .NOINFER).

       PWD from csh/ksh will cause problems if a cd operation is performed and
       -e or -E option is used.

       Using internal macros such as COMMAND, may wreak  havoc  if  you  don’t
       understand their functionality.