Home page: The natdynlink branch in OCaml's CVS
How to get it
The natdynlink branch has been merged to the trunk of OCaml's CVS (HEAD branch). You can get it with the command:
cvs -d :pserver:anoncvs@camlcvs.inria.fr:/caml co ocaml
Before the merger, the branch lived its own life, based on OCaml 3.10.0. This experimental branch is no longer maintained. You can get it with the command:
cvs -d :pserver:anoncvs@camlcvs.inria.fr:/caml co -r natdynlink ocaml
GODI users can simply ask GODI to rebuild the godi-ocaml-src and godi-ocaml after setting OCAML_CVS_CHECKOUT = yes and OCAML_CVS_REVISION = HEAD in the configuration screen for godi-ocaml-src. (Make sure that you have GODI_SECTION = 3.10 in your godi.conf, and do "Update the list of available packages".)
This branch has been tested for the following ports: Linux x86, Linux x86_64, Cygwin 32-bit, Mingw 32-bit, MSVC 2003 Win32 and Win64, MSVC 2005 Win32, Mac OS X Intel 10.4 and 10.5, FreeBSD x86, OpenBSD x86. Under Windows, you need to install the FlexDLL tool.
The main changes with respect to OCaml are:
- Dynamic loading of OCaml code in native code programs, through the Dynlink module.
- Simplified dynamic linking of C code under Windows.
If you play with this experimental branch, please send some feedback!
Dynamic loading of OCaml native code
- The native compiler, ocamlopt, can produce so called plugins (suggested extension: .cmxs) from a set of .cmx/.cmxa files. Plugins can be dynlinked with Dynlink.loadfile.
- The new ocamlopt option -dlcode must be used when compiling a unit so that it can be put into a plugin. It can still be linked statically. Currently, -dlcode is only necessary for the Linux AMD64 port, but it is a good idea to always use it. There is theoretically a chance that -dlcode degrades performances, but it has never never been observed in practice.
- The new ocamlopt option -shared is used to link together a set of .cmx and .cmxa files (and also C objects/libraries) into a plugin. The "transitive closure" algorithm used to select units from .cmxa files is the same as for static linking (-linkall can be used). An option -o is mandatory.
- It is possible to add arbitrary C code into a .cmxs plugin. (Compare to byte code dynlink, where you need additional .so/.dll for stub code.)
- dynlink.cmxa is now available. It defines a single module Dynlink with exactly the same interface as the byte-code one. Of course, in native code, the loadfile function takes the name of a .cmxs file. The new boolean Dynlink.is_native can be used to know whether the program is running in bytecode or in native code.
It is not possible to load native code from a bytecode program. It is not possible to load bytecode modules from a native program. Repeat after me: a program produced by ocamlc/ocamlc.opt can only load .cmo/.cma files and a program produced by ocamlopt/ocamlopt.opt can only load .cmxs file. Thanks for your attention. If you really want to load bytecode from a native program, you can try Fabrice Le Fessant's Asmdynlink.
Dynamic loading of C code under Windows
The life of OCaml users under Windows is greatly simplified:
- The 32-bit Cygwin port now supports dynamic linking of C code (in ocamlrun or in the toplevel). You don't need to use -custom any more.
- The native 32-bit windows ports (Mingw/MSVC) no longer need two different compilations for C code (before, one had to compile differently according to whether the C code would be linked statically or dynamically).
- A dynamically loaded C DLL can refer to any symbol from the main program (symbols of the caml runtime, or symbols of statically-linked C code) and to any symbol from a previously loaded C DLL. The dllimport/dllexport declspecs modifiers in the C code are no longer needed.
- The ocamlmklib tool is now available under Windows.
- Makefiles should be greatly simplified (see the Makefiles in the otherlibs subdirectory).
- the OCaml bytecode runtime system is no longer compiled twice. Dynamically loaded C code can now backlink to the static version directly. ocamlrun.dll and ocamlrun.{a,lib} are gone.
Minor changes
- The "-implib" option of ocamlmklib no longer exists.
- -dllib options recorded in libraries are not ignored when -use_runtime or -use_prims are used (unless -no_auto_link is used). Rationale: one might want to use a specific version of ocamlrun and still use dynamic C libraries.
- ocamlopt now checks that at most one of -a,-pack,-shared,-c is given.
- There is now an ocamldep.opt (built during opt.opt) even on Windows.
Native toplevel
There is also a native toplevel called ocamlnat (not built by default). It can load .cmx/.cmxa/.cmxs files. It is not planned to include this native toplevel in a future official version of OCaml, though.
TODO
- Better internal treatment for Dynlink.loadfile_private (pass RTLD_LOCAL to dlopen); risks of symbol collision otherwise.
- Adapt ocamlbuild scripts.
- Build native versions of Camlp4 dynlinkable modules (syntax extension, filters, pretty-printers).
Home page: The natdynlink branch in OCaml's CVS