mlton foo.cmis 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.smlthen 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, to MLton, 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.smland bar.cm contains
Group is bar.sig bar.funthen 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 # endifTo conditionally include foo.sml when compiling 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.
Comparison with CM
If you are unfamiliar with CM under SML/NJ, then you can 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 SML/NJ, 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.
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 util/cmcat/cmcat.sml for details. Building cmcat requires that you have already installed a recent version of SML/NJ.
Alternatively, you can convert your CM files to .mlb files. The MLton distribution includes the sources for a utility, cm2mlb, that will print an 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 anchored paths are translated to paths according to a default configuration file (cm2mlb-map). For example, the default configuration includes
$basis.cm/basis.cm $(SML_LIB)/basis/basis.mlbto ensure that a $/basis.cm import is translated to a $(SML_LIB)/basis/basis.mlb import. See util/cm2mlb for details. Building cm2mlb requires that you have already installed a recent version of SML/NJ.