Ocaml plugin loader, from ocaml source file. Wrapper around Dynlink module, including on the fly async ocaml compilation.
This is a low level module, casual user should rather use 'Ocaml_compiler' apart from Make to create a dedicated Plugin loader.
mutable type for loading ocaml modules.
Currently this library works with native code only. Called in bytecode,
the function create
will return the following exception as an error result.
The convention over the name of the executable inside the archive. All are native executables (.opt)
Cleaning the files generated by this Ocaml_dynloader.t from the begining of his life, and try to remove the directory if it is empty once the files have been removed. Doesn't fail if the directory contains other files, keep them and keep the directory in that case. Once cleaned, you cannot use a dynloader anymore, you should just leave it alone and let it be collected by the GC at some point. Using a cleaned dynloader will result in an error.
The type t
is the type of a first level module you want to load.
This is typically the type of your expected config file, as a top level
ocaml module.
The field repr
is the concrete OCaml syntax for this module type.
The field univ_constr
is used to constr and match_ values of type t, embedded
in a value of type Univ.t.
The field univ_constr_repr
is the concrete OCaml syntax for the field univ_constr
.
Example : CUSTOM(module) M : A.S defined in the library "mylib.cmxa".
module My_config_loader = Ocaml_plugin.Ocaml_dynloader.Make (
struct
type t = (module A.S)
let repr = "Mylib.A.S"
let univ_constr = A.univ_constr
let univ_constr_repr = "Mylib.A.univ_constr"
end)
repr
and univ_constr_repr
should be contain complete paths, as it would be
used by an ocaml file to link with the shared cmi files, in particular be aware
that if you have some 'open' statements in your file, you might have different
t and repr, which is a bad practice.
If the module type A.M_intf
is defined in a package, you would need
to add it in the repr, as it is part of the complete path of the module type
("Mylib" in the example).
find_dependencies t file
uses ocamldep to compute the list of .ml and .mli files
that file
depends on transitively, which you can then pass to load_ocaml_src_files
.
file
must be an .ml file, and all the files it depend on must be in the same folder.
Load a bunch of ocaml files source files (.ml + .mli). The last module's signature
should be compatible with the signature X.repr
. If the type does not match, there
will be an error during OCaml compilation. The files are copied into the compilation
directory, and compiled versus a generated mli file including the relevant module
signature. This generated file is then dynlinked with the current executable.
The compilation happens using Dynlink.loadfile_private
, meaning that
the toplevel definition defined in these files are hidden
(cannot be referenced) from other modules dynamically loaded afterwards
Similar to load_ocaml_src_files
, but does not execute the plugin toplevel, just
checks that compilation and dynamic linking work.
The following functions are used for step by step use, not for the casual user
because they are much more error prone. Prefer load_ocaml_src_files
if possible
This compiles the source files into cmxs file, but does not execute the plugin
toplevel. The resulting cmxs file can be loaded by blocking_load_cmxs_file
either
from the same process or other processes which share the same executable. If compile
succeeds, it returns Ok
and write the compiled cmxs file into output_file
(may
override existing file), otherwise it returns Error
and won't write to
output_file
at all.
Dynlink has the following not really wanted property: dynlinking a file with a given filename only works properly the first time. Further dynlinks with the same filename (even a different file) will not load the new module but instead execute the initial module. Some even says that the behavior upon reload depends on the platform. Long story short: don't do that. Dynlink files at most once.
It is worth noting too that this function only works with cmxs files produced by
ocaml_plugin's compile_ocaml_src_files_into_cmxs_file
. It expects the code to
perform some internal library calls, thus it cannot be used with any arbitrary cmxs
compiled in some other way. Furthermore this function would return an error even
though the cmxs was built with ocaml_plugin when built under a different context
(compiler version used, cmi dependencies version, etc.) The intended usage is to
have the compilation and loading done using the same executable.