For porting code from SML/NJ and for developing code for MLton under
SML/NJ, MLton supports a very limited subset of
Compilation Manager
(CM) files. From MLton's point of view, a CM file foo.cm
defines a list of SML source files. The call mlton foo.cm is
equivalent to compiling an SML program consisting of the concatenation
of these files. As always with MLton, the concatenation must be
the whole program you wish to compile.
In its simplest form, a CM file contains the keywords Group is
followed by an explicit list of sml files. For example, if foo.cm contains
Group is
bar.sig
bar.fun
main.sml
then a call mlton foo.cm is equivalent to concatenating the
three files together and calling MLton on that SML file. The list
of files defined by a CM file is the same as the order in which the
filenames appear in the CM file. Thus, order in a CM file matters.
In the above example, if main.sml refers to a structure defined
in bar.fun, then main.sml must appear after bar.fun
in the file list.
CM files can also refer to other CM files. A reference to bar.cm from within foo.cm means to include all of the SML files
defined by bar.cm before any of the subsequent files in foo.cm. For example if foo.cm contains
Group is
bar.cm
main.sml
and bar.cm contains
Group is
bar.sig
bar.fun
then a call to mlton foo.cm is equivalent to compiling the
concatenation of bar.sig, bar.fun, and main.sml.
CM also has a preprocessor mechanism that allows files to be
conditionally included. This can be useful when developing code with
SML/NJ and MLton. In SML/NJ, the preprocessor defines the
symbol SMLNJ_VERSION. In MLton, no symbols are defined.
So, to conditionally include foo.sml when compiling under
SML/NJ, one can use the following pattern.
# if (defined(SMLNJ_VERSION))
foo.sml
# endif
To conditionally include foo.sml when comiling under MLton, one can
negate the test.
# if (! defined(SMLNJ_VERSION))
foo.sml
# endif
The filenames listed in a CM file can be either absolute paths or
relative paths, in which case they are interpreted relative to the
directory containing the CM file. If a CM file refers either directly
or indirectly to an SML source file in more than one way, only the
first occurrence of the file is included. Finally, the only valid
file suffixes in a CM file are .cm, .fun, .sig, and
.sml.
11.1 Comparison with CM
If you are unfamiliar with CM under SML/NJ, then you should skip this
section.
MLton supports the full syntax of CM as of SML/NJ version
110.9.1. Extensions since then are unsupported. Also, many of the
syntactic constructs are ignored. The most important difference
between the two is that order in CM files matters to MLton but not
to CM, which performs automatic dependency analysis. Also, CM
supports export filters, which restricts the visibility of modules.
MLton ignores export filters. As a consequence, it is possible
that a program that is accepted by SML/NJ's CM might not be accepted
by MLton's CM. In this case, you will have to manually reorder the
files and possibly rename modules so that the concatenation of the
files is the program you intend.
CM performs cutoff recompilation to avoid recompiling the entire
program, while MLton always compiles the entire program. CM makes
a distinction between groups and libraries, which MLton does not.
CM supports other tools like lex and yacc, while MLton does not.
MLton relies on traditional makefiles to use other tools.
11.2 Porting SML/NJ CM files to MLton
If you have already created large projects using SML/NJ and CM,
there may be a large number of file dependencies implicit in your
sources that are not reflected in your CM files. Because MLton
relies on ordering in CM files, your CM files probably will not work
with MLton. To help in porting CM files to MLton, the MLton
distribution includes the sources for a utility, cmcat, that
will print an ordered list of files corresponding to a CM file. See
doc/mlton/cmcat/cmcat.sml for details. Building cmcat requires
that you have already installed SML/NJ version 110.44.
Alternatively, you may convert your CM files to .mlb files. The
MLton distribution includes the sources for a utility, cm2mlb, that will print a ML basis file with essentially the same
semantics as the CM file -- handling the full syntax of CM supported
by your installed SML/NJ version and correctly handling export
filters. When cm2mlb encounters a .cm import, it attempts
to convert it to a corresponding .mlb import. CM anchors are
translated to paths according to a configuration file in .mlton/cm2mlb-map in the user's home directory (which must be given
by the HOME environment variable. For example, adding
basis $(MLTON_ROOT)/basis
to your cm2mlb-map file will ensure that a $/basis.cm
import is translated to a $(MLTON_ROOT)/basis/basis.mlb import.
See doc/mlton/cmcat/cm2mlb for details. Building cm2mlb
requires that you have already installed SML/NJ version 110.44.