Hi there – first time poster.
Short question: I’d like to link a .ml library program to a standalone C program into a shared library. (If it helps, I would happy to start with just gcc on linux). Is there documentation on how I might do this, or does anyone know?
Long question: I want to create a language interface for OCaml in the Godot game engine. To do this, you need to provide a function with the following signature:
GDExtensionBool
my_entry_function(
GDInterfaceGetProcAddress p_get_proc_address /* pointer to function */,
GDExtensionClassLibraryPtr p_lib /* ptr to Godot class library */,
GDExtensionInitialization* r_initialization
/* ptr to a defined struct type that contains pointers to functions
that do the actual initialization of your plugin at various
"levels" of bringing up the Godot engine. */
);
Which then I can tell Godot to load via a text file on startup.
Failure so Far
I am able to link an executable, but not a shared library with dune or manually. I feel like I’m close, however; Godot can find the startup function and dynamically links to the OCaml runtime (I can tell because it used to not!). However, it says it’s not a shared library (which I agree with) and so can’t load it. Alternatively, I can build it as an object file (seen below), and it claims it’s not dynamic (which I also agree with). Here is the actual error message in the second case [from Godot]:
ERROR: Can't open dynamic library: /home/fizzixnerd/src/toycaml/libhello-gdextension.so. Error: /home/fizzixnerd/src/toycaml/libhello-gdextension.so: only ET_DYN and ET_EXEC can be loaded.
at: open_dynamic_library (drivers/unix/os_unix.cpp:660)
ERROR: GDExtension dynamic library not found: /home/fizzixnerd/src/toycaml/libhello-gdextension.so
at: open_library (core/extension/gdextension.cpp:719)
ERROR: Failed loading resource: res://hello.gdextension. Make sure resources have been imported by opening the project in the editor at least once.
at: _load (core/io/resource_loader.cpp:274)
ERROR: Error loading extension: res://hello.gdextension
at: load_extensions (core/extension/gdextension_manager.cpp:234)
ERROR: Can't open dynamic library: /home/fizzixnerd/src/toycaml/ocaml/godotcaml/c/libhello-gdextension.so. Error: libcamlrun_shared.so: cannot open shared object file: No such file or directory.
at: open_dynamic_library (drivers/unix/os_unix.cpp:660)
ERROR: GDExtension dynamic library not found: /home/fizzixnerd/src/toycaml/ocaml/godotcaml/c/libhello-gdextension.so
at: open_library (core/extension/gdextension.cpp:719)
ERROR: Failed loading resource: res://ocaml/godotcaml/c/hello.gdextension. Make sure resources have been imported by opening the project in the editor at least once.
at: _load (core/io/resource_loader.cpp:274)
ERROR: Error loading extension: res://ocaml/godotcaml/c/hello.gdextension
at: load_extensions (core/extension/gdextension_manager.cpp:234)
Details of What I Have
I have something that looks like
- godotcaml
- dune-project
- godotcaml.opam
- bin
- dune
- gdextension_interface.h (* a C header I include in the C src below *)
- hello-gdextension.c (* a C source file that contains the entry point the plugin expects; calls OCaml from here *)
- main.ml (* Where I do all my real work in OCaml *)
My dune file looks like
(executable
(name main)
(modes (native object))
(libraries godotcaml ctypes.foreign ctypes)
(foreign_stubs (language c) (names hello-gdextension))
(flags (:standard -g -cclib "-L/usr/lib/x86_64-linux-gnu/")))
the library godotcaml
is the main library interface for OCaml for Godot I am writing; it shouldn’t really figure into this, I don’t think. It can be statically linked in.
dune build
creates a file main.exe.o
, and I copy that to where Godot can see it as libhello-gdextension.so
. Yup.
So it’s not exactly surprising it doesn’t work, but I think I’m pretty close. Any help would be appreciated.
PS is there a matrix or IRC for ocaml I could join?