#
Chapter 5
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 `embed.ss` 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 `http://www.drscheme.org/` 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` file1.ss `-f` file2.ss`

unpack the MzScheme source code and perform the following steps:

`cd plt/src/mzscheme`
`./mzmake`
`./mzmake ee-main`
`mzc `--object` `--embedded` file1.ss`
`mzc `--object` `--embedded` file2.ss`
`mzc `--link-glue` `--embedded` file1.kp file1.o file2.kp 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.