Following a long Unix tradition, the Mercury compiler is called ‘mmc’ (for “Melbourne Mercury Compiler”). Some of its options (e.g. ‘-c’, ‘-o’, and ‘-I’) have a similar meaning to that in other Unix compilers.
Arguments to ‘mmc’ may be either file names (ending in ‘.m’), or module names, with ‘.’ (rather than ‘__’ or ‘:’) as the module qualifier. For a module name such as ‘foo.bar.baz’, the compiler will look for the source in files foo.bar.baz.m, bar.baz.m, and baz.m, in that order. Note that if the file name does not include all the module qualifiers (e.g. if it is bar.baz.m or baz.m rather than foo.bar.baz.m), then the module name in the ‘:- module’ declaration for that module must be fully qualified. To make the compiler look in another file for a module, use ‘mmc -f sources-files’ to generate a mapping from module name to file name, where sources-files is the list of source files in the directory (see Output options).
Arguments to ‘mmc’ may also be in ‘@file’. The ‘@file’ argument is replaced with arguments representing the contents of the file. This argument processing is done recursively. The contents of the ‘@file’ is split into arguments one per line in the file.
To compile a program which consists of just a single source file, use the command
Unlike traditional Unix compilers, however, ‘mmc’ will put the executable into a file called filename, not a.out.
For programs that consist of more than one source file, you can use Mmake (see Using Mmake) or the ‘--make’ option to ‘mmc’. Currently, the use of ‘mmc --make’ is recommended:
mmc --make filename
If you use Mmake or ‘mmc --make’, then you don’t need to understand the details of how the Mercury implementation goes about building programs. Thus you may wish to skip the rest of this chapter.
To compile a source file to object code without creating an executable, use the command
mmc -c filename.m
‘mmc’ will put the object code into a file called module.o, where module is the name of the Mercury module defined in filename.m. It also will leave the intermediate C code in a file called module.c. If the source file contains nested modules, then each sub-module will get compiled to separate C and object files.
Before you can compile a module, you must make the interface files for the modules that it imports (directly or indirectly). You can create the interface files for one or more source files using the following commands:
mmc --make-short-int filename1.m filename2.m … mmc --make-priv-int filename1.m filename2.m … mmc --make-int filename1.m filename2.m …
If you are going to compile with ‘--intermodule-optimization’ enabled, then you also need to create the optimization interface files.
mmc --make-opt-int filename1.m filename2.m …
If you are going to compile with ‘--transitive-intermodule-optimization’ enabled, then you also need to create the transitive optimization files.
mmc --make-trans-opt filename1.m filename2.m …
Given that you have made all the interface files, one way to create an executable for a multi-module program is to compile all the modules at the same time using the command
mmc filename1.m filename2.m …
This will by default put the resulting executable in filename1, but you can use the ‘-o filename’ option to specify a different name for the output file, if you so desire.
The other way to create an executable for a multi-module program is to compile each module separately using ‘mmc -c’, and then link the resulting object files together. The linking is a two stage process.
First, you must create and compile an initialization file, which is a C source file containing calls to automatically generated initialization functions contained in the C code of the modules of the program:
c2init module1.c module2.c … > main-module_init.c, mgnuc -c main-module_init.c
The ‘c2init’ command line must contain the name of the C file of every module in the program. The order of the arguments is not important. The ‘mgnuc’ command is the Mercury GNU C compiler; it is a shell script that invokes the GNU C compiler ‘gcc’ with the options appropriate for compiling the C programs generated by Mercury.
You then link the object code of each module with the object code of the initialization file to yield the executable:
ml -o main-module module1.o module2.o … main_module_init.o
‘ml’, the Mercury linker, is another shell script that invokes a C compiler with options appropriate for Mercury, this time for linking. ‘ml’ also pipes any error messages from the linker through ‘mdemangle’, the Mercury symbol demangler, so that error messages refer to predicate and function names from the Mercury source code rather than to the names used in the intermediate C code.
The above command puts the executable in the file main-module. The same command line without the ‘-o’ option would put the executable into the file a.out.
‘mmc’ and ‘ml’ both accept a ‘-v’ (verbose) option. You can use that option to see what is actually going on. For the full set of options of ‘mmc’, see Invocation.