Ffi-7.dll can't be found

I am trying to adapt pg_query to Windows (MinGW, opam.2.2.0~beta1). With some help, I have a version of pg_query which compiles and installs. (The help come from Introducing pg_query for Postgres 16 - Parsing SQL/JSON, Windows support, PL/pgSQL parse mode & more)

However, I have the following results with utop:

utop # #require "pg_query";;
Cannot load required shared library dllctypes-foreign_stubs.
Reason: C:\Users\frede\AppData\Local\opam\default\lib/stublibs\dllctypes-foreign_stubs.dll: Le module spécifié est introuvable.

(The specified module can’t be found).

The error seems weird since I do have a C:\Users\frede\AppData\Local\opam\default\lib/stublibs\dllctypes-foreign_stubs.dll file.

From the library from Introducing pg_query for Postgres 16 - Parsing SQL/JSON, Windows support, PL/pgSQL parse mode & more, I do manage to run one of the example (but need to add /usr/x86_64-w64-mingw32/sys-root/mingw/bin to my PATH because of libwinpthread-1.dll).

The package install a pg_check command which can’t be executed because of a missing ffi-7.dll. I guess this DLL is the culprit. It is not installed on my system.

pg_check is compiled with the following dune file:

(executable
 (name pg_check)
 (public_name pg_check)
 (libraries ctypes ctypes.foreign cmdliner pg_query))

Where Ctypes/Foreign interface can be found.

Note, a dummy Hello world compiled with:

(executable
 (name main)
 (libraries ctypes ctypes.foreign))

Will also miss the ffi-7.dll file. Then, there is nothing which deals with my pg_query tweaks.

EDIT: I have just filed a ticket Programs compiled with ctypes.foreign miss ffi-7.dll · Issue #18 · ocaml-opam/opam-repository-mingw · GitHub

With MSVC, I am even further to make it works: opam install ctypes fails!

Looking ot a fdopen ctypes-foreign opam file, I see conf-libffi which indicates an external dependancy. I have finally found a ffi-7.dll among my GTK library files. It is also available on vcpkg.

On Linux, an homologous library is also needed but provided by the system: then I can compile a file which needs:

        libffi.so.8 => /lib/x86_64-linux-gnu/libffi.so.8 (0x00007fe9a9107000)

But on Linux, installing a fancy package which need an external thing displays something like this:

The following system packages will first need to be installed:
    libgtk-3-dev

I guess we miss an homologous warning on Windows (with a vcpkg distribution ?).

Adding its bin directory to the PATH, I have now the following error:

$pg_check
Fatal error: exception Dl.DL_error("dlsym: no such symbol: \"pg_query_parse\"")

The error is curious. pg_query is compiled as a static library (libpg_query.a), and the error suggest a dynamic linking. I think I should create a minimalist Ctypes-foreign program to spot the issue and ease the debugging.

I have reproduced the error - on Linux - with a stripped down library and a test program with comparable dune stanza.

My dune file:

(rule
 (deps a.c)
 (targets libtest.a)
 (action (run %{make} build)))
(executable
 (name test)
 (modes native)
 (libraries ctypes ctypes.foreign)
 (foreign_archives test))

But despite of the foreign_archives stanza, my libtest.a is not included. The nm command do find my test function in libtest.a but not in test.exe.

Note: dune launch ocamlopt.opt with the -cclib libtest.a flag. Then the linker uses from libtest.a only referenced symbols… then nothing since the Ctypes-foreign indirection.