This manual describes the MMK Make Utility, a "make" utility for VMS systems.
Revision/Update Information: This is a revised manual.
Operating System and Version: VAX/VMS V5.2 or later; OpenVMS Alpha V1.5 or later; OpenVMS IA64 V8.2 or later
Software Version: MMK V4.1
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The following are trademarks of Hewlett-Packard Development Company, LP:
| AXP | DEC | OpenVMS |
| VAX | VMS |
UNIX is a registered trademark of USL, Inc.
| Contents |
This guide explains how to install and use MMK.
This manual is intended for all MMK users, primarily programmers who need to build software systems.
MMK is patterned after VAX DEC/Module Management System (DEC/MMS), which is in turn based on the UNIX make utility. The reader is assumed to have at least cursory knowledge of make or DEC/MMS.
This document does not provide a general tutorial on make utilities. New users are advised to learn more about description files (makefiles) by reviewing either DEC/MMS documentation or books on the UNIX make utility. |
tbs
tbs
In this document, the following convention will be used for the names of the three similar utilities:
This chapter describes MMK. It includes an overview of MMK and basic
information on its use.
1.1 Overview
MMK is a tool for building a "software system;" that is, a collection of one or more executable images or other types of files that are related to a particular project. Building a complex system by hand can be a difficult and time-consuming task; using command procedures can make the task easier, but it may still be time-consuming.
With MMK, you create a file called a Makefile or MMS description file to describe your software system: the objects (i.e., source files, object files, etc.) that comprise the system, the dependencies between those objects, and the commands used to build the system. When you invoke MMK, it performs the following steps:
In this way, MMK can execute the commands to rebuild only those pieces
of your software system that need rebuilding due to a change that you
have made. This can drastically reduce development time for a project.
1.2 Invoking MMK
Provided that MMK has been installed using the steps laid out in the installation instructions (file AAAREADME.INSTALL in the kit), you can invoke MMK from DCL as a foreign command:
$MMK |
Full command syntax is given in MMK. By default, MMK looks for a description file called DESCRIP.MMS in the current directory; if that file does not exist, it then looks for a file called MAKEFILE. If it cannot find that file, an error is signaled. You can use the /DESCRIPTION qualifier to specify a different name for your description file, if needed.
MMK starts by reading the description file and constructing a tree from the objects listed in the description file (e.g., source files, include files, object files, etc.) and a tree of dependencies between those objects. It then identifies the target object to be built, and traverses the dependency tree to identify those objects that need to be built (called intermediate targets) in order to build the target.
MMK compares each target's revision date/time against the objects on which it depends and executes the actions for that building the target only if needed. You can force a complete rebuild by using the /FROM_SOURCES qualifier on the MMK command.
The key to successfully building your software system with MMK is the
creation of a complete and accurate description file. This chapter
describes the format for a description file and its components.
2.1 Description File Components
A description file is a collection of the following components:
Here is an example of a simple description file:
PROGRAM.EXE : MAIN.OBJ,SUBROUTINES.OBJ
LINK/EXEC=PROGRAM.EXE MAIN.OBJ,SUBROUTINES.OBJ
MAIN.OBJ : MAIN.FOR
FORTRAN MAIN
SUBROUTINES.OBJ : SUBROUTINES.MAR
MACRO SUBROUTINES
|
This is a simple collection of dependencies and actions for building an image called PROGRAM.EXE. PROGRAM.EXE depends on two object files, called MAIN.OBJ and SUBROUTINES.OBJ; MAIN is a FORTRAN module and SUBROUTINES is a MACRO module.
MMK accepts either a colon or the DEC/MMS DEPENDS_ON keyword to
separate a target object from its sources. In either case, the
separator must be surrounded by blanks---this differs from
make, but is consistent with DEC/MMS syntax.
2.2 Using Inference Rules
MMK includes a collection of built-in inference rules and actions for most VMS programming languages. The rules are driven by the file type suffix attached to the object name; you must use the default file types in order to make use of the default rules.
For example, the description file in the last section could be simplified to just:
PROGRAM.EXE : MAIN.OBJ,SUBROUTINES.OBJ
LINK/EXEC=PROGRAM.EXE MAIN.OBJ,SUBROUTINES.OBJ
MAIN.OBJ : MAIN.FOR
SUBROUTINES.OBJ : SUBROUTINES.MAR
|
MMK's built-in inference rules automatically define the actions for building a .OBJ file from a .FOR (using the FORTRAN command) and for building a .OBJ file from a .MAR file (using the MACRO command).
The description file could even be simplified further, to just:
PROGRAM.EXE : MAIN.OBJ,SUBROUTINES.OBJ
LINK/EXEC=PROGRAM.EXE MAIN.OBJ,SUBROUTINES.OBJ
|
MMK automatically searches the suffixes list when constructing
the dependency tree and locates inference rules for the .OBJ files
automatically. This illustrates the second use for inference rules:
they are used not only for inferring actions for a dependency that
omits them, but they may also be used for inferring dependencies
themselves based on a combination of source and target suffixes. This
second purpose can greatly simplify your makefiles, and makes the build
process more automatic.
2.3 Defining Inference Rules
You can define your own inference rules, either to extend or replace the ones built into MMK. You may include these rule definitions in your makefile, or in a separate file called a rules file. Rules files can be included by the use of a logical name or through the /RULES qualifier on the MMK command; see the MMK for further information.
MMK supports two types of inference rules: generic and prefixed. Generic rules are based solely on suffixes (file types), as in:
.C.OBJ :
CC/OBJECT=$(MMS$TARGET) $(MMS$SOURCE)
|
Prefixed inference rules are based on both suffixes and "prefixes"---device and directory specifications. This provides a way to have MMK automatically infer dependenices between files that reside in different directories. For example: For example, the prefixed rule:
{SRC$:}.C{OBJ$:}.OBJ :
CC/OBJECT=$(MMS$TARGET) $(MMS$SOURCE)
|
tells MMK, "to build OBJ$:filename.OBJ from an existing file called SRC$:filename.C, use the CC command." This works like the generic rule above, but with the additional provision of having the source and target reside in different locations.
You can have more than one prefixed rule for a particular pair of suffixes; you may also mix generic rules and prefixed rules for a pair of suffixes. When attempting to infer a dependency, MMK will first use the prefixed rules, then fall back to using the generic rule.
In prefixed rules, the curly braces ("{" and "}") are required. One of the two prefixes may be null, but specifying two null prefixes is equivalent to defining a generic rule.
In order to match a prefixed rule, file specification as it exists in the description file must match the prefix in the rule; MMK performs no logical name translation on prefixes, nor can it identify equivalencies between two prefixes that reference the same directory using different syntax.
The first inference rule for a pair of suffixes, whether it is generic or prefixed, must specify an action list; subsequent rules for the same pair of suffixes (with different prefixes) may have the action list omitted, in which case MMK will use the action list from the first rule. For example, MMK already has a built-in generic rule for .C.OBJ, which is:
.C.OBJ :
$(CC)$(CFLAGS) $(MMS$SOURCE)
|
If you are simply adding a set of prefixed rules for the .C.OBJ suffix
pair, you do not need to specify an action list on those rules; MMK
will use the action list from the built-in generic rule.
2.4 Forced Setup/Teardown Actions in Inference Rules
MMK recognizes two special modifiers on action lines specified for inference rules. The setup modifier, "<", forces the execution of an action prior to any unmodified action. The teardown modifier, ">", forces the execution of an action after all other actions. Setup and teardown actions are performed for all dependencies matching the inference rule, even if a dependency includes explicit actions.
For example, the inference rule
.C.OBJ :
< DEFINE/USER DECC$SHR V6_ROOT:[SYSLIB]DECC$SHR
$(CC)$(CFLAGS) $(MMS$SOURCE)
|
would cause the logical name DECC$SHR to be defined prior to the invocation of the C compiler for all compilations into .OBJ files. This would apply even on dependencies containing explicit actions, such as
FRED.OBJ : FRED.C $(CC)$(CFLAGS)/DEFINE=FRED $(MMS$SOURCE) |
MMK uses a suffix list to determine the inference rules it should search for inferring a dependency. MMK has a built-in suffix list which goes with its list of built-in inference rules; see Appendix B for more information on the built-in rules and suffix list.
You can augment or replace the built-in suffix list with your own suffixes by using the .SUFFIXES directive in a rules file or a makefile.
For example, let's say you have a Modula-2 compiler on your system, whose source files have a file type (suffix) of .MOD. MMK has no built-in inference rules for this file type; you could add one with the following sequence:
.SUFFIXES : .MOD
.MOD.OBJ :
MODULA2/OBJECT=$(MMS$TARGET) $(MMS$SOURCE)
|
The .SUFFIXES directive above adds the .MOD suffix to the end of the suffix list. This is followed by the inference rule for creating an object file from a Modula-2 source file.
Specifying the .SUFFIXES directive with nothing to the right of the
colon clears the current suffix list. You can do this to prevent MMK
from using any inference rules for the current build, or to follow it
with another .SUFFIXES directive that specifies only those suffixes for
which you want inference rules to be enabled.
2.6 Using Conditionals
MMK provides several directives that can be used to modify the build sequence based on conditions. These directives are .IF, .IFDEF, .IFNDEF, .ELSE, and .ENDIF. The .IFDEF, .ELSE, and .ENDIF directives work the same as for MMS; the .IF and .IFNDEF directives are MMK extensions. The .IFNDEF directive provides the logical inverse to .IFDEF; the check succeeds if the specified macro is not defined. The .IF directive supports more general comparisons. Its syntax is
.IF "expression1" comparison "expression2" |
MMK provides a way to defer the resolution of a macro that is referenced in the right-hand side of a macro definition, as an extension to MMS. Macros are normally referenced using the $(name) syntax, which causes the value of the macro to be substituted immediately when a line is parsed (except for MMK's "special" macros, such as MMS$SOURCE and MMS$TARGET).
You can defer this substitution in MMK by using the syntax ${name} instead. However, this syntax is only recognized on the right-hand side of a macro definition. This can be useful when defining macros in a rules file that rely on macros that do not get defined until another rules file or a description file gets processed. For example, you might have the following definition in a rules file:
CFLAGS = /OBJECT=$(MMS$TARGET)/NOLIST/DEFINE=(VMS_BUILD,${MOREDEFINES})
|
MOREDEFINES = ANOTHER_C_DEFINE |
MMK provides two mechanisms for causing string substitution to occur
when resolving a macro reference: suffix substitution and general
string substitution.
2.8.1 Suffix Substitution
When a string contains a list of file specifications, you can replace the file type suffixes on each file specification with a different suffix. The general form of this type of substitution is:
$(macro-name:old-sfx=new-sfx) |
which causes the replacement of all occurences of the file type suffix old-sfx with new-sfx. Both suffixes must begin with a dot.
For example, in these macro definitions:
SOURCES = FIRST.C, SECOND.C, THIRD.C OBJECTS = $(SOURCES:.C=.OBJ) |
General string substitution in macro references is an extended feature of MMK. It looks very similar to suffix substitution, but uses a double colon ("::") instead of a single colon and allows the substitution to occur anywhere within the string. The syntax is:
$(macro-name::old-str=new-str) |
which causes the replacement of all occurences of the string old-str with new-str. You may use a backslash "\" as a "literal-next" escape when one of the strings contains an equals sign. Neither string may contain a right parenthesis character (")"), even quoted with a backslash, although this restriction will be lifted in a future release of MMK. For example, the following macro definitions:
SOURCES = FIRST.C,SECOND.C,THIRD.C SOURCEPLUS = $(SOURCES::,=+) |
General string substitutions in macro references are case-insensitive, but do not ignore blanks in the macro value or in the substitution rule. For example, in the following definitions:
TEST = Xyz xYz xyZ REPLACED = $(TEST::YZ =YZ,) |
| Next | Contents |