#
Chapter 5
Building and Distributing Stand-alone Executables

For all compilation modes, the output of `mzc` relies on MzScheme (and MrEd) to provide run-time support to the compiled code. However, `mzc` can also package code together with its run-time support to form an executable that works on the source machine or a package that can be distributed to other machines.

## 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. (Under Unix, the embedding executable is actually a copy of a wrapper executable.) The created executable invokes the embedded module on startup. The `--gui-exe` flag is similar, but it 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.

Example:

`mzc `--gui-exe` hello hello.ss`

Under Windows, this command produces `hello.exe`, which runs the same as invoking the `hello.ss` module. Under Mac OS X, the resulting executable is an application `hello.app`.

A stand-alone executable is ``stand-alone'' in the sense that you can run it without starting MzScheme, MrEd, or DrScheme. However, the executable depends on MzScheme and/or MrEd shared libraries. The executable can be packaged with support libraries to create a distribution, as described in the following section.

## 5.2 Distributing Stand-Alone Executables

The command-line flag `--exe-dir` directs `mzc` to combine a stand-alone executable (created via `--exe` or `--gui-exe`) with all of the shared libraries that are needed to run it. The resulting package can be moved to other machines that run the same operating system.

After the `--exe-dir` flag, supply a directory to contain the combined files for a distribution. Each command-line argument is an executable to include in the distribution, so multiple executables can be packaged together:

Example:

`mzc `--exe-dir` geetings hello.exe goodbye.exe`

Under Windows, this example creates a directory `greetings` (if the directory doesn't exist already), and it copies the executables `hello.exe` and `goodbye.exe` into `greetings`. It also creates a `lib` sub-directory in `greetings` to contain DLLs, and it adjusts the copied `hello.exe` and `goodbye.exe` to use the DLLs in `lib`.

The layout of files within a distribution directory is platform-specific:

- Under Windows, executables are put directly into the distribution directory, and DLLs go into a `lib` sub-directory.

- Under Mac OS X, `--gui-exe` executables go into the distribution directory, `--exe` executables go into a `bin` subdirectory, and frameworks (i.e., shared libraries) go into a `lib` sub-directory. As a special case, if the distribution has a single `--gui-exe` executable, then the `lib` directory is hidden inside the application bundle.

- Under Unix, executables go into a `bin` subdirectory, shared libraries (if any) go into a `lib` subdirectory, and wrapped executables are placed into a `lib/plt` subdirectory with version-specific names. This layout is consistent with Unix installation conventions; the version-specific names for shared libraries and wrapped exectuables means that distributions can be safely unpacked into a standard place on target machines without colliding with an existing PLT Scheme installation or other executables created by `mzc`.

A distribution also has a `collects` directory that is used as the main library collection directory for the packaged executables. By default, the directory is empty. Use the `++copy-collects` flag to supply a directory whose content is copied into the distribution's `collects` directory. The `++copy-collects` flag can be used multiple times to supply multiple directories.

When multiple executables are disrtibuted together, then separately creating the executables with `--exe` and `--gui-exe` can generate multiple copies of collection-based libraries that are used by multiple executables. To share the library code, instead, specify a target directory for library copies using the `--collects-dest` flag with `--exe` and `--gui-exe`, and specify the same directory for each executable (so that the set of libraries used by all executables are pooled together). Finally, when packaging the distribution with `--exe-dir`, use the `++copy-collects` flag to include the copied libraries in the distribution.

## 5.3 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 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.