Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
DMAKE(1)		    General Commands Manual		      DMAKE(1)

       dmake - maintain	program	groups,	or interdependent files

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

       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 prerequi-
       sites  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 spe-
       cial 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	excep-

       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  tar-
       get.   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.

       -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	 stan-
	      dard  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 defi-
	      nitions  in the makefile to override definitions in the environ-

       -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  con-
	      tinue to make as much as possible.

	      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  dis-
	      played  in Unix time format, i.e.	the number of seconds since an
	      epoch.  (Since 1970-01-01T00:00:00Z).  maketarget	obviously rep-
	      resents  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 com-
		     mand) 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 PRO-
	      CESSING" 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  com-
	      mands  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

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

	      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  com-
		     mands.  This  switch  is  useful 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 auto-
		     matically 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 func-
	      tion 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.

       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

       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.

			  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

       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

       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  dmake's 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.

       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	 vari-
		     able 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   "$(DMAKE-
		     ROOT)/",	so you can set the  environment	 vari-
		     able 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 com-
		     mand 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	 make-
       files  and  the	search order that dmake	should use to determine	if one
       exists.	A typical definition for this target is:

	      .MAKEFILES : Makefile	makefile

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

       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	 addi-
       tional  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	speci-
       fied makefile.  The graph is rooted at the special target .ROOT.	 .ROOT
       is  the top level target	that dmake builds when it starts to build tar-
       gets.  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:


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

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

       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	= LINE
			       -> MACRO	[!]*= LINE
			       -> MACRO	[!]:= LINE
			       -> MACRO	[!]*:= LINE
			       -> MACRO	[!]+= LINE
			       -> MACRO	[!]+:= LINE

	      Conditional-Macro-Definition ->  TARGET ?= Macro-Definition

	      Conditional ->  .IF expression
			      [	.ELIF expression
				 Makefile ]
			      [	.ELSE
				 Makefile ]

	      expression -> LINE
			 -> STRING
			 -> 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
			-> .EXECUTE
			-> .GROUP
			-> .IGNORE
			-> .LIBRARY
			-> .MKSARGS
			-> .NOINFER
			-> .NOSTATE
			-> .PHONY
			-> .PROLOG
			-> .SETDIR=path
			-> .SILENT
			-> .SWAP
			-> .SYMBOL
			-> .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 contin-
       ued  over  several physical lines by terminating	it with	a single back-
       slash 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.  \#	trans-
       lates 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 pro-
       cessing 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 def-
       inition 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 spec-
       ifications  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.

       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	inclu-
		   sion	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.

		   Disable the special meaning of  '['	to  initiate  a	 group

       .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	match-
		   ing	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  prereq-
		   uisites.  If	set as a global	attribute this implies setting

       .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	direc-
		   tory	 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 `:' charac-
		   ters	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 specify-
		   ing	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 and
		   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 file and once for the
		   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 rep-
		   resentation.	 (This attribute is specific for cygwin	 dmake
		   executables	and non-cygwin environments ignore this	attri-

		   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

		   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:


		   With	.WINPATH set it	expands	to:


       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,
       assigned	global meaning.

       Any attribute may be used with any target, even with the	 special  tar-
       gets.   Some  combinations are useless (e.g. .INCLUDE .PRECIOUS:	... ),
       while others are	useful (e.g. .INCLUDE .IGNORE  :  ""  will  not
       complain	 if  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.

       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 forc-
       ing the specified macro assignment.

       When dmake defines a non-environment macro it strips leading and	trail-
       ing  white  space from the macro	value.	Macros imported	from the envi-
       ronment 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 specifica-
       tion 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 expres-
       sion representing a macro expansion, the	expansion is performed.	  Cir-
       cular 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	 hier-
       archy  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:


       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}   ->
	      $(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 follow-
       ing 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

       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


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

	      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.

	      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:


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

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


       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


	      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	incom-
       patibility 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	under-

       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  pro-
       vided  with  a  rule defining the target, that recipe is	used to	update
       the target.  A rule definition begins with a line having	the  following

	      _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.  Spe-
       cial 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 sep-
       arated 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  tar-
	      gets.   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 def-
	      inition 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	 make-

       |      Is defined only for PERCENT rule target definitions.  When spec-
	      ified 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 rede-
       fined again with	a new recipe by	using a	`:' operator with a `:'	 modi-
       fier.   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 prerequi-
       site list for the target.  The `:' operator with	no recipe always modi-
       fies the	current	list of	prerequisites.	Thus assuming each of the fol-
       lowing definitions has a	recipe attached, then:

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


	      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)


	      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	 defi-
       nitions 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.

       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	termi-
       nated  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 ter-
	      minal 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  signifi-
       cant, 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.

       dmake supports some builtin commands. An	optional leading '+' describes
       that the	builtin	can be used also when being executed in	a shell	other-
       wise 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	expan-
	      sions at the runtime of the recipe without starting a real comm-

       [+]<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

       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	imple-
       mented  even  though  the <empty	recipe>	will most propably also	not be
       evaluated by most shells	that can be used to handle the recipe groups.

       dmake supports the notion of text diversions.  If a  recipe  line  con-
       tains the macro expression

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

       then all	text contained in the data expression is expanded and is writ-
       ten to a	temporary file.	 The data in the file will  always  be	termi-
       nated  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

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

       is replaced by:

	      cat /tmp/mk12294AA

       where  the  temporary  file contains two	lines both of which are	termi-
       nated 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:


       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:


       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.

       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 "Don't 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 vir-
       tual target.

       Virtual targets should not have a  corresponding	 file  therefore  they
       inherit	the  time  of their newest prerequisite	if they	have prerequi-
       sites, 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.

       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 pro-
		     cessing.  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	termi-
		     nated 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 make-
		     file  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 envi-
		     ronment  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 mes-
		     sage 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 mak-
		     ing 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 ter-
		     minate 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 :=

		     It's  effect  is  to  turn	on STATE keeping and to	define 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 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

       .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

       .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:


       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  tar-
       gets  are  recognized  and are considered special, their	exact form and
       use is defined in the sections that follow.

       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.

       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

       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 sys-
		       tems 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

       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	 func-
		       tion 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" oth-

       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).

		       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 Win-
		       dows as the filesystems on this	operating  system  are
		       case insensitive	and set	to "yes" for all other operat-
		       ing 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  insensi-
		       tive 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 sys-
		       tems  the  value	 of  NAME_MAX is too short by default.
		       Setting a new value for NAMEMAX will override the  com-
		       piled 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 con-
		       dition 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	infer-
		       ences (See the "AUGMAKE META RULES" and "COMPATIBILITY"

       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 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 in	the

       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  num-
		       ber,  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 with-
		       out 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 build system. If set, the	switch
		       disables	the removal of leading './' path elements dur-
		       ing  target  filename  normalization  (See BINDING TAR-
		       GETS). If './' appear in	the pathname, but not  at  the
		       beginning  of it, they are still	removed	by the normal-
		       ization.	Please note that targets that are given	on the
		       command line are	going to be registered as default tar-
		       gets after the startup file is read.

       PREP	       This macro defines  the	number	of  iterations	to  be
		       expanded	 automatically	when processing	% rule defini-
		       tions 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, 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 envi-
       ronment	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 environ-
       ment 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	condi-
       tions 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,	 .PRO-
       LOG,  .SEQUENTIAL,  .SILENT,  .SWAP,  and  .USESHELL.  Assigning	any of
       these a non NULL	value will globally set	the corresponding attribute to

       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  %  pat-
       tern  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 terminat-
       ing  a  text  diversion when they appear	literally together in the same
       input line.

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

	      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

	      $@ --> 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

       dmake  supports	a  full	 set  of functional macros.  One of these, the
       $(mktmp ...)  macro, is discussed in detail in the TEXT DIVERSION  sec-
       tion 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

	      $(!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 sep-
		     arated 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	illus-
		     trates 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  expres-
		     sion, 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 follow-
		     ing foreach expression:

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


			    "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 dis-
		     card 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	expan-
		     sion  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

	      $(or macroterm ...)
		     expands each macroterm  in	 turn  and  returs  the	 empty
		     string  if	 each term expands to the empty	string;	other-
		     wise, 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 exe-
		     cuted. 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 sin-
		     gle space.

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

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

	      is equivalent to:


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

       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  dis-
       carded. The use of this special feature is deprecated and should	not be

       dmake supports conditional macros.  These allow the definition of  tar-
       get 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  any-
       where  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 :: defini-
       tions 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.

       dmake looks for prerequisites whose names contain macro expansions dur-
       ing  target  processing.	  Any  such prerequisites are expanded and the
       result of the expansion is used as the prerequisite name.  As an	 exam-
       ple 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  tar-
       gets .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 identi-
       fier and	not as a character of the filename leading to invalid  runtime
       macros.	In addition to this no filename	normalization is done for pre-
       requisites and targets that contain $ characters.  Nevertheless	it  is
       possible	to use $ in prerequisites by using $$$$	but this is not	recom-
       mended 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	expan-
       sion  the  prerequisite list is fully expanded even if the dynamic pre-
       requisite contained other runtime macros.

       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 con-
       tains  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  mem-
       ber) attribute is searched for, it is first searched for	as an ordinary
       file.  When a number of library members require updating	it  is	desir-
       able  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 modi-
       fied as a result	of the fix.

       When dmake constructs target (and prerequisite) pathnames they are nor-
       malized	 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 surpris-
       ing 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 look-
       ing 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.

       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	.<suf-
       fix>.<suffix> (this is still supported, see "AUGMAKE META RULES") or by
       using the not supported by dmake	.SUFFIXES list of suffixes (see	 "SPE-
       CIAL TARGETS" for more details about .SUFFIXES).	 The exact workings of
       this mechanism were sometimes difficult to understand and often	limit-
       ing 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 repe-
       tition 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

	      %.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	depen-
       dency 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 prerequi-
       site 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	infor-
       mation.	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

	      %	:  $$(@: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  prerequi-
       sites  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 tar-
       get.  They do not play an active	role in	driving	 the  inference	 algo-
       rithm.  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,
       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

       dmake bases all of its inferences on the	 inference  graph  constructed
       from  the %-rules defined in the	makefile.  It knows exactly which tar-
       gets 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  clo-
       sure  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 manu-
       factured.  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 dynami-
       cally 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  tar-
       get  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 clo-
       sure 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) $<

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

       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 = +
	      $(SH)echo	hi

       is completely equivalent	to writing

	      SH = +
	      +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


       The  result  of	this  final expansion is the command that will be exe-
       cuted.  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.

       Libraries are easy to maintain using dmake.  A library is a  file  con-
       taining	a collection of	object files.  Thus to make a library you sim-
       ply specify it as a target with the .LIBRARY attribute set and  specify
       its list	of prerequisites.  The prerequisites should be the object mem-
       bers 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 sys-
       tems, 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	appro-
       priate  .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 exam-

       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 $@	$<
		     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 make-
       file utilizing this feature (possibly due to the	fact that it is	 unim-
       plemented 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.

       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 com-
       piler 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

       The Sun Microsystem's Make construct

	      .KEEP_STATE :

       is  recognized and is mapped to	The dmake ver-
       sion 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)

       If the architecture supports it then dmake is capable of	making a  tar-
       get'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	speci-
       fied  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  hon-
       ored.   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 per-
		     formed sequentially in the	order in which they are	speci-
		     fied 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

	      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 cor-
       respond to that displayed by the	-n flag.

       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  tar-
       get  host  and environment.  The	conditional expression is specified as

	      .IF  expression
		 ... if	text ...
	      .ELIF  expression
		 ... if	text ...
		 ... else text ...

       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.

	      #	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 con-
       cisely by using the inference rules defined  in	the  standard  startup
       file.   The default rule	for making .o's	from .c's looks	something like

       %.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 $<

       There  are  two notable differences between dmake and the standard ver-
       sion 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 appear-
		 ing 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

		 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  con-
		 sistent 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 han-
		 dling is enabled.  For	example:

		 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).

       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 interpreter as your
       shell, dmake text diversions may	help in	these situations.)

       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,	recur-
       sive macros and conditional expressions.	 The recursive	macros,	 allow
       one  to define environment configurations that allow different environ-
       ments for similar types of operating systems.   For  example  the  same
       make script can be used for SYSV	and BSD	but with different macro defi-

       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 differ-
       ent  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.

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

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

       Dennis Vadura,
       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.

       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 mem-
       bers  (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.

       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.

Dmake Version 4.12		  2008-02-26			      DMAKE(1)


Want to link to this manual page? Use this URL:

home | help