Top
Print

# Building Mozart for Windows

## Leif Kornstaedt

> This manual describes how to build Mozart for Windows. We describe the tools used in the build process and how to obtain them. We explain how to configure and build both the packages Mozart depends upon and Mozart itself. We conclude by a description of how to create an installer, should you want to do so.

# 1 Setting up the Build Environment

Cygwin

From Version 1.2.1, Mozart can be built natively under Windows using the Cygwin environment. Cygwin is a Unix environment for Windows. In particular, it provides a C++ compiler (gcc), a Bourne-compatible shell (bash), and all the usual Unix command line tools. Cygwin can be obtained for free at http://www.cygwin.com/.

Take yourself to a Windows machine (Windows XP Professional, Windows 2000 or Windows NT 4 are preferred, though others may work) and install Cygwin (full installation preferred), then start a shell. Make sure that `uname -r` displays at least version 1.3.5. It is a good idea that you familiarize yourself with this environment, as you'll be using it for a while before your Mozart build is finished. I recommend that you read the ``Cygwin User's Guide''.

Cygwin Basics

As you will have seen on the Cygwin web site, Cygwin actually consists of two parts: A DLL providing a significant part of the Unix API, and a collection of tools. The tools we need, the DLL we do not want. By default, all executables created by gcc require the Cygwin DLL (`cygwin1.dll`). This DLL provides the Unix emulation functionality, such as support for Cygwin-style file names (you do not know what this is? Read the User's Guide!) and mount points. If we built Mozart against this DLL, then we would need to ship it with Mozart (so that Mozart works on systems which do not have Cygwin installed). We do not want to ship it, and we do not need the Unix emulation, and we want to be a ``native'' Windows application, so we will use the `-mno-cygwin` flag to gcc throughout the build process. This flag in fact instructs gcc to act as a cross-compiler: the host environment being Windows with Cygwin, the target environment being native Windows. This cross-compiler is called MinGW, which is also available as a standalone product and as a cross-compiler hosted on Linux.

Headers and Libraries

Object files and libraries built for Cygwin do not work with object files and libraries built for MinGW. Instead of the header files in `/usr/include/` and the libraries in `/usr/lib/`, `gcc -mno-cygwin` therefore uses the header files from `/usr/include/mingw/` and the libraries from `/usr/lib/mingw/`. Instead of the Cygwin DLL, MinGW links executables against the Microsoft Visual C/C++ Runtime (`msvcrt.dll`), which we can redistribute with Mozart.

Mozart requires several packages. Even though some of these are provided with Cygwin, they are built for Cygwin, and we need them built for MinGW. So before we can actually start on the Mozart sources, we will build these additional packages. Thankfully we need to do this only once.

# 2 Acquiring the Required Packages

Package Directory

We will install all our packages in a new directory we create especially for them. Say this directory is `/opt/packages`. Whatever it is, we will refer to it as packages throughout this document. Furthermore, we populate the packages directory with the following subdirectories:

Directory | Purpose
--- | ---
`dlls` | For the Dynamically Linked Libraries (DLLs).
`include` | For the packages' C/C++ header files (`.h`).
`lib` | For the libraries (`.a`).

Furthermore, we create a separate directory for the builds, for example, `/tmp/build`. We will refer to this as build.

Required Packages

The following table lists the packages we need, along with their versions and the place where they can be downloaded.

Package | Version | Location
--- | --- | ---
GNU MP | 3.1.1 | `ftp://ftp.gnu.org/pub/gnu/gmp/gmp-3.1.1.tar.gz`
zlib | 1.1.3 | `http://www.gzip.org/zlib.tar.gz`
Tcl/Tk | 8.3.3 | `http://aspn.activestate.com/ASPN/Downloads/ActiveTcl/`
GDBM | 1.8.0 | `ftp://ftp.gnu.org/pub/gnu/gdbm/gdbm-1.8.0.tar.gz`
regex | 0.12 | `ftp://ftp.gnu.org/pub/gnu/regex/regex-0.12.tar.gz`

Note that these are all source packages except for Tcl/Tk. You'll soon find out why.

Build Flags

The remainder of this chapter will use CFLAGS to indicate a meaningful set of flags for the C/C++ compilers. For instance, you can use the following, which we used for the last releases:

> `-mno-cygwin -O3 -fomit-frame-pointer -march=i586 -mcpu=i686`

It is imperative that you include `-mno-cygwin`!

A Note for the Lazy

There's some good news: If you are lazy enough that you would trust the packages I built, you can just obtain a copy of my packages directory from `ftp://ftp.mozart-oz.org/pub/mozart/extras/packages.tgz` and skip most of the following sections (in fact, all but those about the msvcrt and Emacs). Be sure to adapt the included `tclConfig.sh` and `tkConfig.sh` files to reflect your system's paths!

## 2.1 Microsoft Visual C++ Runtime

This one is easy: You already have it! It is located in `$SYSTEMROOT/system32/` (at least under Windows 2000; if you're running 9x, then you'll have to locate it yourself). So we just copy it to our packages`/dlls` directory:

> `cp $SYSTEMROOT/system32/msvcrt.dll` packages`/dlls`

## 2.2 GNU MP

Unpack it, configure it, build it, and install it thus:

> `cd` build`
> tar zxvf gmp-3.1.1.tar.gz
> cd gmp-3.1.1
> ./configure --prefix=`packages`--disable-shared CFLAGS="`CFLAGS`"
> make
> make install`

You should end up with the following files:

packages`/include/gmp.h`
packages`/lib/libgmp.a`

## 2.3 zlib

Unpack it, configure it, build it, and install it thus:

> `cd` build`
> tar zxvf zlib-1.1.3.tar.gz
> cd zlib-1.1.3
> CFLAGS="`CFLAGS`" ./configure --prefix=`packages`
> make
> make install`

You should end up with the following files:

packages`/include/zlib.h`
packages`/include/zconf.h`
packages`/lib/libz.a`

## 2.4 Tcl/Tk

Install your Tcl/Tk distribution (for example, ActiveTcl). Copy the following files and directories from the installed location:

packages`/include/tcl.h`
packages`/include/tclDecls.h`
packages`/include/tk.h`
packages`/include/tkDecls.h`
packages`/include/X11/*`
packages`/lib/tk8.3/*`
packages`/lib/tcl8.3/*`
packages`/dlls/tcl83.dll`
packages`/dlls/tclpip83.dll`
packages`/dlls/tk83.dll`

Unfortunately, Windows Tcl/Tk distributions come without the all-important `tclConfig.sh` and `tkConfig.sh` files, which we therefore have to create manually (directly in the packages directory). `tclConfig.sh` should have the following contents:

> `# tclConfig.sh --
> TCL_VERSION='8.3'
> TCL_PREFIX='`packages`'
> TCL_LIBS=''
> TCL_LIB_SPEC='`packages`/dlls/tcl83.dll'`

Whereas `tkConfig.sh` ought to look like this:

> `# tkConfig.sh --
> TK_VERSION='8.3'
> TK_PREFIX='`packages`'
> TK_LIBS=''
> TK_LIB_SPEC='`packages`/dlls/tk83.dll'
> TK_XINCLUDES=''`

(Don't forget to substitute your actual packages directory for packages in these files!)

## 2.5 GDBM

Unpack it thus:

> `cd` packages`
> tar zxvf gdbm-1.8.0.tar.gz
> cd gdbm-1.8.0`

GDBM does not compile out-of-the-box for MinGW, so we have to apply a patch. Copy the file gdbm-1.8.0-patch.diff, then patch it, configure it, build it, and install it thus:

> `patch < gdbm-1.8.0-patch.diff
> CFLAGS="`CFLAGS`" ./configure --disable-shared
> make CFLAGS="`CFLAGS`"
> make prefix=`packages`install`

You should end up with the following files:

packages`/include/gdbm.h`
packages`/lib/libgdbm.a`

## 2.6 regex

Unpack it thus:

> `cd` packages`
> tar zxvf regex-0.12.tar.gz
> cd regex-0.12`

Like GDBM, the regex package needs a patch regex-0.12-patch.diff. Patch the package, configure it, build it, and install it thus:

> `patch < regex-0.12-patch.diff
> CFLAGS="`CFLAGS`" ./configure --prefix=`packages`
> make CFLAGS="`CFLAGS`"
> make prefix=`packages`install`

You should end up with the following files:

packages`/include/regex.h`
packages`/lib/libregex.a`

## 2.7 Emacs

You need an installed Emacs. You can get it at `http://www.gnu.org/software/emacs/windows/`. Unpack it somewhere, for example to `/cygdrive/c/Program\ Files/` and execute the `addpm.exe` binary in the `bin` subdirectory. We will refer to the directory where Emacs is installed as emacs.

# 3 Building Mozart

Now we can get to the real thing. Retrieve the sources from the CVS:

> `cvs -d cvs.mozart-oz.org:/services/mozart/CVS get mozart
> cvs -d cvs.mozart-oz.org:/services/mozart/CVS get mozart-stdlib`

(specify `-r mozart-1-2-0-fixes` to get the fixes branch). See http://www.mozart-oz.org/download/cvs.html for details about anonymous CVS. Let mozart be the directory created by the first `cvs get` command and stdlib the one created by the second.

Environment Variables

We need to start with a clean `PATH`, which in particular must not contain any Mozart installation. The following works on my system:

> `export PATH=/usr/bin:/bin:` emacs`/bin:/cygdrive/c/WINNT/system32:/cygdrive/c/WINNT`

Furthermore, we want to tell the configuration scripts where we placed our Windows DLLs:

> `export windlldir=`packages`/dlls`

The Fun Part

Say we want to install Mozart into directory install. Then we can configure, build, and install Mozart as follows:

> `cd` build`
> mkdir mozart-build
> cd mozart-build
> `mozart`/configure --prefix=`install`\
> --with-inc-dir=`packages`/include \
> --with-lib-dir=`packages`/lib \
> --with-tcl=`packages`\
> --with-tk=`packages`\
> --disable-contrib-compat \
> --with-stdlib=`stdlib`
> make bootstrap
> make install`

A note on the configuration options: Most of these should be clear, they simply convey to the configuration scripts the knowledge of where we placed our packages. We have to disable the `compat` contrib because it does not build in bootstrap mode (yet). This is why we have to build it separately once we have our installed system:

> `cd` build`
> mkdir compat-build
> cd compat-build
> export PATH=`install`/bin:$PATH
> `mozart`/contrib/compat/configure --prefix=`install`
> mkdir share
> cp` build`/mozart-build/share/Makefile.boot share
> make
> make install`

And yeah, verily, thus and so - we're done.

Using Mozart

To use Mozart, you simply have to extend your `PATH`:

> `export PATH=`install`/bin:$PATH`

Then you can start `oz`, `ozc` and so on, as you would expect.

# 4 Building Documentation

Documentation currently cannot be built under Windows alone. Luckily, this step is optional. If you don't do it, then you simply have a system without documentation, but it runs.

For Windows, we deliver documentation not as a big bunch of HTML files, but as an HTML Help file (also called a CHM file). HTML Help files provide full-text search capabilities, a full table of contents, and are much smaller than all the HTML sources. This section explains how to obtain this file. Take yourself to a Unix machine and say something like:

> `unset OZHOME OZPATH OZEMULATOR TEXT2PICKLE
> export PATH=/opt/gcc-2.95.3/bin:/opt/jdk/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/local/bin
> mkdir /tmp/build
> cd /tmp/build
> `mozart`/configure --prefix=`linux-install`\
> --with-documents=all --enable-chm --with-stdlib=`stdlib`
> make bootstrap
> make install`

where linux-install is a directory different from the install directory. Get back to your Windows machine and do:

> `cd` linux-install`/doc
> /cygdrive/c/Program\ Files/HTML\ Help\ Workshop/hcc Mozart`

(assuming that you have linux-install on a network shared file system. If not, you'll have to somehow copy this directory to your Windows machine). `hhc` is the HTML Help Compiler from Microsoft's HTML Help Workshop, available freely for download at `http://msdn.microsoft.com/library/en-us/htmlhelp/html/hwMicrosoftHTMLHelpDownloads.asp`. The current version is 1.31. (If the URL is invalid, search Microsoft's site for ``download html help workshop''. It seems Microsoft tends to reorganize every so often.)

This process will leave behind a file `Mozart.chm`, which we can copy to a sensible place:

> `cp Mozart.chm` install`/doc`

If you want, you can delete from the install`/doc` directory all files except `Mozart.chm` and the `demo/applets` directory.

# 5 Creating an Installer

Windows applications are typically distributed as an installer, which not only creates the file system structure, but also adds the command line tools to the `PATH`, creates Start Menu entries, and establishes associations for file extensions (in our case, `.oz` and `.ozg` files are associated with `oz.exe`, and `.oza` files are associated with `ozenginew.exe`). Installers also provide a clean way of removing applications from your system. The only reason I see why you would want to remove Mozart is to install a new release.

Creating an installer is not necessary if you do not plan to redistribute your Mozart build. You can run Mozart from your install directory directly.

We build our installer with InstallShield Developer, which you can purchase (yes, these things cost real money!) on InstallShield's Web site at `http://www.installshield.com/isd/`. Start up InstallShield Developer and open the project mozart`/misc/Mozart.ism`. Under ``Advanced Views - Path Variables'' you have to adjust some variables:

Path Variable | Purpose
--- | ---
SYSTEMROOT | Directory where `hhc.exe` resides, normally `C:\WINNT`.
Base | Directory where you installed Mozart (called install above, but in Windows syntax here).

Release Adjustments

When making a new release, you want the installer to document which Mozart version it installs. Therefore, take care to set the following properties correctly. Navigate to ``Organize Your Setup - General Information - Summary Information Stream'' and update the ``Title'' field. It is imperative that you generate a new GUID (Globally Unique Identifier) for the package that you're going to create: Select the ``Package Code'' field and click on the ``Generate GUID'' button. Next, find ``Product Properties'' (also under ``General Information'') and update the ``Product Version'' field.

Check Files

Before building, you should make sure that you didn't screw up and actually have all the files you need (and none you don't want). Run `cd` install`&& find . -type f | sort` and `diff` the result with the file `FILES`, which contains a list of all the files.

Building

Now you're clear to build the release. Start the ``Build - Release Wizard'' and select your options. Choose a ``Product Configuration'' and a ``Release Name'' at random; it's fine to just accept the defaults. Click ``Next'' until you can set the ``Media Type'' to ``Network Image''. Next, select ``Compress all files''. From Release 1.2.3, we deliver Mozart both as an `EXE` and as an `MSI`, for the convenience of people who know that they already have Windows Installer on their machine - the only difference in the Release Wizard is whether you select ``Create installation launcher'' or not. A couple of questions later, you can actually get the beast to work.

The End

Congratulations! You're the proud owner of a Mozart installer!