O'Caml on iPhone (O'Caml on iPod Touch)

Build Instruction

1. Requirements

You need a working toolchain (gcc and binutils) for iPhone/iPod Touch.
For example, you can refer the instruction of building the toolchain provided by iphonedevonlinux people.
Finally, you need a jailbroken iPhone/iPod Touch, of course.

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 iPhone OS 2.X.
In addition, in order to cross-compile O'Caml, you need native (32-bit) version of ocamlrun, ocamlyacc dllunix.so and dllstr.so of exactly the same version.
The simplest (but not so smart) way is to prepare two source trees and build host O'Caml runtime and build tools on one tree on a 32-bit environment, and target ones on another tree.
Example:
% wget http://caml.inria.fr/pub/distrib/ocaml-3.10/ocaml-3.10.2.tar.gz
% tar xzf ocaml-3.10.2.tar.gz
% cp -a ocaml-3.10.2 ocaml-3.10.2.host
% cd ocaml-3.10.2
% patch -p1 < ../cross-ocaml-3.10.2-001.diff
% patch -p1 < ../arm-macosx-ocaml-3.10.2-002.diff
% cd ../ocaml-3.10.2.host
(* build as usual *)

3. Configure

You need to specify the host type (arm-apple-darwin9) and cross-compile toolchains explicitly.
While configuration, you will be asked several questions from the configure script.
In addition, you need to remove graph from the variable "OTHERLIBRARIES" in config/Makefile because X11 is not available.
% cd ../ocaml-3.10.2
% ./configure (* your options [prefix, libdir, and so on] *) -host arm-apple-darwin9 -cc (* your cross-gcc *) -ranlib (* your cross-ranlib) -ar (* your cross-ar*) -aspp (* your cross-gcc *) -ld (* your cross-ld *)

(* ... skip .. *)

Unable to compile the test program.
Make sure the C compiler (* your cross-gcc *) -O is properly installed.
Press <enter> to proceed or <interrupt> to stop.
(* Just hit Enter key *)

(* ... skip .. *)

Input sizeof(int) sizeof(long) sizeof(long *) sizeof(short)
4 4 4 2

(* ... skip .. *)

Is 64-bit integer supported? (y/n: default y)
(* Just hit Enter key *)

What is the type of signed 64-bit integer? (example: long long)
long long

What is the type of unsigned 64-bit integer? (example: unsigned long long)
unsigned long long

What is the printf format? (example: "ll")
"ll"

(* ... skip .. *)

Something went wrong during endianness determination.
You'll have to figure out endianness yourself
Is this a big-endian architecture? (y/n: default n)
(* Just hit Enter key *)

(* ... skip .. *)

Should doubles be doubleword-aligned? (y/n: default: y)
n

(* ... skip .. *)

Should 64-bit integers be doubleword-aligned? (y/n: default: y)
n

(* ... skip .. *)

Do native division and modulus have round-towards-zero semantics? (y/n: default y)
(* Just hit Enter key *)

(* ... skip .. *)

% vi config/Makefile
(* remove graph from the variable OTHERLIBRARIES, if any. *)

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/dllstr.so with the host dllstr.so.
% make world

(* ... skip .. *)

/bin/sh: ../boot/ocamlrun: cannot execute binary file
make[1]: *** [pervasives.cmi] Error 126
make[1]: Leaving directory `/work/tosh/port_caml/ocaml-3.10.2/stdlib'
make: *** [coldstart] Error 2
% mv byterun/ocamlrun byterun/ocamlrun.target
% cp ../ocaml-3.10.2.host/byterun/ocamlrun byterun/ocamlrun
% make world

(* ... skip .. *)

boot/ocamlyacc: boot/ocamlyacc: cannot execute binary file
make: *** [parsing/parser.ml] Error 126
% mv yacc/ocamlyacc yacc/ocamlyacc.target
% cp ../ocaml-3.10.2.host/yacc/ocamlyacc yacc/ocamlyacc
% make world

(* ... skip .. *)

Error on dynamically loaded library: ../otherlibs/unix/dllunix.so: ../otherlibs/unix/dllunix.so: invalid ELF header
Exit code 2 while executing this command:
boot/ocamlrun ./ocamlc -nostdlib unix.cma -g -I stdlib -I ../otherlibs/unix ocamlbuild/ocamlbuild_pack.cmo ocamlbuild/executor.cmo ocamlbuild/my_unix_with_unix.cmo ocamlbuild/ocamlbuild.cmo -o ocamlbuild/ocamlbuild.byte
make: *** [ocamlbuild.byte] Error 2
% mv otherlibs/unix/dllunix.so otherlibs/unix/dllunix.so.target
% cp ../ocaml-3.10.2.host/otherlibs/unix/dllunix.so oterlibs/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 ../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
Error on dynamically loaded library: ../otherlibs/str/dllstr.so: ../otherlibs/str/dllstr.so: invalid ELF header
make[1]: *** [ocamldoc] Error 2
make[1]: Leaving directory `/work/tosh/tmp/src/ocaml-3.10.2/ocamldoc'
make: *** [ocamldoc] Error 2
% mv otherlibs/str/dllstr.so otherlibs/str/dllstr.so.target
% cp ../ocaml-3.10.2.host/otherlibs/str/dllstr.so otherlibs/str/dllstr.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 dllstr.so because they are replaced with the native ones in the above instruction.
% scp byterun/ocamlrun.target mobile@(your iPhone address):~/ocamlrun
% scp ocaml mobile@(your iPhone address):~/
% scp stdlib/*.cmi stdlib/*.cma mobile@(your iPhone address):~/
% scp otherlibs/unix/*.cma otherlibs/unix/*.cmi mobile@(your iPhone address):~/
% scp otherlibs/unix/dllunix.so.target mobile@(your iPhone address):~/dllunix.so
% ssh mobile@(your iPhone address)
localhost:~ mobile$ ldid -S ./ocamlrun
localhost:~ mobile$ ./ocamlrun ./ocaml
If they work, install the runtime and libraries.

Download

Patch for cross-compiling O'Caml 3.10.2 (last update: 2008-04-08. Other versions)
Patch for supporting ARM on iPhone 2.X for O'Caml 3.10.2 (last update: 2009-02-13. Other versions)

Applications


Limitations

1. GUI


TODO


Toshiyuki Maeda
tosh @ is.s.u-tokyo.ac.jp
../