OCaml Forge

Detail: [#891] oasis: support cross-compilation

Feature Requests: Browse | Download .csv | Monitor

[#891] oasis: support cross-compilation

2011-01-21 19:51
Submitted by:
Török Edwin (edwin)
Assigned to:
Sylvain Le Gall (gildor-admin)
Due in version:
Operating System:
oasis: support cross-compilation

Detailed description
./configure should have a way to specify the host/target (for example ./configure --host i586-mingw32msvc), and automaticaly pick the compiler tools for that target.
Once that is done it should also make sure that during 'make' those tools are used and not others.

This is tricky (ocaml-autoconf gets it wrong for example), because the build tools have .opt versions, and the cross-tools don't have .opt versions.
Search order should be:
- tool with target prefix, simple and .opt variants, if found -> use it
- if not found, search without target prefix, again simple and .opt variants


Date: 2011-12-29 00:22
Sender: William R

@sylvain :
I am quite a rookie too in cross compilation, because I have learnt it for one or two week now. But I had time this Christmas to study it ;-) And I am french, just in case you wonder of my english!

your remarks and questions implies a long answer, so let's start.

1) what is cross-compilation?
cross-compilation = compile from a platform for another platform. For my concern, the interesting thing to do is to port linux applications under windows, that is to say cross-compile from linux/debian to windows.
As you say, as far as ocaml is concerned, this has to do with using the right ocamlc/ocamlopt for ocamlfind, which might not be a very simple task. Here is an example, under debian, of a cross compiled ocaml program :
! sudo aptitude install mingw32-ocaml wine
! mkdir test_hello
! cd test_hello
! echo "Printf.printf \"hello\n\"" > hello.ml
! i586-mingw32msvc-ocamlopt -o hello.exe hello.ml
! file hello.exe
! wine hello.exe
Note that because wine is installed, you can even do :
! ./hello.exe

2) Now the problem is to port an application a bit more complex than "hello" : my case is a lablgtk2 application, which involves ocaml, gtk2, lablgtk2, and many other C libraries. For now, I have identified three 'standard' ways to compile a windows ocaml program :
- from windows, install cygwin, then suitable C packages, then suitable godi packages. But godi does not work for this (I mean, is not actively supported, and there are always problems).
- from linux, oasis with godi could be the system, but the cross-compilation is not supported for neither one
- fedora, with the work of Richard Jones, has maybe the most advanced ocaml cross compilation toolchain towards windows, with the mingw-* packages.

Buy the way, do you have a good method to port gnu linux applications to windows?

3) Richard Jones, the guy from fedora, seems to have quite good knowledge for porting/packaging applications. According to him, the autotools are the best for this job. The autotools are the standard gnu tools for compilation and porting of C/C++ gnu programs (to my understanding).
Autotools and oasis look very much the same in terms of functionality. Autotools seem to benefit from a much bigger community than oasis, and are used for C/C++. But no support for ocaml, unless ocaml-autoconf, which are additional macros made to actually extend autotools.

4) good tests for oasis would be to be able to cross compile lablgtk2, and then to cross compile a lablgtk2 application such as this one :

let destroy () = GMain.Main.quit ()
let _ =
let _ = GtkMain.Main.init () in
let window = GWindow.window () in
let _ = window#connect#destroy ~callback:destroy in
window#show ();
GMain.Main.main ()

Best regards,
Date: 2011-12-26 12:23
Sender: Török Edwin

Attached is an example with ocaml-autoconf and Makefile (attached configure.ac, configure and Makefile).

See the Makefile how to call ocamlfind/ocamlbuild.

Note about cross compilation (GCC docs probably explain this better):
When you build a cross compiler: compiler runs on $build, builds a compiler
that will run on $host and produce code for $target.
Normally when you build programs $host = $target, and $build = the system you are using to build.

This is what I mean by ocaml-autoconf getting cross-compilation wrong (on my system at least):
./configure --build=x86_64-linux-gnu --host=i686-w64-mingw32
checking for i686-w64-mingw32-ocamlc... i686-w64-mingw32-ocamlc
OCaml version is 3.12.1
OCaml library path is /usr/i686-w64-mingw32/lib/ocaml
checking for i686-w64-mingw32-ocamlopt... i686-w64-mingw32-ocamlopt
checking for i686-w64-mingw32-ocamlc.opt... no
checking for ocamlc.opt... ocamlc.opt
configure: WARNING: using cross tools not prefixed with host triplet
checking for i686-w64-mingw32-ocamlopt.opt... no
checking for ocamlopt.opt... ocamlopt.opt
checking for i686-w64-mingw32-ocaml... no
checking for ocaml... ocaml
checking for i686-w64-mingw32-ocamldep... i686-w64-mingw32-ocamldep
checking for i686-w64-mingw32-ocamlmktop... i686-w64-mingw32-ocamlmktop
checking for i686-w64-mingw32-ocamlmklib... i686-w64-mingw32-ocamlmklib
checking for i686-w64-mingw32-ocamldoc... no
checking for ocamldoc... ocamldoc
checking for i686-w64-mingw32-ocamlbuild... no
checking for ocamlbuild... ocamlbuild
checking for i686-w64-mingw32-ocamlfind... no
checking for ocamlfind... ocamlfind
checking for OCaml findlib package extlib... found
configure: creating ./config.status
config.status: creating Makefile

Notice that it finds the cross-compiler tool, and then goes searching for a .opt. So far so good.
Here is the bad part: it doesn't find a cross-compiler with an .opt suffix, so it tries the one without the prefix!
A simple fix would be to search for .opt first, and to refuse using the compiler without the target-prefix, when cross-compilation is asked.

I think what it should do is:
1. search for <target-prefix>-<compilername>.opt, <target-prefix>-<compilername>. If found, then stop searching
2. If <target> = <host> then search for normal <compilername>.opt
and <compilername> too, otherwise fail because we didn't find the cross-compiler we were asked for!

$ ./configure --host=i686-w64-mingw32
build=x86_64-linux-gnu (or whatever your current build system is)

Search for $target-ocamlc.opt, $target-ocamlc. The first one found will be used. If neither is found -> fail because we didn't find a cross-compiler
Similarly search for $target-ocamlopt.opt, etc.

Example 2 (when $build is x86_64-linux-gnu)
$ ./configure --host=x86_64-linux-gnu
build=host=target=x86_64-linux-gnu (or whatever your current build system is)

Search for $target-ocamlc.opt, $target-ocamlc. If found, use it.
If not found then search for ocamlc.opt, and ocamlc. If found, use it, if not fail.

When $target=$build then you can use either $target-ocamlc, or ocamlc, both will produce code for $target.
When $target != $build you can only use $target-ocamlc, because ocamlc would produce code for $build not $target.

Date: 2011-12-26 11:07
Sender: Sylvain Le Gall

I know almost nothing about cross compilation. Could you be more descriptive on how to do (e.g. complete example).

Honestly, I don't see how to do that (except just using the right ocamlc/ocamlopt for ocamlfind).
Date: 2011-12-25 21:24
Sender: William R

exactly same need for me.
The only interest in using oasis, to my concern, is to help port application to ohter platforms, and especially cross compile to mingw32msvc.

Attached Files:



Field Old Value Date By
File Added152: tst.tar.gz2011-12-26 12:23edwin
assigned_tonone2011-01-31 09:37gildor-admin