[SOLVED] Jbuilder and Ctypes, configure the C flags

I have a lib that use Ctypes, I have created the following lib/jbuild :

(jbuild_version 1)

(library
 ((name        GObjectIntrospection)
  (public_name ocaml-gobject-introspection)
  (libraries (ctypes ctypes.foreign str))
  (c_flags         (:include c_flags.sexp))
  (c_library_flags (:include c_library_flags.sexp))))

(rule
 ((targets (c_flags.sexp
            c_library_flags.sexp))
  (deps    (../config/discover.exe))
  (action  (run ${<} -ocamlc ${OCAMLC}))))

In order to load the C flags I have the following config/discover.ml file :

open Base
open Stdio
module C = Configurator

let write_sexp fn sexp =
  Out_channel.write_all fn ~data:(Sexp.to_string sexp)

let () =
  C.main ~name:"GObject-Introspection" (fun c ->
    let default : C.Pkg_config.package_conf =
      { libs   = ["-lgirepository-1.0"; "-lgobject-2.0"; "-lglib-2.0"]
      ; cflags = ["-O2"; "-Wall"; "-Wextra"; "-Wno-unused-parameter"; "-pthread";
                  "-I/usr/include/gobject-introspection-1.0";
                  "-I/usr/lib/libffi-3.2.1/include";
                  "-I/usr/include/glib-2.0";
                  "-I/usr/lib/glib-2.0/include"]
      }
    in
    let conf =
      match C.Pkg_config.get c with
      | None -> default
      | Some pc ->
        Option.value (C.Pkg_config.query pc ~package:"gobject-introspection-1.0") ~default
    in

    write_sexp "c_flags.sexp"         (sexp_of_list sexp_of_string conf.libs);
    write_sexp "c_library_flags.sexp" (sexp_of_list sexp_of_string conf.cflags))

with the following config/jbuild :

(jbuild_version 1)

(executable
 ((name discover)
  (libraries (base stdio configurator))))

When I run jbuilder build, evrything is fine, the problem come when I try to launch my tests :

the tests/jbuild file :

(jbuild_version 1)

(executables
 ((names (test))
  (libraries   (GObjectIntrospection oUnit ctypes ctypes.foreign))
))

(alias
 ((name    runtest)
  (deps    (test.exe))
  (action  (run ${<}))))

It seems that the my OCaml Ctypes bindings are not able to find the C libs :

jbuild runtest

...

(cd _build/default/tests && ./test.exe)
Fatal error: exception Dl.DL_error("./test.exe: undefined symbol: g_base_info_ref")

How can I fix that ?

Do you have the full source somewhere? I can have a look but would like to reproduce this first.

https://github.com/cedlemo/OCaml-GObject-Introspection. (please keep in mind that I am just a beginner).

thanks for bringing me the solution @rgrinberg,

The problem was related to the libffi C flags that were missing.

I was able to fix that, based on your example, with the following discover.ml file :

open Base
open Stdio
module C = Configurator

let write_sexp fn sexp =
  Out_channel.write_all fn ~data:(Sexp.to_string sexp)

let () =
  C.main ~name:"GObject-Introspection" (fun c ->
    let default : C.Pkg_config.package_conf =
      { libs   = ["-lgirepository-1.0"; "-lgobject-2.0"; "-lglib-2.0"]
      ; cflags = ["-O2"; "-Wall"; "-Wextra"; "-Wno-unused-parameter"; "-pthread";
                  "-I/usr/include/gobject-introspection-1.0";
                  "-I/usr/lib/libffi-3.2.1/include";
                  "-I/usr/include/glib-2.0";
                  "-I/usr/lib/glib-2.0/include"]
      }
    in
    let conf =
      match C.Pkg_config.get c with
      | None -> default
      | Some pc ->
         let libffi = Option.value_exn (C.Pkg_config.query pc ~package:"libffi") in
         let gobject = Option.value (C.Pkg_config.query pc ~package:"gobject-introspection-1.0") ~default in
         let  module P = C.Pkg_config in
         { libs = libffi.P.libs @ gobject.P.libs ;
           cflags = libffi.P.libs @ gobject.P.libs }
    in

    write_sexp "c_flags.sexp"         (sexp_of_list sexp_of_string conf.libs);
    write_sexp "c_library_flags.sexp" (sexp_of_list sexp_of_string conf.cflags))