Как создать плагин GTK (cmxs) для моей программы OCaml
Я хотел бы создать плагин GTK для моего приложения OCaml, загруженный с помощью Dynlink. Как я могу заставить ocamlbuild включить библиотеку lablgtk2 в сгенерированный плагин?
В качестве теста у меня есть 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)
Но я получаю:
$ 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")
Примечание: основной двоичный файл не должен зависеть от libgtk (который может быть не установлен в целевой системе) - если плагин не загружается, я хочу вернуться в режим консоли.
1 ответ
Вам нужно
добавить
linkall
флаг дляmain
в противном случае будут удалены части среды выполнения OCaml, которые впоследствии понадобятся динамическим плагинам.скомпилировать
gtk_plugin.cmxs
файл с опцией-lflag lablgtk.cma
(который я вывел, увидев в_log
что этот вариант не был пройден)
Как ocamlbuild выводит .cmxs
В настоящее время зависимости не оптимальны, и это трудно, потому что разные пользователи могут хотеть разные вещи (минимальные плагины, предполагающие наличие библиотек, или наоборот, переносимые статически связанные вещи). Для модулей из вашего проекта вы можете написать foo.mldylib
файл должен быть явным о том, что вы хотите исключить, но я не знаю, возможно ли включить "все модули этой внешней библиотеки".
Обратите внимание, что также можно распространять lablgtk.cmxs
и соответствующие .cmi
вместе с вашим плагином, и сначала загрузите его динамически.
mkdir lablgtk
cp `ocamlfind query lablgtk2`/lablgtk.cmxs lablgtk
cp `ocamlfind query lablgtk2`/*.cmi lablgtk
echo "\"lablgtk\": not_hygienic" >> _tags
тогда в вашем main.ml
let () =
try
Dynlink.loadfile "lablgtk/lablgtk.cmxs";
Dynlink.loadfile "_build/gtk_plugin.cmxs"
...