% (C) Copyright International Business Machines Corporation 23 January 
% 1990.  All Rights Reserved. 
%  
% See the file USERAGREEMENT distributed with this software for full 
% terms and conditions of use. 
\subsection{Make facility}
\cb{08a}
Typically the set of 
type and process definition modules that compose a Hermes program
are highly interdependent. 
The {\tt makehermes} program automates the activity of compiling a set
of interdependent modules.  
Given a target module {\tt makehermes} determines the set of all modules
on which the target depends, either directly or indirectly.
It then compiles all uncompiled or out-of-date modules in the set,
producing a current version of the target.

{\tt Makehermes} is similar to the Unix `make' program, but easier to use 
because it automatically determines module dependencies
from the {\tt using( )} and {\tt linking( )} lists in Hermes modules.
{\tt Makehermes} does not use a ``makefile.''

{\tt makehermes} is invoked by the command:
$$\hbox{\tt makehermes {\em [options]} {\em target} $\ldots$}$$

\endcb{08a}

{\tt Makehermes} determines and performs (depending on its
options) the necessary compilations (both {\tt dcom} and {\tt pcom})
to produce the requested compiled module files.  Process modules and
definitions modules can both be specified, with the appropriate file
extensions ({\tt .do} for definitions modules, {\tt .po} for process
modules).  For example, the following command would compile one
definition module and three process modules, as well as any other
modules on which they depend and which are out-of-date.
\begin{verbatim}
makehermes foo.do goo.po /u/hermes/bar.po zip.po
\end{verbatim}

\subsubsection{Module dependencies and consistency}

\cb{08a}
There are two ways in which a 
module {\tt bar} can {\em depend on} another module {\tt foo}:
{\tt bar} can import the definitions module {\tt foo} (in its {\tt
using( )} list), or {\tt bar} can statically link process module 
{\tt foo} (in its {\tt linking( )} list).  
A module {\tt bar}\endcb{08a} is {\em
inconsistent} if its source file was modified since it was last
compiled, or if it depends on any other module that is inconsistent or
was compiled more recently than {\tt bar}.

The {\tt makehermes} program determines all the modules on which each
of the {\em target} arguments depends, and then all the modules on
which those modules depend, and so on.  In this way it creates a {\em
dependency graph} where nodes represent modules and edges represent
dependencies between modules.  {\tt makehermes} then recompiles all
\cb{08a}the inconsistent files represented in the graph.
Every module is compiled before all modules that depend on it.
Modules are compiled in a sequence that ensures 
no module will be compiled twice.  Whether
a module is inconsistent is
determined by examining the modification times 
of the files containing the source and object modules.

\subsubsection{Target list files}

Target lists make it easy to make many targets.
A target of the form {\tt foo.target} indicates that file
{\tt foo.target} contains a list of targets.
The target list file can store one target per line. 
Blank lines and lines beginning with the comment 
delimiter {\tt \#} are ignored.

A target of the form {\tt foo}, without any {\tt .po} or {\tt .do}
suffix, is assumed to indicate a target list file named
{\tt foo.target}.  
Be careful to remember the {\tt .po} or {\tt .do} when not using
target lists or {\tt makehermes} will look for a target list.

\subsubsection{Directories searched by {\tt makehermes}}
\label{makehermes-pathvars}

Several environment variables are used by {\tt makehermes} to obtain
search paths for locating target files appearing in the dependency
graph, as follows: 

\begin{itemize}
\item {\tt HSOURCEPATH}: Used to locate Hermes source files ({\tt .p}
and {\tt .d} files), as well as target files ({\tt .target} files).
\item {\tt HLINKPATH}: Used to locate compiled process modules ({\tt
.po} files) referenced in {\tt linking(...)} lists of process module
sources.
\item {\tt HLOADPATH}: Used instead of {\tt HLINKPATH} for locating
compiled process modules, if the latter is not defined.
\item {\tt HPATH}: Used to locate compiled definitions modules({\tt
.do} files) referenced in {\tt using(...)} lists of process and
definitions module sources.  Also used to locate compiled process
modules, if neither {\tt HLINKPATH} nor {\tt HLOADPATH} is defined.
\end{itemize}

If {\tt HPATH} is not defined, it defaults to {\tt .:\$HROOTDIR/bin}.

One other environment variable, {\tt MKSCOPE}, affects the operation
of {\tt makehermes}.  When {\tt makehermes} locates a target file
(using the path variables listed above), it checks to see whether the
file appears in one of the directories listed in {\tt MKSCOPE}.  If
not, the target is automatically considered up-to-date, and {\tt
makehermes} does not attempt to elaborate its dependencies.  This is
useful when your programs import or statically link modules from
``system'' directories or belonging to another user.  Although these
modules may be out of date with respect to their sources, you may wish
to use the most recently compiled versions rather than bring them
up-to-date (indeed, you may not have access to the sources).  By
excluding such directories from {\tt MKSCOPE} you can achieve this
behavior.

If {\tt MKSCOPE} is not defined, it defaults to a search list
including only the current directory.  Thus {\tt makehermes} will
operate only on files in the current directory, by default.

Normally, each {\tt makehermes} satisfies its search for each target
file with the first instance of the file located in the appropriate
search path, as given in the environment variables described above.
However, if a source file appears in the current directory, {\tt
makehermes} will always insist on creating an up-to-date object module
in the current directory, even if an up-to-date object module already
appears in the appropriate search path.  This {\em ad-hoc} rule
facilitates the use of {\tt makehermes} when programs are compiled in
a ``work'' directory and later installed in some other ``system''
directory.  {\tt Makehermes} will always ensure that the work
directory is kept up-to-date, as long as the sources appear in the
work directory.

Finally, note that {\tt makehermes} always places the results of its
compilations in the current working directory (as indicated by the
{\tt getCwd} resource).


\endcb{08a}

\subsubsection{Options}

\cb{08a}
{\tt Makehermes} recognizes four orthogonal 
categories of options.
\endcb{08a}
Options are specified on the command line by means of one or more
option letters preceded by a hyphen.  The options are as follows;
defaults are marked with asterisks:

\begin{enumerate}
\item The {\em action} options determine what {\tt makehermes} will do with 
an inconsistent file.
\begin{verbatim}
  c*     (compile)          compile (pcom or dcom) the file
  p      (print)            print the filename and compilation
                            command, but do not compile
\end{verbatim}
\item The {\em error} options control {\tt makehermes}'s response to
    compilation errors encountered while building the dependency graph and 
    applying the required actions.
\begin{verbatim}
  s*     (Stop)             halt immediately on any error
\end{verbatim}
\cb{08a}
\begin{verbatim}
  g      (Ignore)           ignore all errors, that is, compile every
                            inconsistent module in the dependency graph
  o      (Continue Others)  if a compilation error occurs do not
                            compile modules that depend, directly or
                            transitively, on the module that did
                            not compile.  compile all other modules.
\end{verbatim}
\endcb{08a}
\item The {\em selection} options help select the files to which
{\tt makehermes} will apply its actions. 
\begin{verbatim}
  i*     (Inconsistent)     apply the action to all inconsistent files
  n      (None)             take no action (just build the dependency graph)
\end{verbatim}
\cb{08a}
\begin{verbatim}
  a      (All)              do action to all files in the dependency
                            graph, including ones that are not
                            inconsistent
\end{verbatim}
\cb{08a}
\item {\em Debug} options indicate the level of debugging output.
\begin{verbatim}
  D      (Dependencies)     show all dependencies that are discovered
  Y      (Why)              explain why a makehermes makes or doesn't
                            make each node 
\end{verbatim}
\endcb{08a}
%  - Debug options can appear with other options on the command line:
%     -D - show all dependencies that are discovered
%     -A - announce when actions are being invoked
%     -T - trace the general flow of the make program
%    Of these, only -D is currently implemented.
\endcb{08a}
\end{enumerate}

These options can be combined, as in:
\begin{itemize}
\cb{08a}
\item{\tt hermes makehermes -ap bar.po}  will list all the actions
that would be required for a complete rebuild of {\tt bar.po}.
\item{\tt hermes makehermes -cg foo.do} will perform all compilations
required to bring {\tt foo.do} up-to-date.  It will attempt to compile
every inconsistent module in the dependency graph.
\endcb{08a}
\end{itemize}
