Technical Capabilities
Having trouble finding what you need?
Get in touch with us, so we can answer your specific questions directly.
Get In Touch

VX/MMS – OpenVMS MMS to make and XML

Overview

VX/MMS is a native Linux implementation of the OpenVMS Module Management System (MMS), DEC's dependency-driven build tool and the OpenVMS analogue of make. It reads an MMS description file, builds an in-memory dependency graph, works out which targets are out of date by comparing file timestamps, and brings each target up to date by running its action lines through VX/DCL. Existing DESCRIP.MMS and MAKEFILE descriptions, their rules, macros, suffix rules and conditionals build the same way on Linux as they did on OpenVMS, so the build automation migrates alongside the application it drives.

Because the action lines are executed through the same VX/DCL command interpreter that runs migrated .COM procedures, the compile, link and utility commands inside a build (COPY, DELETE, LINK, CC, COBOL, FORTRAN and the rest) keep working after migration. VX/MMS plugs into Sector7's continuous integration migration approach: teams keep developing on OpenVMS while the same descriptions rebuild on Linux, so a build environment moves across without a code freeze.

What VX/MMS is

VX/MMS is a standalone build engine, not a translator that emits an intermediate project file. It is shipped as a single image and is also reachable as the MMS verb inside the VX/DCL shell, so a description file that was invoked with MMS on OpenVMS is invoked the same way on Linux. The engine reads a description file, resolves OpenVMS-style file specifications through the VX runtime so they open on a Linux filesystem, and drives the build directly.

OpenVMS MMS conceptVX/MMS counterpartRole
MMS utilitymms image + MMS DCL verbReads the description file, builds the dependency graph, updates out-of-date targets.
Description-file parserLine-oriented MMS lexer and parserParses comments, continuation, dependencies, directives, macros and conditionals.
Dependency and build engineVerification and bottom-up build engineCompares timestamps, applies built-in and suffix rules, orders the build.
Action execution (spawns DCL)VX/DCL action-line bridgeRuns each action line through VX/DCL and translates the exit status back to VMS status.
MMS$STATUS / MMS$SEVEREST_STATUSPublished DCL global symbolsExposes the per-image and worst-case build status to the surrounding procedure.
Actions run through VX/DCL. VX/MMS does not reimplement the compilers or file utilities a build calls. It hands each action line to VX/DCL, the same interpreter that runs migrated .COM procedures, so COPY, DELETE, LINK, CC, COBOL and FORTRAN behave consistently across scripts and builds.

Build data flow

The engine runs one description file through three stages and emits updated targets:

Input candidate 1DESCRIP.MMSPreferred default description file.
Input candidate 2MAKEFILE.Second default description file candidate.
Input candidate 3<target>.MMSTarget-derived description file candidate.
01ParseExpand macros and interpret directives from the selected input.
02Dependency graphResolve targets, sources, and explicit or built-in rules.
03Verify timestampsCompare modification times to identify out-of-date targets.
04Update targetsRun action lines through VX/DCL in bottom-up dependency order.

The build is driven bottom-up: a target's sources are brought up to date first, recursively, before the target's own action lines run. A target is considered out of date when it is forced, when it is built from sources, when it does not exist, when any source is newer than it, or when a prerequisite was itself just rebuilt.

Build lifecycle

VX/MMS follows the classic MMS three-phase model. The same phases and the same description-file search order that OpenVMS MMS uses are preserved, so an existing build resolves its description file and its default target identically on Linux.

PhaseWhat happens
InitializationLocate and parse the description file, expand macros, and build the dependency graph. With /DESCRIPTION=foo and no dot, .MMS is appended.
VerificationStat each target and its sources and compare modification times to decide what must be rebuilt.
File processingBottom-up: build sources first (recursively), then run the target's action lines through VX/DCL.

Description-file search order

When no /DESCRIPTION qualifier is given, VX/MMS looks for a description file in the OpenVMS order and uses the first one it finds:

The default goal is the first target declared in the file when no target is named on the command line, matching OpenVMS behaviour.

Special targets and ordering

TargetEffect
.FIRSTIts actions run once, before any other target is processed.
.LASTIts actions run once, after all targets, even if the build failed.
.DEFAULTSupplies actions for any target that has none of its own.
Cycle protection. Each target carries a visit state while the graph is walked. Re-entering a target that is still on the build stack is reported as a circular dependency (%MMS-F-GWKLOOP) rather than looping forever.

Description-file language

The parser is a real, line-oriented MMS lexer: it honours the same lexical rules, dependency forms, action-line prefixes, directives and macro syntax as OpenVMS MMS. The examples below use a banking demo estate, but the syntax is exactly what a migrated description file contains.

Lexical rules

ConstructHandling
Comment! to end of line, respecting text inside double quotes.
Line continuationA trailing - or \ joins the next physical line.
Blank lineEnds the current rule group.
Indented lineAn action line for the current rule.
Column-1 lineA directive, a macro definition, or a dependency.
Target / source splitCommas and/or whitespace separate list members.

Dependency separators

Three dependency forms are recognised:

  • :: anywhere on the line declares a double-colon rule.
  • : with whitespace on either side declares a single-colon rule.
  • the keyword DEPENDS_ON (case-insensitive) is treated as a single-colon rule.

Mixing : and :: for the same target is flagged as an error (%MMS-E-GFBTYPEMIX).

Action-line prefixes

PrefixMeaning
-Ignore this line's error and keep going.
@Silent: do not echo the line before running it.
?nameRemap this line's status through a matching .ACTION_STATUS definition.

A description file

A representative banking build: macros, a link target with two object sources, a compile rule, and a conditional that selects debug or optimised compiler flags.

! Ledger posting build
CC     = CC
LINK   = LINK

.IFDEF prod
CFLAGS = /OPTIMIZE
.ELSE
CFLAGS = /DEBUG
.ENDIF

LEDGER.EXE : LEDGER.OBJ, POSTING.OBJ
    $(LINK)/EXE=LEDGER.EXE LEDGER.OBJ, POSTING.OBJ

LEDGER.OBJ : LEDGER.C LEDGER.H
    $(CC)$(CFLAGS) LEDGER.C

POSTING.OBJ : POSTING.C LEDGER.H
    - $(CC)$(CFLAGS) POSTING.C

Directives

DirectiveEffect
.SILENTGlobal no-echo of action lines.
.IGNORE / .IGNORE_ALLGlobal ignore-error.
.FIRST / .LAST / .DEFAULTRun-before, run-after, and fallback action sets.
.SUFFIXESReplace the suffix precedence list (empty clears it).
.SUFFIXES_AFTER / .SUFFIXES_BEFORE / .SUFFIXES_DELETEAppend, prepend, or remove named suffixes.
.ACTION_STATUS name = valDefine a named status for ?name action prefixes.
.INCLUDE "file"Parse another description file inline (macro-expanded, quote-stripped).
.IF / .IFDEF / .IFNDEFOpen a conditional on an expression or on a macro being (un)defined.
.ELSE / .ELSIF / .ENDIFBranch and close a conditional.
Nothing is silently dropped. An unrecognised .-directive is warned (%MMS-W-DRVPARSERR), not ignored without notice. .INCLUDE nesting is capped to guard against loops (%MMS-F-LEXFILELOOP), and an unterminated .IF at end of file warns (%MMS-W-LEXNOENDIF).

Special and user macros

Macro expansion is recursive, so CFLAGS = $(OPT)/debug resolves nested references, with a depth guard that raises an error on a probable circular reference. Undefined macros expand to the null string, per the OpenVMS manual, and a command-line /MACRO definition wins over an in-file definition. The predefined per-rule macros are populated while a rule's actions run:

MacroMeaning
$(MMS$TARGET)The current target specification.
$(MMS$TARGET_NAME)The target name.
$(MMS$SOURCE)The first source.
$(MMS$SOURCE_LIST)All sources, space-joined.
$(MMS$CHANGED_LIST)Sources newer than the target.

Extended string functions

Under /EXTENDED_SYNTAX, VX/MMS adds a set of GNU-make-style string functions for description files that use them. Patterns use a single % stem, and path splitting recognises the OpenVMS and Unix separators /, ] and :.

SUBST
STRIP
WORD
WORDS
WORDLIST
FIRSTWORD
LASTWORD
FILTER
FILTER-OUT
SORT
ADDPREFIX
ADDSUFFIX
DIR
NOTDIR
BASENAME
FILETYPE
FINDSTRING
PATSUBST
JOIN
WILDCARD
ORIGIN

Built-in rules, suffixes and macros

VX/MMS seeds the standard OpenVMS built-in rules, suffix precedence and rule macros after the description file has been parsed, so any definition the file already provides takes precedence over the built-in default. A description file that relies on the implicit .C.OBJ or .OBJ.EXE rules builds without listing them.

Default suffix precedence

Used only when the description file gives no .SUFFIXES of its own, most-derived first:

.EXE  .OLB  .OBJ  .C  .FOR  .COB  .PAS  .MAR  .BAS  .CLD  .MSG

Built-in suffix rules

RuleAction
.C.OBJ$(CC)$(CFLAGS) $(MMS$SOURCE)
.FOR.OBJ$(FORT)$(FFLAGS) $(MMS$SOURCE)
.COB.OBJ$(COBOL)$(COBFLAGS) $(MMS$SOURCE)
.PAS.OBJ$(PASCAL)$(PFLAGS) $(MMS$SOURCE)
.MAR.OBJ$(MACRO)$(MFLAGS) $(MMS$SOURCE)
.OBJ.EXE$(LINK)$(LFLAGS) $(MMS$SOURCE)

Default rule macros

Each of these is overridable from the description file or the command line:

CC = cc
CFLAGS =
LINK = link
LFLAGS =
FORT = fortran
FFLAGS =
COBOL = cobol
COBFLAGS =
PASCAL = pascal
PFLAGS =
MACRO = macro
MFLAGS =
LIBR = library

Suffix-rule inference

When a target has no explicit sources and no actions, VX/MMS infers a rule: for each source suffix in precedence order whose rule .<src>.<tar> exists and whose candidate file is present on disk, that source and the rule's actions are adopted. When a target has explicit sources but no actions, the first source's suffix drives the rule lookup. This is how a bare LEDGER.EXE : LEDGER.OBJ line links without spelling out the link command.

Action execution and status

The point of difference from a pure make clone is that VX/MMS action lines are OpenVMS DCL, not shell. Each action line is handed to VX/DCL for execution, so the compile, link and file commands inside a migrated build run through the same interpreter that runs the estate's .COM procedures.

The VX/DCL bridge

Each action line is run by spawning a fresh VX/DCL process that executes just that command and exits. The child's real exit status is captured and translated back into an OpenVMS status value: success maps to a success status, a non-zero exit maps to error severity, and a process killed by a signal maps to fatal severity. A /OUTPUT=file qualifier redirects each child's output so that action output joins MMS's own output stream.

DCL state does not persist across action lines. Because each line runs in its own one-shot VX/DCL process, changes such as SET DEFAULT, local symbols and logical names defined in one action line are not visible to the next. Lines that need shared state must be combined onto one line or moved into a command procedure. This is a deliberate, documented divergence from OpenVMS MMS, which runs actions in a single subprocess context.

Status model

VX/MMS tracks the worst status seen across all action lines. A line whose status indicates failure aborts the build (%MMS-F-ABORT) unless the failure is suppressed by a line-level - prefix, a global .IGNORE, or a /IGNORE severity floor. Severity is ranked WARNING below ERROR below FATAL. The final status is returned by the image and published as the DCL global symbols MMS$STATUS and MMS$SEVEREST_STATUS for the surrounding procedure to test.

The .ACTION_STATUS directive maps status letters to OpenVMS status values for use with the ?name action prefix:

LetterSeverity
SSuccess.
IInformational.
WWarning.
EError (the default).
FFatal.

A numeric value is taken as-is, so a description file can define an exact status code.

CLI qualifiers and compatibility

The MMS verb takes a target list and the OpenVMS MMS qualifiers. The qualifiers that control the build itself are honoured; a set of less common qualifiers is parsed and warned as deferred rather than being silently accepted, so a build never behaves differently than the description file implies.

Honoured qualifiers

QualifierEffect
/DESCRIPTION=fileUse a named description file (.MMS appended if no dot).
/ACTION / /NOACTIONRun action lines, or print them without running.
/VERIFY / /NOVERIFYEcho, or suppress the echo of, action lines.
/FORCERebuild targets regardless of timestamps.
/FROM_SOURCESRebuild everything from sources.
/IGNORE[=WARNING|ERROR|FATAL]Set the severity floor below which a failing action does not abort.
/MACRO=("N=V",...)Define macros on the command line; these win over in-file definitions.
/EXTENDED_SYNTAXEnable the extended string functions.
/OUTPUT=fileSend MMS and action output to a file.
/LOGEmit informational diagnostics.
/IDENTIFICATIONPrint the version and exit.

Compatibility status

FeatureStatus
Description-file parse (comments, continuation, blank-line grouping)live
Single-colon, double-colon and DEPENDS_ON ruleslive
Action prefixes -, @, ?namelive
Simple and recursive macro expansion, special macroslive
Conditionals (.IF / .IFDEF / .IFNDEF / .ELSE / .ELSIF / .ENDIF)live
Directives (.SILENT / .IGNORE / .FIRST / .LAST / .DEFAULT / .INCLUDE / .ACTION_STATUS)live
.SUFFIXES family and built-in suffix ruleslive
Suffix-rule inference for undeclared targetslive
DCL action execution, status and severity handling, abort/ignorelive
/EXTENDED_SYNTAX string functionslive
Persistent DCL state across action linesout of scope: per-line one-shot, documented
/OVERRIDE /REVISE_DATE /RULES /SKIP_INTERMEDIATE /LIST /CHANGED /CMS /SCA_LIBRARY /GENERATEdeferred: parse-and-warn
Deferred qualifiers are named, not ignored. A deferred qualifier emits %MMS-W-DRVQUALIF, /<q> is recognised but not yet implemented (deferred), ignored, so a build script relying on one is told clearly rather than getting a silently different result.

Divergences from OpenVMS MMS

DivergenceReason
Action lines run as one VX/DCL process per line, with no shared DCL state.The one-shot command path is reliable across platforms; lines needing shared state combine onto one line or use a command procedure.
/NODESCRIPTION (build purely from built-in rules) is not yet supported.Built-in-rule-only builds are planned for a later phase; the qualifier reports rather than misbuilds.

Quick reference

Invocation

MMS [/quals] target[,target...]

Common qualifiers

/DESCRIPTION=file
/MACRO=("N=V")
/FORCE
/FROM_SOURCES
/NOACTION
/NOVERIFY
/IGNORE[=ERROR]
/LOG
/EXTENDED_SYNTAX
/OUTPUT=file
/IDENTIFICATION

Description-file resolution

Without /DESCRIPTION, VX/MMS uses the first available candidate in the canonical search order shown under Build lifecycle.

Rule syntax

target[,...] : [source[,...]] (or :: / DEPENDS_ON), then indented action lines. Action prefixes: - ignore error, @ silent, ?name status map.

Special macros

$(MMS$TARGET)
$(MMS$TARGET_NAME)
$(MMS$SOURCE)
$(MMS$SOURCE_LIST)
$(MMS$CHANGED_LIST)

Built-in suffix rules

.C.OBJ
.FOR.OBJ
.COB.OBJ
.PAS.OBJ
.MAR.OBJ
.OBJ.EXE

Diagnostic codes

ABORT
DRVBADPARSE
DRVDEPFIL
DRVOUTFIL
DRVPARSERR
DRVQUALIF
EXENCRE
GFBTYPEMIX
GWKCURRNT
GWKLOOP
GWKNOACTS
LEXFILELOOP
LEXNOENDIF
LEXNULLNAME
LFSBADFP
MBREDEFILL

Frequently Asked Questions

Curious about how Sector7 can facilitate your application migration? Explore our FAQs for expert insights.

What is VX/MMS?

VX/MMS is a Linux implementation of the OpenVMS Module Management System (MMS), DEC's dependency-driven build tool and the OpenVMS analogue of make. It reads your existing MMS description files, works out which targets are out of date, and rebuilds them on Linux, so your build automation migrates with the rest of your OpenVMS application.

Do I have to rewrite my MMS description files?

No. Existing DESCRIP.MMS and MAKEFILE descriptions, along with their rules, macros, suffix rules and conditionals, are parsed and built the same way on Linux as they were on OpenVMS.

How does VX/MMS run the commands in my build?

Each action line is executed through VX/DCL, the same command interpreter that runs your migrated .COM procedures. Commands such as COPY, DELETE, LINK, CC, COBOL and FORTRAN keep working after migration because they run in the same DCL environment as the rest of the estate.

Does migrating my build force a code freeze?

No. VX/MMS fits Sector7's continuous integration migration approach. Teams keep developing on OpenVMS while the same descriptions rebuild on Linux, so the build environment moves across without a code freeze.

Which MMS features does VX/MMS support?

VX/MMS supports single-colon, double-colon and DEPENDS_ON rules; the action-line prefixes; recursive macro expansion and the special MMS$ macros; the full conditional family (.IF, .IFDEF, .IFNDEF, .ELSE, .ELSIF, .ENDIF); directives such as .FIRST, .LAST, .DEFAULT, .INCLUDE and the .SUFFIXES family; the built-in suffix rules; and extended string functions under /EXTENDED_SYNTAX.

How does VX/MMS differ from OpenVMS MMS?

The main difference is that each action line runs in its own VX/DCL process, so state such as SET DEFAULT, local symbols and logical names does not persist between lines. Lines that need shared state are combined onto one line or moved into a command procedure. A small set of less common qualifiers is deferred, and VX/MMS reports each one clearly rather than ignoring it silently.

Does VX/MMS work with the rest of my migrated OpenVMS toolchain?

Yes. VX/MMS drives the migrated compilers such as VX/C, VX/COBOL and VX/FORTRAN, and it runs alongside VX/DCL, VX/CDD, VX/DECFORMS and VX/MSG during a build.

How does VX/MMS report build status and errors?

VX/MMS tracks the worst status across all action lines, aborts on a failing line unless the failure is ignored, and publishes MMS$STATUS and MMS$SEVEREST_STATUS as DCL symbols for the surrounding procedure to test. Unrecognised directives and deferred qualifiers are named in diagnostics rather than dropped silently.

Transform Your Legacy Software Today!

Get In Touch
Unlock the potential of your legacy software with our expert migration services.