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.

/DEBUG
 /DEBUG
 /NODEBUG (default)

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

/DEFAULTS
 /DEFAULTS (default)
 /NODEFAULTS

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

/DEFINE
 /DEFINE=("symbol1","symbol1=value1",...)

 Define symbols prior to execution.

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

/FORCE

 Always rebuild all targets, even if they are in synch.

/IGNORE
 /IGNORE
 /NOIGNORE (default)

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

/KEEP
 /KEEP
 /NOKEEP (default)

 Prevent deletion of the command file generated by running MAKE.


/MACRO
 /MACRO=("file1","symbol1=value1",...)

 Define symbols either directly or from a file prior to execution.

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

/VERIFY
 /VERIFY
 /NOVERIFY (default)

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

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.  MAKE   reads
 user-supplied description files and executes any commands required to
 bring the target(s) up to date with respect to all dependents.
3 Parsing
 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 Making
 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 Normal_files
 The comparison date for normal 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
 acceptable to the VAX Librarian facility (.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 Building
 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 Dependencies
 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 Objects
4 Normal_files
 There are no tricks to specifying a normal file. Use the standard VMS
 syntax as described in the DCL Dictionary (et al.).
4 Library_modules
 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. The default  library type is '.OLB'  if no
 type is specified (this  is the VAX  Librarian's default).  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 $*  #
 ##########################
4 CMS_library_modules
 A  CMS module is specified as  the element name followed by   the '~'
 (tilde) character, optionally followed by a CMS library name. You can
 specify a default CMS  library using  the '%CMSLIB'  directive.   For
 example, the element FOO.C in library [.CMS] would be 'FOO.C~[.CMS]'.
3 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 (the  part   that matches the
 wildcard), '$@' expands to the name  of the target,  and '$<' expands
 to  the name of  the prerequisite.  '$?'  expands to the list  of all
 the  prerequisites  whose date  information forced  the target  to be
 built.  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.

 The wildcard character '*' does not have to be the first character in
 the target. You  might  want to have  your  sources   and  objects in
 different directories, for example. The following rule epitomizes the
 flexibility of wildcards:

       [OBJ]*.obj: [SRC]*.c
            cc $</obj=$@

 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.
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.
4 Predefined_symbol
 The symbol  __VAX is defined  when MAKE is run on VAX platforms.  The
 symbol __ALPHA is define when MAKE is run on Alpha platforms.
3 Directives
 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 IFDEF_<symbol>
 Subsequent  commands are executed only if  <symbol> is defined.  This
 processing state will exist until a matching ELSE, ELIFDEF, ELIFNDEF,
 or ENDIF is encountered. These commands may be nested to any depth.
4 IFNDEF_<symbol>
 Subsequent  commands are  executed only  if <symbol> is not  defined.
 This  processing state  will exist until a  matching  ELSE,  ELIFDEF,
 ELIFNDEF, or ENDIF is encountered.  These commands  may be nested  to
 any depth.
4 ENDIF
 Terminates the  processing state established  by a previous  IFDEF or
 IFNDEF directive.
4 ELSE
 Inverts the  processing state  caused by  a previous  IFDEF,  IFNDEF,
 ELIFDEF, or ELIFNDEF directive.
4 ELIFDEF_<symbol>
 The  processing  state established  by the  closest  previous  IFDEF,
 IFNDEF, ELIFDEF, or ELIFNDEF is overridden; subsequent  commands will
 be executed only if <symbol> is defined. 
4 ELIFNDEF_<symbol>
 The  processing  state established  by the  closest  previous  IFDEF,
 IFNDEF, ELIFDEF, or ELIFNDEF is overridden; subsequent  commands will
 be executed only if <symbol> is not defined. 
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>
 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 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. Report bugs to:

      Ned Freed
      Innosoft International, Inc.
      Claremont, CA 91711
      ned@innosoft.com

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