O'Caml for iOS (O'Caml on iPod Touch/iPad/iPhone)

News (2010-11-09)

Jonathan Kimmitt created a pretty GUI frontend for iPad and it is now available on AppStore!

Build Instruction

1. Requirements

You need a working toolchain (gcc and binutils) for iOS (iPod Touch/iPad/iPhone).
For example, you can use the official iOS SDK.
In addition, in order to run your O'Caml programs, you need the iPhone Simulator of SDK, registered iOS devices, or jailbroken iOS devices.

2. Prepare sources

Obtain the O'Caml source tarball and patch it with the patch for cross-compiling O'Caml and the patch for supporting ARM on iOS.
In addition, in order to cross-compile O'Caml, you need ocamlrun, ocamlyacc dllunix.so and dllstr.so of exactly the same version on your host machine.
The simplest (but not so smart) way is to prepare two source trees and build host O'Caml runtime and tools on one tree, and target ones on another tree.

Example:
% wget http://caml.inria.fr/pub/distrib/ocaml-3.12/ocaml-3.12.0.tar.gz
% tar xzf ocaml-3.12.0.tar.gz
% cp -a ocaml-3.12.0 ocaml-3.12.0.host
% cd ocaml-3.12.0
% patch -p1 < ../cross-ocaml-3.12.0-001.diff
% patch -p1 < ../arm-iOS-ocaml-3.12.0-001.diff
% cd ../ocaml-3.12.0.host
(* build as usual *)

3. Configure

You need to specify the host type (e.g., arm-apple-darwin10) and your cross-compile toolchains explicitly.

% cd ../ocaml-3.12.0
% ./configure (* your options [prefix, libdir, and so on] *) -host arm-apple-darwin10 -cc (* your cross-gcc *) -as (* your cross-as) -aspp (* your cross-aspp*) -partialld (* your cross-ld *)

(* More concrete example (on Mac OS X v10.6.4):
% export ACC="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-gcc-4.2.1 -I/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk/usr/lib/gcc/arm-apple-darwin10/4.2.1/include/ -I/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk/usr/include/ -isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.0.sdk"
% ./configure -prefix /var/mobile/ocaml-3.12.0 -host arm-apple-darwin10 -cc "$ACC" -as "$ACC -c" -aspp "$ACC -c" -partialld "/Developer/Platforms/iPhoneOS.platform//Developer/usr/bin/ld -r"
*)

4. Build

The build process should fail several times.
First, it stops because cross-ocamlrun cannot be run on your host machine. To solve the problem, you need to replace byterun/ocamlrun with the host ocamlrun. Be careful not to overwrite the cross-ocamlrun.
Second, it stops because cross-ocamlyacc cannot be run on your host machine. To solve the problem, you need to replace yacc/ocamlyacc with the host ocamlyacc.
Third, it fails in building ocamlbuild. To solve the problem, you need to replace otherlibs/unix/dllunix.so with the host dllunix.so.
Finally, it fails in building ocamldoc. To solve the problem, you need to replace otherlibs/str/dllcamlstr.so with the host dllcamlstr.so.

% make world

(* ... skip .. *)

/bin/sh: ../boot/ocamlrun: Bad CPU type in executable
make[2]: *** [pervasives.cmi] Error 126
make[1]: *** [coldstart] Error 2
make: *** [world] Error 2
% mv byterun/ocamlrun byterun/ocamlrun.target
% cp ../ocaml-3.12.0.host/byterun/ocamlrun byterun/ocamlrun
% make world

(* ... skip .. *)

boot/ocamlyacc -v parsing/parser.mly
make[1]: boot/ocamlyacc: Bad CPU type in executable
make[1]: *** [parsing/parser.ml] Error 1
make: *** [world] Error 2
% mv yacc/ocamlyacc yacc/ocamlyacc.target
% cp ../ocaml-3.12.0.host/yacc/ocamlyacc yacc/ocamlyacc
% make world

(* ... skip .. *)

Error: Error on dynamically loaded library: ../otherlibs/unix/dllunix.so: dlopen(../otherlibs/unix/dllunix.so, 138): no suitable image found. Did find:
../otherlibs/unix/dllunix.so: mach-o, but wrong architecture
Exit code 2 while executing this command:
../ocamlcomp.sh unix.cma -g -I stdlib -I ../otherlibs/unix ocamlbuild/ocamlbuild_pack.cmo ocamlbuild/ocamlbuild_executor.cmo ocamlbuild/ocamlbuild_unix_plugin.cmo ocamlbuild/ocamlbuild.cmo -o ocamlbuild/ocamlbuild.byte
make[1]: *** [ocamlbuild.byte] Error 2
make: *** [world] Error 2
% mv otherlibs/unix/dllunix.so otherlibs/unix/dllunix.so.target
% cp ../ocaml-3.12.0.host/otherlibs/unix/dllunix.so otherlibs/unix/dllunix.so
% make world

(* ... skip .. *)

../ocamlcomp.sh -o ocamldoc -linkall unix.cma str.cma dynlink.cma -I ../parsing -I ../utils -I ../typing -I ../driver -I ../bytecomp -I ../tools -I ../toplevel/ -I ../stdlib -I ../otherlibs/str -I ../otherlibs/dynlink -I ../otherlibs/unix -I ../otherlibs/num -I ../otherlibs/graph -nostdlib ../parsing/printast.cmo ../typing/ident.cmo ../utils/tbl.cmo ../utils/misc.cmo ../utils/config.cmo ../utils/clflags.cmo ../utils/warnings.cmo ../utils/ccomp.cmo ../utils/consistbl.cmo ../parsing/linenum.cmo ../parsing/location.cmo ../parsing/longident.cmo ../parsing/syntaxerr.cmo ../parsing/parser.cmo ../parsing/lexer.cmo ../parsing/parse.cmo ../typing/types.cmo ../typing/path.cmo ../typing/btype.cmo ../typing/predef.cmo ../typing/datarepr.cmo ../typing/subst.cmo ../typing/env.cmo ../typing/ctype.cmo ../typing/primitive.cmo ../typing/oprint.cmo ../typing/printtyp.cmo ../typing/includecore.cmo ../typing/typetexp.cmo ../typing/typedtree.cmo ../typing/parmatch.cmo ../typing/stypes.cmo ../typing/typecore.cmo ../typing/includeclass.cmo ../typing/typedecl.cmo ../typing/typeclass.cmo ../typing/mtype.cmo ../typing/includemod.cmo ../typing/typemod.cmo ../bytecomp/lambda.cmo ../bytecomp/typeopt.cmo ../bytecomp/printlambda.cmo ../bytecomp/switch.cmo ../bytecomp/matching.cmo ../bytecomp/translobj.cmo ../bytecomp/translcore.cmo ../bytecomp/translclass.cmo ../tools/depend.cmo odoc_config.cmo odoc_global.cmo odoc_messages.cmo odoc_types.cmo odoc_misc.cmo odoc_text_parser.cmo odoc_text_lexer.cmo odoc_text.cmo odoc_name.cmo odoc_parameter.cmo odoc_value.cmo odoc_type.cmo odoc_exception.cmo odoc_class.cmo odoc_module.cmo odoc_print.cmo odoc_str.cmo odoc_args.cmo odoc_comments_global.cmo odoc_parser.cmo odoc_lexer.cmo odoc_see_lexer.cmo odoc_env.cmo odoc_merge.cmo odoc_sig.cmo odoc_ast.cmo odoc_control.cmo odoc_inherit.cmo odoc_search.cmo odoc_scan.cmo odoc_cross.cmo odoc_comments.cmo odoc_dep.cmo odoc_analyse.cmo odoc_info.cmo odoc_dag2html.cmo odoc_to_text.cmo odoc_ocamlhtml.cmo odoc_html.cmo odoc_man.cmo odoc_latex_style.cmo odoc_latex.cmo odoc_texi.cmo odoc_dot.cmo odoc.cmo
File "_none_", line 1, characters 0-1:
Error: Error on dynamically loaded library: ../otherlibs/str/dllcamlstr.so: dlopen(../otherlibs/str/dllcamlstr.so, 138): no suitable image found. Did find:
../otherlibs/str/dllcamlstr.so: mach-o, but wrong architecture
make[2]: *** [ocamldoc] Error 2
make[1]: *** [ocamldoc] Error 2
% mv otherlibs/str/dllcamlstr.so otherlibs/str/dllcamlstr.so.target
% cp ../ocaml-3.12.0.host/otherlibs/str/dllcamlstr.so otherlibs/str/dllcamlstr.so
% make world
% make opt

5. Run

Now you have ocamlrun.target (the runtime) and ocamlopt (the cross compiler). To test the runtime, copy ocamlrun.target (the runtime), ocaml (the interpreter) and the libraries to your iPhone/iPod Touch, and test them. Be careful about dllunix.so and dllcamlstr.so because they are replaced with the native ones in the above instruction. If they work, install the runtime and libraries.

Download

Patch for cross-compiling O'Caml 3.12.0 (last update: 2010-09-11. Other versions)
Patch for supporting ARM on iOS for O'Caml 3.12.0 (last update: 2010-09-11. Other versions)

Applications


Limitations

1. GUI


TODO


Notice

Be carefull not to cross the line.
Toshiyuki Maeda
tosh @ is.s.u-tokyo.ac.jp
../