Next: , Previous: , Up: Compiling multi-module programs   [Contents][Index]


2.3.2 Introduction to mmake

The Mercury build tool that was implemented first is mmake, whose name is short for “Mercury make”. If you have Mercury program containing three modules, maybe called main_module.m, module_a.m and module_b.m, with the main predicate being in main_module.m, you can use these commands to compile a program:

mmc -f *.m
mmake main_module.depend
mmake main_module

The first step creates the Mercury.modules file that maps the name of each module inside each Mercury source file in the current directory to the name of the file containing it. It is not needed if all the modules are stored in files whose name is the module name plus the .m suffix.

The second step creates some small files containing makefile fragments. These small files will include main_module.dep and main_module.dv, which record whole-program-level information, such as the list of modules in the program, and the intended executable name. In this case, that name will be main_module, either without an extension, if the platform does not require one for executables, or with the required extension (such as .exe on Windows).

The second step will also create one file with the suffix .d for each module in the program, with e.g. module_a.d recording which other modules module_a.m imports.

One important aspect of .d files is that every compilation of a Mercury module will implicitly update that module’s .d file if its old contents are not up-to-date. This is not true for .dep and .dep files; those are updated only if you explicitly ask for it, e.g. via the second step command above.

The third step then uses those small files to create all the necessary interface files in the proper order, to compile each Mercury module, and to then link the resulting object files together to yield the desired executable.

In outline, mmake works by concatenating the set of makefile rules for Mercury compilation built into it, all the makefile fragments in .dep, .dv and .d files in the current directory, and the file named Mmakefile if it exists, and invoking gmake on it, passing it the targets or targets that it itself was given. (gmake is the GNU version of the standard Unix make program, though on many platforms it is installed as just plain make.)

This close relationship to gmake allows mmake to be used to control not just the compilation of Mercury code, but also the building of any other file, provided only that one can write makefile rules for their construction.

Many small Mercury projects don’t really need an Mmakefile, but they have one anyway, usually looking something like this:

PROGRAM_NAME = prog

.PHONY: default_target
default_target: $(PROGRAM_NAME)

.PHONY: depend
depend: Mercury.modules $(PROGRAM_NAME).depend

Mercury.modules: $(wildcard *.m)
        mmc -f $(wildcard *.m)

.PHONY: install
install:
        test -d $(INSTALL_DIR) || mkdir -p $(INSTALL_DIR)
        cp $(PROGRAM_NAME) $(INSTALL_DIR)

.PHONY: clean
clean:  $(PROGRAM_NAME).clean

If you have an Mmakefile like this, you can then type just

mmake depend

instead of

mmc -f *.m
mmake main_module.depend

and you can type just

mmake

instead of

mmake main_module

And obviously, the Mmakefile also shortens the command you need to give to install the program, or to clean up the directory by deleting the automatically regenerable files.

For more information on how to use this tool, please see Using Mmake.


Next: , Previous: , Up: Compiling multi-module programs   [Contents][Index]