Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006266OCamlOCaml generalpublic2013-12-12 11:252015-05-12 16:46
Assigned Todoligez 
PlatformOSOS Version
Product Version 
Target Version4.02.2+dev / +rc1Fixed in Version4.02.2+dev / +rc1 
Summary0006266: Cross compilation for iOs, Android etc
DescriptionI guess that out of box compiling support for mobile platforms like iOs and Android might be a significant stimulus for popularization of language.
Currently mobile market is huge in stlll growing (for instance [^]).

I think that creating lot of bindings for native platforms APIs (like Xamarian did for mono, for instance) is not so important - that is really necessary that:
* cross compilation
* out of box ways to easily build library binary which can be linked to native application code with original platform tools/IDEs.
Attached Filespatch file icon camlrun-4.02.patch [^] (34,937 bytes) 2015-02-12 04:50 [Show Content]
patch file icon camlrun-trunk.patch [^] (33,154 bytes) 2015-02-12 04:50 [Show Content]
diff file icon ocamlrun-fixed.diff [^] (34,228 bytes) 2015-04-30 21:03 [Show Content]
diff file icon camlrun-fixed-2.diff [^] (29,346 bytes) 2015-05-05 22:58 [Show Content]
diff file icon camlrun-fixed-3.diff [^] (20,900 bytes) 2015-05-07 16:39 [Show Content]
diff file icon camlrun-fixed-4.diff [^] (27,151 bytes) 2015-05-08 00:26 [Show Content]
diff file icon camlrun-fixed-5.diff [^] (31,351 bytes) 2015-05-08 22:55 [Show Content]
diff file icon camlrun-fixed-6.diff [^] (31,351 bytes) 2015-05-11 17:00 [Show Content]

- Relationships
related to 0005887resolvedgasche Name clash with memory.h header file with the Android NDK 
parent of 0006861assigneddoligez Do not install native-code executables when cross-compiling 
related to 0006613resolved armv5te code generation bug: shift expression expected -- `subs r0,r3,#4294967296' 
Not all the children of this issue are yet resolved or closed.

-  Notes
gasche (developer)
2013-12-12 14:22

I know nothing at all about cross-compilation, but I think that cross-compilation to android is already possible today, as explained by Jonathan Protzenko in [^] I've also heard about iOS applications implemented in OCaml, see [^] for example.
strobegen (reporter)
2013-12-13 15:48

Yes it all possible now, I also know examples of few games written on Ocaml in iOs App Store (I guess, I was read some time ago article about small team which shipped few game titles to AppStore (not psellos)) but this functionally doesn't included to default compiler, currently only short way to build this kinds of apps for iOs is OCamlXARM ( [^]), I'm not sure but I guess that OCamlXARM contain few patches to original Ocaml distribution related to ARM assembler (& crosscompiling) parts. Therefore my opinion that it will be very useful for Ocaml community if this functionally will be available in default distribution and officially supported:
on OSX: cross compiling to iOs: ARM, ARM64 & Android: ARM.
on Windows: cross compiling to Android ARM,
on Linux: cross compiling to Android ARM.
whitequark (developer)
2014-10-17 06:11

I have started working on proper cross-compilation to Android, and shortly after that I will probably switch to iOS. My goal is to produce small, self-contained patches that can be merged one by one; I will post a patchset shortly. In fact, the amount of work required is not as large as one would expect.
whitequark (developer)
2014-10-17 07:45

I have uploaded three small patches, which allow Android cross-compilation to proceed (both world and world.opt), given that config/{Makefile,m.h,s.h} are provided.

This can be easily tested using:

    opam repo add android [^]
    opam install ocaml-android
    ocamlfind -toolchain android ocamlopt

I will follow up these patches with ones that properly detect the target environment features without running target binaries.
whitequark (developer)
2014-10-17 08:01

Actually, maybe not. I have just realized that my approach is fundamentally flawed while writing out some detailed instructions. Please wait for an updated patchset.
strobegen (reporter)
2014-10-17 09:29

I will try to test when it be ready
whitequark (developer)
2014-12-21 23:12

Reminder sent to: gasche

@gasche, I've attached a patch that brings cross-builds one step closer. Specifically this patch ensures that the variable CAMLRUN, which is already set by the configure script, is actually used when running boot/ binaries, freshly built binaries, and is also embedded in the shebang line in all the built tools.

It also replaces some usage of gcc with $(CC).
gasche (developer)
2014-12-27 08:50

Applying the patch makes "make world.opt" fail on my machine at the following point:

make ocamlc.opt
make[2]: Entering directory `/home/gasche/Prog/ocaml/github-trunk'
/home/gasche/Prog/ocaml/github-trunk/boot/ocamlrun ./ocamlopt -nostdlib -I stdlib -I otherlibs/dynlink -use-runtime /home/gasche/Prog/ocaml/github-trunk/boot/ocamlrun -ccopt "-Wl,-E" -o ocamlc.opt \
  compilerlibs/ocamlcommon.cmxa compilerlibs/ocamlbytecomp.cmxa \
  driver/main.cmx -cclib "-lm -ldl -lcurses -lpthread"
./ocamlopt: unknown option '-use-runtime'.
whitequark (developer)
2014-12-28 23:35
edited on: 2014-12-28 23:36

I've updated the patch. Notable changes:

  * All tools and all Makefile.nt files are also updated. (Some were missing in original patch.)
  * ocamlyacc, being the only other native component except ocamlrun, is also detected with ./configure and required to be present on host for cross-builds.
  * ocamlbuild/Makefile.noboot is removed, as it was never referenced and also ocamlbuild/Makefile does not require ocamlbuild anymore.

make world world.opt now passes.

gasche (developer)
2015-02-08 11:12

The patch seems okay in principle and I was about to merge it, but:

- the patch conflicts with Damien's change to use $(CC) more consistently in trunk@15784 [^]
- Damien only patched trunk, but we may want to apply this one change to 4.02 as well

whitequark, would you mind preparing two versions of the patch, one that applies cleanly to trunk and the other for 4.02. I feel sorry to ask for such tedious work, I could do it but I'll rather try to merge the other patches on my list during my weekend time window.

Damien, could you give your opinion on whether the present change and trunk@15784 are eligible for 4.02+dev?
doligez (administrator)
2015-02-09 17:54

@whitequark if you don't want to bother with two versions of the patch, let's go for 4.02 and I'll deal with the conflicts when I merge it into trunk (after the 4.02.2 release). Or split it into two patches, one for CAMLRUN and one for CC.

I'm a bit nervous with the use of -use-runtime because it precludes using libraries that have C object files, but I guess it's OK for building the compiler.

There is a small problem with the patch: as far as I can tell, it gives the -use-runtime option twice to the compiler (but only in Makefile, not in Makefile.nt). You have to decide whether to add it to OCAMLC or to give it on the command line.

I'm OK for integrating this and trunk@15784 into 4.02.2.
whitequark (developer)
2015-02-12 04:51

I've attached diffs for 4.02 and trunk.

I've fixed the double -use-runtime problem.
gasche (developer)
2015-02-15 22:02

Damien, I just tried to cherry-pick trunk@15784 in 4.02, but:
- it will also conflict (slightly) with PR#5887 so I'd rather wait for PR#5887 to be tested and hopefully picked as well
- I don't understand the interaction between this change and 4.02@15762 ( [^] ); why is -DPROFILING not used in trunk, only in 4.02? Why does byterun/Makefile not use it as well?

My guess would be that -DPROFILING is the right thing to do both in trunk and in byterun/. I can make the change but I'd rather double-check it.
whitequark (developer)
2015-02-27 16:50

whitequark (developer)
2015-03-06 01:38

doligez (administrator)
2015-03-09 20:18
edited on: 2015-03-09 20:25


I fixed it in 4.02 and not trunk because it will get merged eventually, and I don't expect it to cause problems in the meantime.

It's in asmrun and not byterun because byterun doesn't have a set of object files annotated for profiling.

PS. If commit 15762 is bothering you, feel free to overwrite it, it's not important.

doligez (administrator)
2015-04-30 21:03
edited on: 2015-04-30 21:05

I cherry-picked trunk@15784.

Then I tried to apply this patch (the "trunk" one applies cleanly to 4.02) but there is a problem: it breaks the bootstrap. The way you use `-use-runtime` ensures that the compiler always compiles code that runs on the same runtime as the compiler itself. But the bootstrap needs to make an intermediate compiler that runs on the old runtime and generates code for the new runtime.

I think the solution is to replace `-use-runtime ${OCAMLRUN}` with `-use-prims byterun/primitives` for the bootstrap executables (ocamlc, ocamllex, ocamldep) [see new patch]. I checked that it fixes the problem with bootstrapping, but I'm not 100% sure it does what is needed for cross-compilation. Can you check?

whitequark (developer)
2015-05-02 15:50
edited on: 2015-05-02 15:51

No, this of course does not work. The cross-compiling patch uses -use-runtime in order to set the #! field correctly.

With your patch, the /bin looks like this:
$ for i in *; do echo $i `head -n1 $i`; done
ocaml #!/home/whitequark/.opam/4.02.1+32bit/arm-linux-androideabi/bin/ocamlrun
ocamlc #!/home/whitequark/.opam/4.02.1+32bit/arm-linux-androideabi/bin/ocamlrun
ocamlcp #!/home/whitequark/.opam/4.02.1+32bit/bin/ocamlrun
ocamldep #!/home/whitequark/.opam/4.02.1+32bit/arm-linux-androideabi/bin/ocamlrun
ocamllex #!/home/whitequark/.opam/4.02.1+32bit/arm-linux-androideabi/bin/ocamlrun
ocamlmklib #!/home/whitequark/.opam/4.02.1+32bit/bin/ocamlrun
ocamlmktop #!/bin/sh
ocamlobjinfo #!/home/whitequark/.opam/4.02.1+32bit/bin/ocamlrun
ocamlopt #!/home/whitequark/.opam/4.02.1+32bit/arm-linux-androideabi/bin/ocamlrun
ocamloptp #!/home/whitequark/.opam/4.02.1+32bit/bin/ocamlrun
ocamlprof #!/home/whitequark/.opam/4.02.1+32bit/bin/ocamlrun

In order for cross-compilation to be possible, all of these should point to #!/home/whitequark/.opam/4.02.1+32bit/bin/ocamlrun. (I'm especially puzzled by ocamlopt, which is not required for bootstrapping...)

doligez (administrator)
2015-05-05 22:58

For ocamlopt (and ocaml): it's because they are made by the same Makefile as ocamlc.

I think the solution is to use an as-yet undocumented feature of these two options: if you specify both -use-runtime and -use-prims, the list of primitives will come from -use-prims but the runtime path will come from -use-runtime. It works because the bootstrap doesn't care what's in the header, and when you're cross-compiling the lists of primitives are the same so you care only about the header.

Here is a new diff. Please check if it works for cross-compilation.
whitequark (developer)
2015-05-06 00:31

Yup, this works completely! I've imported it in opam-android and I have built the compiler and a few packages, with C extensions and not.

Amazing. Thank you so much for your work on this.
doligez (administrator)
2015-05-06 20:38

Patch applied to branch 4.02 (rev 16093).
doligez (administrator)
2015-05-06 22:47

Except that it doesn't work... I've reverted the patch while we're investigating.
doligez (administrator)
2015-05-07 16:57

Mark Shinwell and I brainstormed about this issue, here are our

Here is why it doesn't work: in normal mode, it sets the absolute path
of `ocamlrun` in the headers of the files that will be installed as
executables. But this absolute path points to the build directory, not
to the final binary directory, so this fails. In the case of
cross-compilation, it sets the path to `ocamlrun`, which is still
incorrect, but happens to work if you have the binary directory in your

What we need is to set the header to the absolute path of the
installed `ocamlrun` as seen on the target machine. And that's what
the makefiles are doing by default: they set it to
`${BINDIR}/ocamlrun`. You just need to make sure that `BINDIR` is a
path on the target machine, not on the host.

Then, if you want to `make install` on the host, you can specify
a pre-prefix for the install with the `DESTDIR` variable.

For example, assuming you want to install in `/usr/local` on the target
and that the target's filesystem is mounted under `/mnt/target` on the
host, you would have:

binary directory on target = /usr/local/bin
                 on host = /mnt/target/local/bin

and you need to use:
  PREFIX=/usr/local (i.e `configure -prefix /usr/local`)
  DESTDIR=/mnt/target (i.e `make install DESTDIR=/mnt/target`)

Then the bytecode file headers will have the correct value:

If the target's filesystem is not mounted on the host, you can choose
any directory you want for `DESTDIR`, and then build a tarball from
the tree installed in that directory.

This is all from analyzing the build procedure and the previous
discussion: we don't have a cross-compilation setup on hand, so I've
prepared a new patch for you to test (camlrun-fixed-3.diff).
whitequark (developer)
2015-05-07 17:02

No, that's wrong. I'm not cross-building the compiler itself! The newly built compiler will be executed on the same machine, and from the same filesystem, as the host compiler.

The reason I need to change ocamlrun at all is that by default, the #! in the newly built compiler points to /its own/ ocamlrun, which is built, like the runtime library is, for the target, and so it cannot be executed on host.
whitequark (developer)
2015-05-07 17:05

Essentially the problem we're running into is that the compiler and the runtime library (and thus ocamlrun) built in the same build tree will be executed on different architectures.
doligez (administrator)
2015-05-07 21:38
edited on: 2015-05-07 21:48

Ah ok I understand now.

Here is a new plan:

- It does not make sense to install the (target) ocamlrun in the same directory as the cross-compiler, so we should install (copy) the host's pre-existing ocamlrun into ${BINDIR} at installation time.

- The compiler's configuration (the camlheader file installed into ${LIBDIR}) should refer to the path of ocamlrun on the target.

- The compiler itself must be built with another version of camlheader, which will refer to ${BINDIR} on the host.

- When cross-compiling, the location of ocamlrun on the target must be specified by the user because there is no other way to determine it.

Does this sound workable?

doligez (administrator)
2015-05-08 00:27

Can you try this new version (camlrun-fixed-4.diff) ?
whitequark (developer)
2015-05-08 07:11

It seems to build correctly but fails at installation:

cd byterun; make install
make[1]: Entering directory '/home/whitequark/.opam/4.02.1+32bit/build/ocaml-android32.4.02.2/byterun'
cp `type -p /home/whitequark/.opam/4.02.1+32bit/bin/ocamlrun` /home/whitequark/.opam/4.02.1+32bit/arm-linux-androideabi/bin/ocamlrun
cp: invalid option -- ':'
Try 'cp --help' for more information.
whitequark (developer)
2015-05-08 07:18

After removing the `type -p ` around the ocamlrun path, everything installs and works, though target ocamlrund and ocamlyacc are still left in the tree, falling short of a fix to PR6861.
doligez (administrator)
2015-05-08 14:53

The purpose of `type -p` is to get the absolute name of the ocamlrun in path. Apparently, type is not as portable as I hoped, but I'm curious: how did it get the full name of your ocamlrun? Did you configure it yourself?

For ocamlyacc, we should probably do the same as for ocamlrun, namely copy the one from the pre-existing install.

For ocamlrund, we should not install it on the host.

I'll make a new patch.
whitequark (developer)
2015-05-08 14:56

The OPAM package supplies a config/Makefile explicitly: [^]
dbuenzli (reporter)
2015-05-08 15:21

@doligez it's always a good idea to have a look at the posix spec. You'll see that the type utility has neither standarized argument options nor standarized a output. [^]
dbuenzli (reporter)
2015-05-08 15:23

`command -p -v` may be a better fit [^]
doligez (administrator)
2015-05-08 22:59

> The OPAM package supplies a config/Makefile explicitly: [^] [^]

I've left the install of ocamlrund for the moment, I'll probably later add a variable to config/Makefile (CROSS_COMPILER=true/false) to handle this.

Can you please check this new version (camlrun-fixed-5.diff)?

@dbuenzli thanks for the advice but I'd already extended the `searchpath` script...
whitequark (developer)
2015-05-09 09:10
edited on: 2015-05-09 09:10

The new patch does not apply at all to the 4.02 branch.

doligez (administrator)
2015-05-11 17:00

I'm sorry, the branch moved under my feet. Here's one that applies cleanly.
shinwell (developer)
2015-05-11 19:11

whitequark: does the new patch work?
whitequark (developer)
2015-05-11 19:20

No, it does not apply.
doligez (administrator)
2015-05-11 19:42

I think I know what's going on. 4.02 is changing, and you're getting the version from the mirror, which is up to 4 hours behind the version I get.

I'll make a GitHub PR, it'll be easier to work with that.
doligez (administrator)
2015-05-11 19:51

Let's continue this discussion (and debugging) at [^] .
doligez (administrator)
2015-05-12 16:46

applied to branch 4.02 (rev 16114)

- Issue History
Date Modified Username Field Change
2013-12-12 11:25 strobegen New Issue
2013-12-12 14:22 gasche Note Added: 0010704
2013-12-13 15:48 strobegen Note Added: 0010706
2014-07-16 14:48 doligez Status new => confirmed
2014-10-16 09:34 xleroy Relationship added related to 0006613
2014-10-17 06:11 whitequark Note Added: 0012386
2014-10-17 06:11 whitequark Relationship added related to 0005887
2014-10-17 07:37 whitequark File Added: 0002-Detect-host-ocamlyacc-alongside-host-ocamlrun-in-con.patch
2014-10-17 07:37 whitequark File Added: 0003-Update-every-invocation-of-ocamlrun-or-ocamlyacc-to-.patch
2014-10-17 07:38 whitequark File Added: 0004-Add-a-CROSS_COMPILING-Makefile.config-flag.patch
2014-10-17 07:45 whitequark Note Added: 0012387
2014-10-17 08:01 whitequark Note Added: 0012388
2014-10-17 08:05 whitequark File Deleted: 0002-Detect-host-ocamlyacc-alongside-host-ocamlrun-in-con.patch
2014-10-17 08:05 whitequark File Deleted: 0003-Update-every-invocation-of-ocamlrun-or-ocamlyacc-to-.patch
2014-10-17 08:05 whitequark File Deleted: 0004-Add-a-CROSS_COMPILING-Makefile.config-flag.patch
2014-10-17 09:29 strobegen Note Added: 0012389
2014-12-21 23:08 whitequark File Added: camlrun.patch
2014-12-21 23:12 whitequark Note Added: 0012926
2014-12-27 08:50 gasche Note Added: 0012989
2014-12-28 23:34 whitequark File Deleted: camlrun.patch
2014-12-28 23:34 whitequark File Added: camlrun.patch
2014-12-28 23:35 whitequark Note Added: 0012995
2014-12-28 23:36 whitequark Note Edited: 0012995 View Revisions
2015-01-23 12:45 whitequark Tag Attached: patch
2015-02-08 11:12 gasche Note Added: 0013252
2015-02-09 17:54 doligez Note Added: 0013262
2015-02-09 17:54 doligez Target Version => 4.02.2+dev / +rc1
2015-02-12 04:50 whitequark File Deleted: camlrun.patch
2015-02-12 04:50 whitequark File Added: camlrun-4.02.patch
2015-02-12 04:50 whitequark File Added: camlrun-trunk.patch
2015-02-12 04:51 whitequark Note Added: 0013272
2015-02-15 22:02 gasche Note Added: 0013290
2015-02-27 16:50 whitequark Note Added: 0013357
2015-03-06 01:38 whitequark Note Added: 0013395
2015-03-09 20:18 doligez Note Added: 0013422
2015-03-09 20:23 doligez Note Edited: 0013422 View Revisions
2015-03-09 20:25 doligez Note Edited: 0013422 View Revisions
2015-04-30 21:03 doligez Note Added: 0013772
2015-04-30 21:03 doligez File Added: ocamlrun-fixed.diff
2015-04-30 21:04 doligez Assigned To => doligez
2015-04-30 21:04 doligez Status confirmed => feedback
2015-04-30 21:04 doligez Note Edited: 0013772 View Revisions
2015-04-30 21:05 doligez Note Edited: 0013772 View Revisions
2015-05-02 15:50 whitequark Note Added: 0013778
2015-05-02 15:51 whitequark Note Edited: 0013778 View Revisions
2015-05-05 22:58 doligez Note Added: 0013822
2015-05-05 22:58 doligez File Added: camlrun-fixed-2.diff
2015-05-06 00:31 whitequark Note Added: 0013824
2015-05-06 20:38 doligez Note Added: 0013847
2015-05-06 20:38 doligez Status feedback => closed
2015-05-06 20:38 doligez Resolution open => fixed
2015-05-06 20:38 doligez Fixed in Version => 4.02.2+dev / +rc1
2015-05-06 22:47 doligez Note Added: 0013855
2015-05-06 22:47 doligez Status closed => acknowledged
2015-05-06 22:47 doligez Resolution fixed => reopened
2015-05-07 16:39 doligez File Added: camlrun-fixed-3.diff
2015-05-07 16:57 doligez Note Added: 0013864
2015-05-07 16:58 doligez Status acknowledged => feedback
2015-05-07 16:58 doligez Fixed in Version 4.02.2+dev / +rc1 =>
2015-05-07 17:02 whitequark Note Added: 0013865
2015-05-07 17:05 whitequark Note Added: 0013866
2015-05-07 21:38 doligez Note Added: 0013868
2015-05-07 21:48 doligez Note Edited: 0013868 View Revisions
2015-05-08 00:00 doligez File Added: camlrun-fixed-4.diff
2015-05-08 00:01 doligez File Deleted: camlrun-fixed-4.diff
2015-05-08 00:26 doligez File Added: camlrun-fixed-4.diff
2015-05-08 00:27 doligez Note Added: 0013869
2015-05-08 07:11 whitequark Note Added: 0013870
2015-05-08 07:18 whitequark Relationship added parent of 0006861
2015-05-08 07:18 whitequark Note Added: 0013872
2015-05-08 14:53 doligez Note Added: 0013873
2015-05-08 14:56 whitequark Note Added: 0013874
2015-05-08 15:21 dbuenzli Note Added: 0013875
2015-05-08 15:23 dbuenzli Note Added: 0013876
2015-05-08 22:41 doligez File Added: camlrun-fixed-5.diff
2015-05-08 22:44 doligez File Deleted: camlrun-fixed-5.diff
2015-05-08 22:55 doligez File Added: camlrun-fixed-5.diff
2015-05-08 22:59 doligez Note Added: 0013877
2015-05-09 09:10 whitequark Note Added: 0013883
2015-05-09 09:10 whitequark Note Edited: 0013883 View Revisions
2015-05-11 17:00 doligez File Added: camlrun-fixed-6.diff
2015-05-11 17:00 doligez Note Added: 0013890
2015-05-11 19:11 shinwell Note Added: 0013892
2015-05-11 19:20 whitequark Note Added: 0013893
2015-05-11 19:42 doligez Note Added: 0013894
2015-05-11 19:51 doligez Note Added: 0013895
2015-05-12 16:46 doligez Note Added: 0013905
2015-05-12 16:46 doligez Status feedback => closed
2015-05-12 16:46 doligez Resolution reopened => fixed
2015-05-12 16:46 doligez Fixed in Version => 4.02.2+dev / +rc1

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker