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
linkall
flag tomain
, otherwise it will remove parts of the OCaml runtime that will later be needed by dynamic pluginscompile the
gtk_plugin.cmxs
file with option-lflag lablgtk.cma
(which I deduced from seeing in the_log
that this option was not passed)The way ocamlbuild deduces
.cmxs
dependencies 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.mldylib
file 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.cmxs
and the relevant.cmi
along with your plugin, and load it dynamically first.then in your main.ml