                            MAKE
            Implementation of Unix make Utility
                            for
         TOPS-20 & VMS & MS-DOS & UNIX & EON & OS/9
                        [18-Apr-87]

MAKE is a version of  a public-domain implementation of  the
Unix  make  utility.   A  single  source  program   supports
versions for TOPS-20, VAX VMS, MS-DOS, UNIX, EON, and  OS/9;
the choice between them is made at compile-time when MAKE is
built.  It is compatible to a high degree with the  original
Unix  version,  as  far  as  the  syntax  of  MAKEFILE's  is
concerned.  The built-in default rules have been modified to
be suitable for TOPS-20, VAX  VMS, and MS-DOS, and a  number
of additional rules have been added.  They are given  below.

The essential ideas behind MAKE are:

        Many  common  tasks  in  software  development   are
        repetitive (edit - compile -  link - run and  test),
        and should be encapsulated in a command file to save
        typing.

        Processing (e.g. compilation)  of a  single file  is
        unnecessary if that  file, and  its dependent  files
        (e.g. #include  files)  are older  than  the  output
        file(s) of the processing step.

        A computer  program  specially constructed  for  the
        purpose (MAKE) can read  a list of dependencies  and
        rules from a file, and from them, and from the  file
        last-write time stamps, determine what steps need to
        be taken to bring everything up to date.

Complete documentation  on MAKE  can be  found in  any  Unix
manual   on   the   corresponding   man   page   (the   file
/usr/man/man1/make on most Unix  systems).  The man page  is
available in INFO  node (UNIXMAN)MAKE  on UTAH-SCIENCE.   An
extended description is found in

        S.I. Feldman,  "Make --  A Program  for  Maintaining
        Computer Programs", pp.  291-300, Unix  Programmer's
        Manual,  Volume  2,  Holt,  Rinehardt  and   Winston
        (1983).

That article is in /usr/doc/make  on most Unix systems,  and
is in INFO node MAKE on UTAH-SCIENCE.

The original version of MAKE  was done by Stuart Feldman  in
1978.  This  multi-operating-system version  is based  on  a
public-domain posting  of 3-Dec-86  to the  Usenet  bulletin
board  mod.sources,  its  author  known  only  by  an  EMAIL
address: Caret@FAIRLIGHT.OZ.  It contained support for Unix,
OS9, and  EON  operating  systems.  The  TOPS-20,  VMS,  and
MS-DOS   support   was   added   by   Nelson   H.F.    Beebe
(BEEBE@UTAH-SCIENCE).

Support for  VAX VMS  libraries  was borrowed  from  another
public-domain  VMS  MAKE  by  Todd  Aven.   This  permits  a
filename   in    a    MAKEFILE    to    be    replaced    by
"libname.xlb(modulename)".   The   library   filename   must
include the file extension, since  it cannot be inferred  by
context.  Here is a simple example:

foo.olb(bar):	bar.obj
	library foo.olb bar.obj
	delete bar.obj

fee.exe:	fee.obj foo.olb(bar)
	link fee,foo/lib

With library targets,  the macro $@  expands to the  library
name, and $% to the  module name.  Library support is  still
weak in that there is no  way in the current MAKE syntax  to
specify a  default  rule  for installing  a  module  into  a
library, since the rule syntax assumes the files differ only
in extension.

Under Unix, when MAKE determines that it needs to execute  a
shell command to update a target  file, it issues a call  to
system() in the standard C library.  The command is executed
by a fresh copy of the shell, and it returns an exit code (0
on success, non-zero on  error) to the  shell which in  turn
returns that code to MAKE.

The implementation of system()  with the KCC compiler  under
TOPS-20 differs somewhat, in  that the shell (TOPS-20  EXEC)
is fed its commands  from the terminal  input buffer, as  if
they were typed  by the user,  exactly like the  DO and  MIC
commands and the batch job controller do, instead of getting
them from a file.  This  mechanism is necessary because  the
EXEC has not been trained to exit gracefully at  end-of-file
in a top-level command  file.  The net  effect is the  same,
with the exception that it  is possible for user  type-ahead
to be mixed  in with  the input  MAKE is  stuffing into  the
terminal input buffer;  therefore, when  running MAKE,  keep
your fingers off the keys until it is done.

If you wish to have  MAKE's commands executed in batch,  the
command list can be captured in a file, and not executed  by
MAKE, as follows:

        make -n >foo.ctl
        submit foo

TOPS-20 commands do  not return any  command status code  to
their parent, so a TOPS-20 MAKE  run may attempt to do  more
steps than it  would under Unix,  since it normally  assumes
that each step succeeds.

The touch (-t) option is not yet implemented in the  TOPS-20
and VAX VMS versions of MAKE.

Unlike  Unix  make,   this  MAKE  has   been  built  to   be
case-insensitive, both  for command-line  switches, and  for
rules and file  names in makefiles.   A compile-time  switch
can select case sensitivity if desired.

In order  to  support multi-line  strings  to be  passed  to
system() (usually  a  program  invocation  and  its  input),
TOPS-20 MAKE provides for the substition of "\n" literals in
rule lines by newlines prior to calling system.  Here is  an
example:

liblcl: fileof.rel jfnof.rel freass.rel system.rel getlog.rel
        delete liblcl.rel
        maklib\n\
        liblcl=freass,fileof/a,getlog/a,jfnof/a,system/a\n\
        liblcl=liblcl/index\n\
        
        copy liblcl.rel.0 c:
        delete liblcl.rel

Note that  the  MAKLIB  invocation actually  consists  of  4
lines.  The backslash on the first 3 is necessary to get the
rule picked up as one string, and the "\n" sequences will be
converted to newlines by doexp() before the rule line (which
is really 4 lines) is passed to system().

MAKE has fairly lax parsing  rules, and the only  characters
that are  particulary  significant are  white  space  (token
separators),  initial  tab  (on  a  rule  line),  colon  and
semicolon following  a  target  name, and  equals  in  macro
assignments.    Nevertheless,    these   characters    could
conceivably be  required  in names,  particularly  colon  in
TOPS-20, VMS, and MS-DOS filenames.  Therefore, an extension
to Unix make is adopted which permits a backslash to protect
the following  character from  special interpretation.   The
following sequences are recognized:

        \n      LF, newline
        \t      HT, horizontal tab
        \b      BS, backspace
        \r      CR, carriage return
        \f      FF, formfeed
        \\      \, backslash
        \'      ', single quote
        \ddd    ddd, character corresponding to 1, 2, or 3
                octal digit bit pattern.

Any other  backslash-char  pair  is  reduced  to  char;  for
example, \= will be reduced to =, and \\ to \.

Here is the complete list  of built-in TOPS-20 MAKE  macros,
rules, and suffixes.  It was produced by requesting MAKE  to
print its built-in values by executing

        MAKE -p

in a PHOTO session, then editing the output PHOTO log.  Note
that it includes rules for compiling source code in C, FAIL,
FORTRAN,  MACRO, MIDAS,  PASCAL,   and  SFTRAN3,   and   for
processing various  TeX  files.  All  compiler  and  program
names used  in  built-in  rules are  defined  by  macros  to
facilitate modifying  MAKE's behavior.   Finally, macros  RM
and MV are used for DELETE and RENAME, to facilitate porting
MAKEFILE's from TOPS-20 to Unix.

        $ = $
        AFLAGS =
        AMSTEX = AMSTeX
        AMSTEXFLAGS = \batchmode
        AS = compile
        CC = kcc
        CFLAGS =
        FC = compile
        FFLAGS = /debug:(argument,label)
        LATEX = LaTeX
        LATEXFLAGS = \batchmode
        MV = rename
        PC = compile
        PFLAGS =
        RM = delete
        SF3 = sf3
        SLITEX = SliTeX
        SLITEXFLAGS = \batchmode
        TEX = TeX
        TEXFLAGS = \batchmode
        YACC = yacc

        .atx.dvi:
        -       $(AMSTEX) $(AMSTEXFLAGS) \input $<


        .amstex.dvi:
        -       $(AMSTEX) $(AMSTEXFLAGS) \input $<


        .c.rel:
        -       $(CC) $(CFLAGS) -c $<


        .fai.rel:
        -       $(AS) $(AFLAGS) $<


        .mac.rel:
        -       $(AS) $(AFLAGS) $<


        .mid.rel:
        -       $(AS) $(AFLAGS) $<


        .for.rel:
        -       $(FC) /fortran/language:"$(FFLAGS)" $<


        .f.rel:
        -       $(FC) /fortran/language:"$(FFLAGS)" $<


        .ltx.dvi:
        -       $(LATEX) $(LATEXFLAGS) \input $<


        .latex.dvi:
        -       $(LATEX) $(LATEXFLAGS) \input $<


        .pas.rel:
        -       $(PC) /pascal/language:"$(PFLAGS)" $<


        .p.rel:
        -       $(PC) /pascal/language:"$(PFLAGS)" $<


        .sf3.for:
        -       $(SF3) $(SF3FLAGS) $<


        .stx.dvi:
        -       $(SLITEX) $(SLITEXFLAGS) \input $<


        .slitex.dvi:
        -       $(SLITEX) $(SLITEXFLAGS) \input $<


        .tex.dvi:
        -       $(TEX) $(TEXFLAGS) \input $<


        .y.c:
        -       $(YACC) $(YFLAGS) $<
        -       $(MV) ytab.c $@


        .y.rel:
        -       $(YACC) $(YFLAGS) $<
        -       $(CC) $(CFLAGS) -c ytab.c
        -       $(RM) ytab.c
        -       $(MV) ytab.rel $@

        .SUFFIXES: .exe .rel .dvi .c .y .l .mac .fai .mid .sf3 .for .f \
                   .pas .p .tex .latex .ltx .slitex .stx .amstex .atx \
                   .inc .h
