I want to compile an OCaml program interfacing with C code, using a MinGW-based GCC, and using separate compilation (GCC produces the .o
, then ocamlopt
produces the final executable).
It's not clear to me if (1) this should work on Windows and, if so, (2) which command-line arguments are necessary.
I'm using Jonathan Protzenko's OCaml on Windows installer to install OCaml 4.02.1 along with a Cygwin shell (note that it uses a native windows OCaml compiler, not a Cygwin-based one). I installed gcc using Nuwen's MinGW (but had the same issue when using Strawberry Perl's gcc).
Here's my source code:
C file (tc.c
):
#include <stdio.h>
#include "caml/mlvalues.h"
value print(value unused) {
printf("hello from C\n");
return Val_unit;
}
OCaml file (t.ml
):
external print : unit -> unit = "print"
let () =
Printf.printf "platform: %s\n" (Sys.os_type);
print ();
The following works just fine:
and@win7 $ ocamlopt t.ml tc.c -o t.exe
and@win7 $ ./t.exe
platform: Win32
hello from C
However, if I use a .o
instead of a .c
, it doesn't work:
and@win7 $ gcc tc.c -c -I c:/OCaml/lib -o tc.o
and@win7 $ ocamlopt t.ml tc.o -o t.exe
** Cannot resolve symbols for tc.o:
puts
** Fatal error: Unsupported relocation kind 0004 for puts in tc.o
File "caml_startup", line 1:
Error: Error during linking
Both versions work fine on Linux.
I wonder if it's just some silly mistake that I can quickly fix by giving the right arguments to gcc/ocamlc/ocamlopt, or if it's a current limitation of OCaml's native compilation on Windows.
Edit: camlspotter identified the cause, so in retrospect, I did not need Nuwen's MinGW at all. OCaml on Windows already includes a MinGW-based C compiler, except that it is called i686-w64-mingw32-gcc
and not gcc
.
mingw
tag;mingw-w64
may be an acceptable alternative, (but nuwen isn't strictly that fork either). – Keith Marshall