1 MAKE
 MAKE/VMS is a utility which  performs commands specified  by the user
 when  a  dependency  relationship  specified  by   the   user is  not
 satisfied. This is useful in situations such  as software development
 where   the  user is  in an  edit-compile-test   cycle and wishes  to
 simplify the steps between 'edit' and 'test'. Many  other  tasks lend
 themselves well to the MAKE structure.

 $ MAKE [Qualifier(s)] [Target(s)]

2 Qualifiers
/INPUT=<file>
 Choose an alternate makefile. The default value is "MAKEFILE".

/OUTPUT=<file>
 Specify the name  of the command   file.  Use '/KEEP'   also   if you
 actually wish for the file to remain.

/SPAWN
 /SPAWN
 /NOSPAWN (default)

 The default action of  MAKE is to call  the routine LIB$DO_COMMAND to
 execute the command file (if any) that has been built during the Make
 phase. Use of this qualifier directs MAKE to  perform a  SPAWN/NOWAIT
 instead.

/IGNORE
 /IGNORE
 /NOIGNORE (default)

 Ignore errors in the command file (via the command 'SET NOON').

/EXECUTE
 /EXECUTE (default)
 /NOEXECUTE

 Execute the commands needed to  update the targets.   The negation of
 this qualifier is useful in order to obtain a static command file via
 a combination of qualifiers  such as /KEEP,  /FORCE, and  /OUTPUT for
 later use.

/DEFAULTS
 /DEFAULTS (default)
 /NODEFAULTS

 Control reading of the default rules file MAKE_DEFAULTS or MAKE.INI.

/VERIFY
 /VERIFY
 /NOVERIFY (default)

 Echo commands as they execute (via the command 'SET VERIFY').

/DEBUG
 /DEBUG
 /NODEBUG (default)

 Print debugging info (for bug reports).  Much of  the action  of MAKE
 may be discerned from this output.

2 Description
 Make is a program which  reads a file  of  dependencies and  executes
 commands  when one file  is out  of date with  respect to one or more
 files upon which it   depends.  For instance,  an   executable  image
 FOO.EXE depends  upon FOO.OBJ, which in  turn depends  upon FOO.C and
 FOO.H.  If FOO.H is modified,  then it  is newer than  FOO.OBJ and so
 FOO.OBJ needs to be remade.  Because FOO.OBJ is  remade, FOO.EXE will
 become out of date and must be remade subsequently.  The MAKE program
 reads user-supplied description  files  and  executes  any   commands
 required   to bring the target(s)  up  to date  with  respect to  all
 dependents.

 Make has three distinct phases of operation, described below.

3 Parse phase
 MAKE  takes   as input one    or   more description    files   which,
 appropriately enough, describe the relationships  between targets and
 sources. An attempt is made to open the file MAKE_DEFAULTS, which may
 be a logical  name. If this  fails, the file MAKE.INI  in the current
 directory is attempted.    After the initialization  file   is parsed
 (only the first encountered will be used), an attempt is made to open
 MAKEFILE. This, too, may be a logical name. Alternatively,  it may be
 specified on the command line with the /INPUT qualifier.  There is no
 explicit  requirement to  access  a makefile  successfully,   but the
 requirement of  finding at least one  target  implicitly requires  at
 least one makefile to be accessed.

 As the files are read in line by line, they are internalized into the
 various data  structures used by  MAKE, such as the Symbol  list, the
 Target list, the File list,  et al. Output  from the /DEBUG qualifier
 demonstrates the parsing phase in gory detail.

3 Make phase
 After all makefiles  have  been digested, one  or  more  targets  are
 'made'. If any targets  were  specified on the command  line, each is
 'made' in turn.  If no targets  were specified, the first  bona  fide
 target encountered during the parsing phase is 'made'.

 A target is 'made'  by making in turn each  of its prerequisites.  If
 you  are  thinking that this  is a  recursive definition, you   might
 consider becoming  a  programmer.  When  MAKE reaches  the end   of a
 branch, it climbs back down a level in the tree comparing the date of
 the current level's target to  the newest dependent. If  a target  is
 older than at least one of its prerequisites (and a missing target is
 considered infinitely old),  it is 'built' according  to the commands
 that were supplied with the dependency rule being examined.

 A  target  is  out  of date  if it  is newer  than  a  dependent, but
 obviously the more general case has a  target out of  date if it does
 not  even exist.   Also,  one    can create  a  target  that   has no
 dependents, a so-called 'terminal target'.  Terminal targets exist or
 don't exist, but can't be out of date.  If a terminal target does not
 exist, it will be 'built' (the commands for the target will be  added
 to the command file).   If it exists,  fine.  If  any dependent of  a
 target is built, then  the target must  be built as  well.  Since the
 'making' is recursive, the leaves of the tree  are checked before the
 branches so that this forces 'building' to propagate back to the root
 target.

4 Regular files
 The comparison  date for regular files is   the revision date  of the
 file   as  returned by  the VAXCRTL  'stat'   function.  This  can be
 examined from DCL using the DIR/DAT=MOD command.

4 Library modules
 The comparison date for library modules (syntax  = 'lib.typ(mod)') is
 the  date of last modification  of  the  module as  returned   by the
 LBR$SET_MODULE routine. Note that libraries may be of any type (.OLB,
 .TLB, .MLB, etc.).

4 CMS elements
 The comparison date for CMS elements is the date of last modification
 for the  generation of the  element in the  specified  class, or  the
 newest generation along the  main  line   of descent if  no  class is
 specified.

3 Execute phase
 Building a  target   consists  of placing    the  commands,  suitably
 formatted, into  a command file for   later execution. When the  Make
 phase completes, the command file is closed and it is executed (using
 LIB$DO_COMMAND)  in the current  process, unless the /SPAWN qualifier
 was  specified  or the %SPAWN  directive  was encountered  without  a
 countermanding %NOSPAWN.  Simple error handling  is included  in  the
 command file to cause command processing to  terminate when an  error
 (DCL ERROR severity) is encountered. Also, the  command file contains
 a command to delete itself  upon exiting. This can be  prevented  via
 the /KEEP qualifier.

2 Syntax
 The description file is called a 'MAKEFILE',  as in the UNIX version.
 Lines in  a  VMS makefile fall  into  four categories: target  lines,
 command lines, symbol lines, or directives.

3 Target lines
 Target lines must begin at column  one (no preceding whitespace). The
 colon separating the targets from the prerequisites  must be followed
 by  at  least one whitespace.   Targets and  prerequisites    may  be
 separated from each other by commas and/or whitespace. Because commas
 are simply replaced with whitespace in a target line, two commas in a
 row do not signify a null target. If  a target or  prerequisite has a
 qualifier attached  ('/junk'), the   qualifier  is removed  from  the
 module name. This allows a symbol to be used in both target lines and
 command lines.  For instance, you  may have  a symbol  defined as the
 list of LINK  options files, with each options  file  followed by the
 qualifier '/OPT'. This way, you can use the symbol in the target line
 AND the LINK command.

3 Command lines
 A  command line  is ANY  line  with  whitespace in  column one.   The
 commands apply to ALL targets on the most recent target line.  If the
 the last non-whitespace character on the command  line is a '$',  the
 dollar sign is removed and no  '$ ' will be  prepended to the command
 line on output. This allows you to indicate that  a 'command line' is
 actually a data line for a program and not a DCL command  line.  If a
 command line  ends  in '-', the following line  will be  handled as a
 continuation  line, so no  '$' will be  prepended to the _next_ line.
 If both the '$' and the '-' need to be used, such as when you wish to
 continue a data line, the order of the two characters IS significant.
 When using both special characters, the order should be  '-$',  since
 the dollar sign is removed first. If '$-' was  used, the '-' would be
 detected as the last character and the '$' would  be left at  the end
 of the line without having been processed.

3 Symbol lines
 Symbol  definitions begin  in column  one. The  presence of  the  '='
 character  distinguishes  these lines from target lines.  The  symbol
 name is the first string  on the  left side of  the '='. The symbol's
 value is everything  to the right  of  the '=',  not   including  any
 whitespace following the '='. For instance, the  symbol line "FOO BAR
 JOE'S GARAGE  = This string" would  result in the symbol 'FOO'  being
 assigned the value "This string".  Note that since the delimiter  for
 the symbol name is ONLY whitespace, you can inadvertently have symbol
 names with special  characters   such   as  punctuation   or  control
 characters.  WARNING: if you define the one-character  symbols '{' or
 '(', you will be  unable to use multi-character   symbols.  Also, you
 must not define a multi-character  symbol with the characters  ')' or
 '}'  in them.  The  symbol  parsing routine is  not  smart  enough to
 understand that these are not symbol name terminators.

3 Directive lines
 Directives are signified by a  '%'  in column  one. There  can not be
 whitespace between  the '%' and the  directive  name. Some directives
 take  arguments,  which must  be separated by   whitespace   from the
 directive name.

4 INCLUDE <file>
 Causes the parsing routine to digest the specified file.

4 CMSLIB <directory>
 Selects the specified directory as the default CMS library.

4 CMSGEN <generation specification>
 Specifies the generation to be used for determining element dates.

4 DEBUG
 Turn on debugging (similar to the /DEBUG command qualifier).

4 NODEBUG
 Turn off debugging (similar to the /NODEBUG command qualifier).

4 SPAWN
 Direct MAKE to spawn the command file at the end of execution.

4 NOSPAWN
 Direct MAKE to execute the command file in the current process at the
 end of execution.

3 Example
 # <== This is a comment indicator (in column one)
 ! <== As is this
 %SPAWN	  !Force the command file to be spawned at the end of making
 foo.exe: foo.obj        # This is a target line 
         link foo        # This is a DCL command line 

 foo.obj: foo.c foo.h    ! <== This is also a comment indicator 
         cc/lis foo 

 As a human would read the description, it says:

 "FOO.EXE depends upon FOO.OBJ.  If FOO.EXE is out  of date or FOO.OBJ
 has been  'made', then  add  the command 'LINK   FOO' to   a file  of
 commands to be executed.  FOO.OBJ depends  upon FOO.C  and FOO.H.  If
 it is out of date, or either of its dependents have been 'made', then
 add 'CC/LIS FOO' to the command file to be executed."

2 Makefiles
 MAKE tries to  locate two description files. The  first  is nominally
 the default rules file,  while the second is  the 'main'  description
 file. In  reality, there is no internal  distinction  between the two
 files.   No error is  reported  if neither file   is found.  An error
 during the MAKE phase will be displayed:  if you  specify a target on
 the command line and  it  exists, nothing  happens; if the  target is
 missing, the error  is "target  doesn't  exist and  couldn't be made"
 since there are no  rules; if no target  was specified on the command
 line, then MAKE has no target and complains accordingly.

3 Default rules
 The first file which MAKE attempts to locate is a description of  the
 default rules to be applied when  no explicit rules for  a target are
 provided. Two  attempts   are made to locate  a  default rules  file.
 First,  the file "MAKE_DEFAULTS"  (which may be a  logical  name)  is
 tried.   If the open  fails on  this file, MAKE   tries for the  file
 "MAKE.INI".

3 Makefile
 The  second file which MAKE  attempts to locate  is "MAKEFILE", which
 may be a logical name. You may also specify this file on the  command
 line via the '/INPUT' qualifier.

2 Default rules
 When  dealing with complex programs, it   is not  reasonable to  list
 explicitly rules for compilation of every module.   Rather, one would
 like to be able to say "If X.Obj is out of date, go look for X.C  and
 compile it, regardless of who X is." This  feature is provided by the
 default rules mechanism:

 ####################
 *.obj : *.c        # '$*' is a symbol which means
         cc $*      # 'whatever matched the *'.
 ####################

 With the above makefile, we may compile any C program (FOO) by giving
 the  DCL command  '$ make foo.obj'.  The default  rule will match the
 '*' with 'foo' and will insert '$ cc foo' into the command file.

 The default rules will be searched for a pattern match only if either
 there are no rules for the file in question or there are rules but no
 command lines.  If a match is found, the default rules will be  added
 just  as though  they  were  found  explicitly in  the makefile.  The
 symbol '$*' expands to  the root  name (file name without extension),
 and '$@' expands to the name of the  target, and '$<'  expands to the
 name of the prerequisite. In the case of multiple rules for a target,
 the first rule for which the prerequisite _exists_ will  be used.  If
 no rule has an existing prerequisite,  then the  first  matching rule
 will be used.

 Default rules  are added to  the head of  the internal rules list, so
 that a default  rule in the   Makefile will take precedence over   an
 identical rule in the default rules file.

2 Library modules
 A special form of name is recognized.  A  name like 'a.olb(b)'  means
 the module named 'b' stored in the library  named 'a.olb'.  This name
 is  handled  just  like a   normal file name,   except that a special
 routine is entered to read the modification time of the module in the
 library.  If the library doesn't exist, then it is made.  If there is
 a rule for creating the library, such as:

 ###################
 a.olb :	   #
         lib/cre a #
 ###################

 then it will be created.  Otherwise, an error  is signalled since the
 library couldn't be found.  Note that  you can use a  default rule to
 create the library if it doesn't exist:

 ##########################
 *.olb :		  #
         lib/cre $*	  #
 *.hlb :		  #
         lib/help/cre $*  #
 *.tlb :		  #
         lib/cre/text $*  #
 ##########################

2 General_Advice
 The Makefile that comes with MAKE/VMS is a very good  example of what
 can be done with the system.  Also, UNIX makefiles  are fairly useful
 to examine, but obviously the command lines will be different.  Also,
 since it is horribly inefficient  in VMS to spawn  a subprocess   for
 each command, there is a fundamental difference between the operation
 on VMS and UNIX.  UNIX MAKE spins off a new process for each command,
 but MAKE/VMS builds  a command file  and defers  execution until  the
 end.  I like  my way    much better, but  I  have  the  advantage  of
 hindsight.  Of  course, there are   some significant drawbacks to the
 batch method, too.

2 Bugs
 There are always bugs. I'm sure there are plenty.  Report bugs to

                Todd Aven
                the Software Sweatshop
		165 East Broadway, #3B
		Long Beach, NY  11561
		(516)432-3002

	   ******** Please include /DEBUG output. *********
