Compile OCaml for iOS Simulator

September 7, 2014

OCamlXSim is a version of OCaml that compiles apps for the iOS
Simulator, an iPhone and iPad simulator available from Apple as part of
Xcode. The current version of OCamlXSim is 4.0, based on OCaml 4.01.0.

If you’re not familiar with OCaml, it’s a functional language in the
same family as Haskell, Scala, and (especially) Standard ML. It’s
powerful, flexible, and rigorous. I’ve found programming in OCaml for
iOS to be productive and even delightful.

You can download a prebuilt OCamlXSim package for Mavericks (OS X 10.9)
from this link:

The package installs OCamlXSim under /usr/local/ocamlxsim. It was
built under Mavericks using Xcode 5.1.1, and builds against the iOS 7.1
SDK by default. You can use the compiler with a different SDK version by
specifying the proper -ccopt flags, explained just below under
Test.

If you want more control over the installation and the default SDK, you
can build OCamlXSim from sources as described at the end of the page
under Building from Sources.

The OCamlXSim compiler can be used to develop real-world iOS apps. I did
almost all the development of the GUI for our released app Master
Schnapsen/66 in the iOS Simulator. (The Schnapsen game
engine was developed under Linux.)

Our OCaml Programming page has more resources for doing OCaml
programming for iOS. For example, I’ve released sources for five
illustrative apps (shown in miniature at left) that you can compile and
run on an iOS device or in the iOS Simulator.

If your Simulator program is simple enough, you can actually run it from
the OS X command line by controlling the set of dynamically loaded
libraries. First, set shell variables PLT and SDK. You can cut and
paste the definitions from the xsim-build script.

This most likely indicates that OCamlXSim was built using an iOS SDK
version that is not currently present on your system. This doesn’t
necessarily indicate a problem. For example, the prebuilt OCamlXSim
4.0.1 compiler from Psellos is built using the iPhoneOS 7.1 SDK, but you
may well be using a later Xcode version with a later SDK.

The solution is to specify explicit options to ocamlopt telling it which
SDK version to use. Assuming you’ve set PLT and BIN as above, you
can use the pre-built OCamlXSim 4.0.1 with iPhoneOS Simulator 8.0 SDK as
follows:

Although the SDK options are somewhat painful to specify, it’s probably
best to think of them as part of using OCamlXSim with Apple’s
ever-evolving iOS SDK. A solution that may be better in some cases is to
rebuild OCamlXSim from sources, specifying the new SDK values in
xsim-build.

Further Information

To run a program that actually does something interesting, you need the
richer environment provided by the actual iOS Simulator. The pages
linked here show how to build three different OCaml example apps and run
them in the iOS Simulator:

Gamut is a simple app that displays a small animation in all possible
colors. Voronoi is a more complex app that displays dynamic colored
Voronoi diagrams that you can manipulate through the touch interface.
IcosaBlue shows how to use OpenGL ES—it is packaged to work both in the
simulator and on real iOS devices.

If you’re interested in running OCaml apps on real iOS devices, see the
accompanying note Compile OCaml for iOS. This
note has links to two other sample apps that you can try.

If you have any questions, comments, or corrections, please leave them
below, or email me at jeffsco@psellos.com.

Appendix: Building from Sources

For maximum flexibility, you can build OCamlXSim from sources. This is a
little more complicated than a standard OCaml build, but I’ve created a
shell script that does it for you.

An app running natively on an iOS device is an ARM program. However, an
app running in the iOS Simulator runs as a 32-bit (i386 architecture)
Mac OS X program. In other words, the Simulator doesn’t simulate an iOS
device down to the hardware level. It provides a faithful copy of the
iOS environment, reimplemented to run natively on the Mac.

This means that OCamlXSim needs to be a 32-bit compiler for the i386
architecture, much like the stock 32-bit OCaml compiler for OS X. In
fact, the stock compiler very nearly works. The difficulty is that the
stock OCaml compiler is a native compiler, i.e., it runs in the same
environment as the programs that it compiles. The Simulator environment
is different enough from the standard OS X environment that a native
compiler doesn’t work correctly. So OCamlXSim needs to be built as a
cross compiler. (The simple test statdo, above, shows the basic
problem. I’ve written a blog post iOS Simulator Vs. OS X
that discusses the issue a little more.)

The standard OCaml release isn’t designed to run as a cross compiler, so
it takes a little extra work to build it as one. In essence, the OCaml
build system doesn’t ordinarily need to distinguish between generating
parts of the compiler itself, which we run on OS X, and generating the
runtime, which we want to run in the iOS Simulator.

The trick I’ve used in OCamlXSim is to build two distinct copies of the
OCaml runtime. The first copy is targeted at OS X, and powers the cross
compiler itself. The second copy is targeted at the iOS Simulator, and
powers the apps running in the iOS Simulator. By lucky chance, there are
no parts of the runtime that absolutely need to work independently in
both environments. As a result, the two runtimes can coexist inside a
single OCaml release. (This would not be the case if, for example, I
wanted to support the bytecode interpreter in Simulator apps. For now,
I’m sticking with native code apps.)

Please note that a few of the command lines of the following discussion
are too long to fit on a single line of a typical browser window. In a
lot of cases there is no good place to split them into smaller lines,
usually because of a long filename or URL. Take care that you enter them
as a single line if you are typing them in by hand.

Preliminaries

To develop and run code on the iOS Simulator, you need an installation
of Apple’s Xcode programming environment, which contains the iOS
Simulator as one part. You can download Xcode (for free) from the Mac
App Store. See Apple’s Xcode page for more details. Recent
versions of Xcode contain the traditional Unix command-line tools, which
you will also need to build OCamlXSim. (In earlier versions of Xcode,
the command-line tools were downloaded separately.)

To simplify the command lines below, I’ll define some shell variables as
abbreviations for some of the key paths of development tools. If you’re
following along at the keyboard, you should define them yourself for
later use:

The OCaml native code compiler (ocamlopt) uses an external assembler to
produce its final object files. In the same way, OCamlXSim uses the
assembler of the iOS Simulator platform to produce object files. After
you’ve installed Xcode, you should find an assembler for the iOS
Simulator platform:

This is the assembler OCamlXSim will use, so it must be present. If it
isn’t, check that you’ve installed Xcode (version 5.1 or later). If
you’ve installed it in a non-standard location (other than
/Applications), you’ll need to modify paths accordingly in the
following discussion.

In recent years, Apple has switched from the GNU C compiler gcc to a new
compiler clang, based on LLVM. If you want to build OCamlXSim from
sources, you should have a native C compiler and a C cross compiler for
the Simulator as follows:

Check Out Sources from Repository

You can also check out the sources for OCamlXSim 4.0.1 from Psellos’s
public Subversion repository. This is simpler, but it doesn’t give you
the opportunity to examine the patches separately before applying them.

These sources are identical to what you get if you apply the 4.0.1
patches to the INRIA 4.01.0 release, as above.

Build OCamlXSim

Once you have the sources, you’re ready to build OCamlXSim. The file
xsim-build is a shell script that does the building. You may want to
modify the script before running it. At the beginning of the script are
the following lines:

Desired iOS Simulator SDK version (a subdirectory of PLT—normally, the most recent available).

XSIMTARGET

Where OCamlXSim should be installed.

OSXARCH

Architecture for OS X executables (i386 or x86_64).

The value of XSIMTARGET is a directory where OCamlXSim should be
installed. This location is compiled into the OCamlXSim tools; that is,
they are aware of their own installation location. This is convenient
for finding libraries and such, but it also means that the tools
actually need to be installed in this one specific place. It’s not
possible (or at least not convenient at all) to move them somewhere else
later on.

Ordinarily, xsim-build will create 32-bit (i386 architecture) OS X
executables. This is simplest, because they work on all Intel Macs. If
you want to create 64-bit executables, change the value of OSXARCH to
x86_64. In my initial testing, I’ve found that the 64-bit executables
make compiles go a little faster—but only around 9%.

To build OCamlXSim all in one step:

$ sh xsim-build all > xsim-build.log 2>&1

If things go well, xsim-build.log will contain around 2424 lines of
output, ending with something like this:

If there is a problem, it may be possible to figure out what went wrong
by looking at the error messages in xsim-build.log. It’s also possible
to build OCamlXSim in smaller stages—see the script for details.