The mmxxsupgen support file generator

mmxxsupgen is a tool used to simplify the arrangement of MMXX classes into modules, and the tracking of dependencies across modules. Its input includes a list of MMXX classes, the headers they're declared in, and the modules they belong to, and a description of cross-module dependencies. It automatically generates two kinds of support files:
  1. A prefix header file (with suffix .mpr.h) for each defined module, used to inform MMXX of the implementation location of classes by assigning appropriate, module-specific values to the _MMXX_SHADOW_<class_name> macros. This file is intended to be prefixed to the compilation of all MMXX-related source files in the module.
  2. A module import/export file (with suffix .mie.cpp) for each defined module, intended to be compiled as a source file and linked with the module. This will generate all the required MMXX support code and glue for the classes that the module exports (i.e. implements) and imports (i.e. references or derives from.)
The method by which the .mpr.h file is prefixed to compilation in user projects is, unfortunately, dependent on the development environment used to build them. See the section on platform support for an overview of the suggested mechanism(s) for your target platform.

mmxxsupgen's input files consist of directives separated by single / (slash) tokens, and use the .mxg suffix (if the platform supports it, the directives may be specified directly on the command line instead.) Inside directives, an identifier prefixed by a @ token denotes a module name, whereas a % prefix denotes a subset name, a # prefix denotes a header name (note that the .h suffix is implicit and should not be specified), and the absence of a prefix denotes a class name. Directives are either of the form:

  [ extern ] [ auto ] module [ ":" module_dependencies ] [ "=" module_contents ]

used to specify a module's contents and dependencies, and:

  subset "=" subset_contents

used to define a subset.

In the above, module_dependencies is a comma-separated list of foreign classes, whole headers, subsets or whole modules that the module depends upon (and thus needs to import) and module_contents is a comma-separated list of classes and subsets that the module implements (and thus will export.) If the extern keyword is used, then no files will be generated for the module being defined. Unless you're generating support files for all modules with a single mmxxsupgen input file, you will want to use extern for those modules whose support files are generated elsewhere. The auto keyword indicates that the module in question is linked by way of the library auto-loading facility, explained below.

A subset is an alias for a list of classes, and behaves similarly to a macro or shell variable. Subsets can be useful to delineate logical divisions between major components of a module. The syntax for subset_contents is the same as that for module_contents. Once defined, a subset needs to be implemented in a module before it can be used as a dependency.

Here are examples of items that might be placed in each of these lists:

Contents examples:

foo#bar Module implements class foo, found in header bar.h
aardvark Class aardvark. Since the header is omitted, it's implicitly assumed to be the same as the class name, namely aardvark.h.
Red + Green + Blue #Colors Classes Red, Green and Blue, found in header Colors.h.
%gui Module implements the subset named gui, which must have been previously defined. Only one module may implement a subset.

Dependency examples:

foo#bar@zap Module depends upon class foo, found in header bar.h and implemented in module zap. Note that all the classes in header bar.h will actually be imported.
#bar In practice, same as above, if more ambiguous. The module is implicitly zap - since mmxxsupgen requires class/header/module items to be defined before they can be specified as dependencies, it already knows which module implements the classes in bar.h. All classes in bar.h are imported.
foo Again, same result as above.
@zap All the classes/headers implemented by module zap.
%gui The subset named gui, which must have been previously defined and implemented in a module.

Here is an example input file:

%gui = gc#gfx, widget /
/* defines subset gui to contain two classes, gc in header gfx.h and widget in header widget.h. The slash is used to separate directives. */

extern @zap = %gui, foo#bar, aardvark, %HOST /
/* zap implements the classes found in subset gui, the foo and aardvark classes from the examples above, and the MMXX support classes (implying that zap is the host module.) Since it's marked as extern, no support files for module zap will be generated here. */

@ab : foo, %HOST = Red + Green + Blue #Colors, calculator
/* module ab imports (depends upon) class foo and the MMXX support classes, and implements the three classes in Colors.h as well as class calculator in calculator.h */

Note that both C-style and C++-style comments can be used in input files. With these input directives, mmxxsupgen will generate ab.mpr.h and ab.mie.cpp, intended to be respectively prefixed and compiled when building module ab.

mmxxsupgen predefines two subsets, %HOST and %MINHOST. %HOST is a list of all the MMXX support classes that are themselves MMXX-enabled. The %HOST subset must be implemented by the host module. Note that if the library auto-loading system is used, the "host" module is in fact lib2020. All other modules must have a dependency to %HOST or, if they do not use any of MMXX's library classes directly (and the user wishes to save an however-small amount of support glue,) to %MINHOST. It is recommended that %HOST be used everywhere instead of %MINHOST.

Library auto-loading system

This system should be employed when the host executable depends upon one or more MMXX libraries. Under this arrangement, the MMXX support classes are implemented and exported by lib2020, and imported by all other modules. The mmxxsupgen input file for an executable that uses a single library mylib will look as follows:

extern auto @lib2020 = %HOST /
/* a directive for lib2020 itself must be specified */

extern auto @mylib : %HOST = myclass /

auto @myexecutable : %HOST, myclass
/* in this particular application, the executable exports no classes */

Note the use of the auto flag. If the executable will manually load any further modules, these modules must be specified without the auto flag.