I'd like to make a GTK plugin for my OCaml application, loaded using Dynlink. How can I get ocamlbuild to include the lablgtk2 library in the generated plugin?
As a test, I have main.ml:
let () =
try
Dynlink.loadfile "_build/gtk_plugin.cmxs"
with Dynlink.Error err ->
failwith (Dynlink.error_message err)
gtk_plugin.ml:
let () =
print_endline "GTK plugin loaded!";
GMain.Main.main ()
_tags:
<main.*>: package(dynlink)
<gtk_plugin.*>: package(lablgtk2)
But I get:
$ ocamlbuild -use-ocamlfind main.native gtk_plugin.cmxs
$ ./main.native
Fatal error: exception Failure("error loading shared library:
.../_build/gtk_plugin.cmxs: undefined symbol: camlGtkMain")
Note: the main binary must not depend on libgtk (which might not be installed on the target system) - if the plugin fails to load I want to fall back to console mode.
You need to
add the
linkallflag tomain, otherwise it will remove parts of the OCaml runtime that will later be needed by dynamic pluginscompile the
gtk_plugin.cmxsfile with option-lflag lablgtk.cma(which I deduced from seeing in the_logthat this option was not passed)The way ocamlbuild deduces
.cmxsdependencies is not optimal right now, and it's hard because different users may want different things (minimal plugins assuming libs are present, or on the contrary portable statically linked stuff). For modules coming from your project you can write afoo.mldylibfile to be explicit about what you want excluded, but I don't know whether it's possible to include "all modules of this external library".Note that it is also possible to distribute
lablgtk.cmxsand the relevant.cmialong with your plugin, and load it dynamically first.then in your main.ml