PLT mzc: MzScheme Compiler Manual

Building a Stand-alone Executable

Since the output of mzc relies on MzScheme to provide all run-time support, there is no way to use mzc to obtain small stand-alone executables. However, it is possible to produce a large stand-alone executable that contains an embedded copy of the MzScheme (or MrEd) run-time engine.

5.1  Stand-Alone Executables from Scheme Code

The command-line flag --exe directs mzc to embed a module (from source or byte code) into a copy of the MzScheme executable. The created executable invokes the embedded module on startup. The --gui-exe flag is similar, but copies the MrEd executable.

If the embedded module refers statically (i.e., through require) to modules in MzLib or other collections, then those modules are also included in the embedding executable.

Library modules that are referenced dynamically -- through eval, load, or dynamic-require -- are not automatically embedded into the created executable, but they can be explicitly included using mzc's --lib flag.

The --exe and --gui-exe flags work only with module-based programs. The library in the compiler collection provides a more general interface to the embedding mechanism.

5.2  Stand-Alone Executables from Native Code

Creating a stand-alone executable that embeds native code from mzc requires downloading the MzScheme source code and using a C compiler and linker directly.

To build an executable with an embedded MzScheme engine:

  • Download the source code from and compile MzScheme.

  • Recompile MzScheme's main.c with the preprocessor symbol STANDALONE_WITH_EMBEDDED_EXTENSION defined. Under Unix, the Makefile distributed with MzScheme provides a target ee-main that performs this step.

    The preprocessor symbol causes MzScheme's startup code to skip command line parsing, the user's initialization file, and the read-eval-print loop. Instead, the C function scheme_initialize is called, which is the entry point into mzc-compiled Scheme code. After compiling main.c with STANDALONE_WITH_EMBEDDED_EXTENSION defined, MzScheme will not link by itself; it must be linked with objects produced by mzc.

  • Compile each Scheme source file in the program with mzc's -o or --object flag and the --embedded flag, producing a set of .kp files and object (.o or .obj) files.

  • After each Scheme file is compiled, run mzc with the -g or --link-glue and the --embedded flag, providing all of the .kp files and object files on the command line. (Put the object files in the order that they should be ``loaded.'') The -g or --link-glue step produces a new object file, _loader.o or _loader.obj.

    Each of the Scheme source files in the program must have a different base name (i.e., the file name without its directory path or extension), otherwise _loader cannot distinguish them. The files need not reside in the same directory.

  • Link all of the mzc-created object files with the MzScheme implementation (having compiled main.c with STANDALONE_WITH_EMBEDDED_EXTENSION defined) to produce a stand-alone executable.

    Under Unix, the Makefile distributed with MzScheme provides a target ee-app that performs the final linking step. To use the target, call mzmake with a definition for the makefile macro EEAPP to the output file name, and a definition for the makefile macro EEOBJECTS to to the list of mzc-created object files. (The example below demonstrates how to define makefile variables on the command line.)

For example, under Unix, to create a standalone executable MyApp that is equivalent to

mzscheme -mv -f -f

unpack the MzScheme source code and perform the following steps:

cd plt/src/mzscheme
./mzmake ee-main
mzc --object --embedded
mzc --object --embedded
mzc --link-glue --embedded file1.o file2.o
./mzmake EEAPP=MyApp EEOBJECTS="file1.o file2.o _loader.o" ee-app

To produce an executable that embeds the MrEd engine, the procedure is essentially the same; MrEd's main file is mrmain.cxx instead of main.c. See the compilation notes in the MrEd source code distribution for more information.