# Writing ctypes bindings to system shared libraries for bytecode targets via the dune ctypes stanza

**URL:** <https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844>\
**Category:** Ecosystem\
**Tags:** dune\
**Created:** [January 11, 2024, 3:12pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844 "2024-01-11T15:12:38Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![lukstafi](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lukstafi/32/3442_2.png) [@lukstafi](https://discuss.ocaml.org/u/lukstafi)\
**Post date:** [January 11, 2024, 3:12pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/1 "2024-01-11T15:12:38Z")

</div>

Working on [GitHub - lukstafi/ocaml-gccjit: OCaml bindings for libgccjit](https://github.com/lukstafi/ocaml-gccjit), I’m facing a problem with the same symptom as in this issue: [Add link flags ocamlmklib when using ctypes stubs](https://github.com/ocaml/dune/pull/8784).

```shell
lukstafi@DESKTOP-6RRUNR4:~/ocaml-gccjit$ dune exec examples/tut01_hello_world.bc
Fatal error: cannot load shared library dllgccjit_stubs
Reason: /home/lukstafi/ocaml-gccjit/_build/install/default/lib/stublibs/dllgccjit_stubs.so: undefined symbol: gcc_jit_context_new_opaque_struct
Aborted

```

The stubs library is found, but the underlying `libgccjit.so` library is not loaded. I tried various things like: adding `-linkall`; setting the env variables `DYLD_LIBRARY_PATH`, `LD_LIBRARY_PATH`, `CAML_LD_LIBRARY_PATH`; using `byte_complete` (doesn’t produce a `.bc` target); adding `(ocamlc_flags (-custom))` (breaks the build).

Any ideas I could follow?

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [January 11, 2024, 4:00pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/2 "2024-01-11T16:00:15Z")

</div>

> [@lukstafi](#):
>
> Any ideas I could follow?

I’m not familiar with Ctypes, so don’t have much to offer. But it is often useful to look at the link flags recorded in `libgccjit.cma`/`libgccjit.cmxa`, which you can do with eg `ocamlobjinfo libgccjit.cma`. I think you would like to see at least `-lgccjit` and `-lgccjit_stubs` (in that order). If `-lgccjit` is missing then it means that some link-time flag is not being passed correctly somewhere.

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![lukstafi](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lukstafi/32/3442_2.png) [@lukstafi](https://discuss.ocaml.org/u/lukstafi)\
**Post date:** [January 11, 2024, 5:01pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/3 "2024-01-11T17:01:20Z")

</div>

Yes, `-lgccjit` is neither in `Extra dynamically-loaded libraries:`, nor in the result of `ldd build/_default/lib/dllgccjit_stubs.so`. All flags are crammed into `Extra C object files:`.

---

<div class="post-metadata">

**Author:** ![mobileink](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/mobileink/32/3295_2.png) [@mobileink](https://discuss.ocaml.org/u/mobileink)\
**Post date:** [January 11, 2024, 6:07pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/4 "2024-01-11T18:07:10Z")

</div>

> [@lukstafi](#):
>
> The stubs library is found, but the underlying `libgccjit.so` library is not loaded.

Is it possible the lib is loaded but the symbol is stripped? I encountered this recently. The fix was `-Wl,-export-dynamic` (or `-export_dynamic` for mac).

---

<div class="post-metadata">

**Author:** ![lukstafi](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lukstafi/32/3442_2.png) [@lukstafi](https://discuss.ocaml.org/u/lukstafi)\
**Post date:** [January 11, 2024, 6:24pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/5 "2024-01-11T18:24:18Z")

</div>

` -Wl,-export-dynamic` did not help.

I managed to get ocamlobjinfo ==\> `Extra C options: -lgccjit -Wl,-export-dynamic`, but it did not help.

Is there any way to pass additional parameters for `ocamlmklib`? Dune `-verbose`:

```shell
Running[26]: (cd _build/default && /home/lukstafi/.opam/5.1.1/bin/ocamlmklib -g -o lib/gccjit_stubs lib/libgccjit __c_cout_generated_functions__ Gccjit_bindings__Functions.o)

```

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [January 11, 2024, 7:20pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/6 "2024-01-11T19:20:55Z")

</div>

> [@lukstafi](#):
>
> I managed to get ocamlobjinfo ==\> `Extra C options: -lgccjit -Wl,-export-dynamic`, but it did not help.

I think you need to get `-lgccjit` inside the “Extra dynamically-loaded libraries” field of your archive. This is typically achieved by passing `-lgccjit` to the `ocamlmklib` invocation.

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![lukstafi](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lukstafi/32/3442_2.png) [@lukstafi](https://discuss.ocaml.org/u/lukstafi)\
**Post date:** [January 11, 2024, 7:29pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/7 "2024-01-11T19:29:58Z")

</div>

Yes but does it mean I need to abandon the `ctypes` stanza? Since I wasn’t able to achieve passing arguments to `ocamlmklib`. Edit: despite this line, meaning it should be possible, maybe outside of the `ctypes` stanza: [dune/src/dune\_rules/lib\_rules.ml at e515c294686999610e14079608a7d912c77bfe1b · ocaml/dune · GitHub](https://github.com/ocaml/dune/blob/e515c294686999610e14079608a7d912c77bfe1b/src/dune_rules/lib_rules.ml#L202)

---

<div class="post-metadata">

**Author:** ![nojb](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/nojb/32/519_2.png) [@nojb](https://discuss.ocaml.org/u/nojb)\
**Post date:** [January 11, 2024, 7:33pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/8 "2024-01-11T19:33:39Z")

</div>

> [@lukstafi](#):
>
> Yes but does it mean I need to abandon the `ctypes` stanza?

I don’t know enough about the `ctypes` stanza to answer this question, sorry.

> <https://github.com/lukstafi/ocaml-gccjit/blob/1a768671e27e9fa314904dccad024d349af4dee6/lib/dune#L62-L68>

Did you try adding `(c_library_flags -lgccjit)` directly to the `(library)` stanza?

Cheers,  
Nicolas

---

<div class="post-metadata">

**Author:** ![lukstafi](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lukstafi/32/3442_2.png) [@lukstafi](https://discuss.ocaml.org/u/lukstafi)\
**Post date:** [January 11, 2024, 7:37pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/9 "2024-01-11T19:37:25Z")

</div>

> [@nojb](#):
>
> Did you try adding `(c_library_flags -lgccjit)` directly to the `(library)` stanza?

Yes IIRC. (Double-checked now it doesn’t help.) I definitely also tried `(flags -cclib -lgccjit)`. And also global env `c_flags` and `flags`.

---

<div class="post-metadata">

**Author:** ![soya](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/soya/32/119_2.png) [@soya](https://discuss.ocaml.org/u/soya)\
**Post date:** [January 11, 2024, 9:05pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/10 "2024-01-11T21:05:43Z")

</div>

> <https://github.com/ocaml/dune/pull/8784>
>
> Add link flags for external dependencies when using ctypes.
> 
> Required when t…he external lib is not statically linked, in which case
> linker needs to be aware at runtime what libs to call. This is the case
> for
> 
> - dune exec \<file\>.bc
> - dune utop
> - mdx tests
> 
> That is add to ocamlmklib, link flags such as -l\<libname\> -L\<libdir\>
> from ctypes if info is available.
> 
> If dependent library are not installed in expected locations, env
> variable such as LD\_LIBRARY\_PATH must be extended when required program
> is run, depending on os. This may be fixed by adding relocatable paths to
> link flags.

This might help, had similar issue with ctypes and dune when using bytecode.

---

<div class="post-metadata">

**Author:** ![lukstafi](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lukstafi/32/3442_2.png) [@lukstafi](https://discuss.ocaml.org/u/lukstafi)\
**Post date:** [January 11, 2024, 9:23pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/11 "2024-01-11T21:23:39Z")

</div>

Thanks, I haven’t seen this in my searches! In the meantime, I had another idea to try: generate/vendor `libgccjit.pc` and use `(build_flags_resolver pkg_config)`. If it doesn’t work, I’ll study this PR. Edit: ah, sorry I did see this. I linked this PR in my original post!

---

<div class="post-metadata">

**Author:** ![lukstafi](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lukstafi/32/3442_2.png) [@lukstafi](https://discuss.ocaml.org/u/lukstafi)\
**Post date:** [January 11, 2024, 10:58pm UTC](https://discuss.ocaml.org/t/writing-ctypes-bindings-to-system-shared-libraries-for-bytecode-targets-via-the-dune-ctypes-stanza/13844/12 "2024-01-11T22:58:23Z")

</div>

I now converted to `(build_flags_resolver pkg_config)`, but the situation is the same: `ocamlmklib` still does not get any arguments (in particular it does not ask to link the `external_library_name`), and the execution still fails with the original error message.

Edit (updated): I now patched [Add link flags ocamlmklib when using ctypes stubs. by frejsoya](https://github.com/ocaml/dune/pull/8784), and it solves the problem (both the `(build_flags_resolver pkg_config)` variant and the `(build_flags_resolver (vendored ...))` variant). It still has the [bytecode + c stubs not working as expected · Issue #108](https://github.com/ocaml/dune/issues/108) problem when `dune clean; dune exec` – but it is easily solved by `dune build; dune exec`; alternatively need to update `CAML_LD_LIBRARY_PATH` i.e. `dune clean; CAML_LD_LIBRARY_PATH=... dune exec` works, but using `(env (_ (env-vars (CAML_LD_LIBRARY_PATH ...))))` does not work.
