Saturday, July 13, 2013

Static OCaml embedding on Win32

A procedure for OCaml embedding in a DLL at least is documented on the web in this thread. As far as I know though, there isn't any explicit information anywhere on how to embed OCaml statically on Win32. This tip for how to do it was taught to me by Alain Frisch. The build commands are given as CMake rules. First we compile our OCaml sources and have ocamlopt.opt output an object file of the result.
add_custom_command( 
  OUTPUT foo_ocaml.obj
  DEPENDS foo.mli foo.ml
  COMMAND ${OCAMLOPT_OPT} -o foo_ocaml.obj
          foo.mli
          foo.ml
  )
We package the output object into a library archive with this:
add_library (foo STATIC foo_ocaml.obj)
set_target_properties (foo PROPERTIES LINKER_LANGUAGE CXX)
The C wrapper is compiled with the C compiler into an archive with a file flexdll_stubs_c.c:
add_library (foo_api
  STATIC
  foo.c
  flexdll_stubs_c.c
)
flexdll_stubs_c.c provides "what it says on the tin":
void flexdll_dump_exports(void* u)
{ 
  (void)u; 
}

void *flexdll_dlopen(char const* file, int mode)   
{ 
  (void)file; (void)mode; return (void*)0; 
}

void flexdll_dlclose(void* u)                                                      
{ 
  (void)u; 
}

void* flexdll_dlsym(void* u, const char * n)             
{ 
  (void)u; (void)n; return (void*)0; 
}

char* flexdll_dlerror()                                        
{ 
  static char* flexdll_error_buffer = "flexdll is not availble";

  return flexdll_error_buffer; 
}
Executable targets link with the two archives above and the OCaml runtime via libasmrun.lib.