# Stubs c - shared and static libs

**URL:** <https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987>\
**Category:** Learning\
**Tags:** c, stubs, dune\
**Created:** [June 11, 2021, 10:08am UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987 "2021-06-11T10:08:11Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![maiste](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/maiste/32/3919_2.png) [@maiste](https://discuss.ocaml.org/u/maiste)\
**Post date:** [June 11, 2021, 10:08am UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/1 "2021-06-11T10:08:11Z")

</div>

Hi,  
I’m currently working with an [ocaml library](https://github.com/mathiasbourgoin/ocaml_mammut) that uses c++ binding. When I build the library from the sources, in the build repository, there are both `.so` and `.a` file. However, when I install it from opam and pin-depends, only the `.a` files are built.

I don’t understand why, and I wonder if there is a way to force that?

---

<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:** [June 11, 2021, 11:17am UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/2 "2021-06-11T11:17:43Z")

</div>

I don’t know much about `opam`, but the shared library is only built for use with the bytecode interpreter. So perhaps if `opam` is only installing the native version, then the shared library will not be built.

Cheers,  
Nicolás

---

<div class="post-metadata">

**Author:** ![maiste](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/maiste/32/3919_2.png) [@maiste](https://discuss.ocaml.org/u/maiste)\
**Post date:** [June 11, 2021, 11:41am UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/3 "2021-06-11T11:41:19Z")

</div>

Thanks for your reply and for the answer!  
My issue is when I try to use it, I have an error because the shared libraries are not included.  
Is there a way to tell dune to not care about them?

---

<div class="post-metadata">

**Author:** ![ivg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ivg/32/103_2.png) [@ivg](https://discuss.ocaml.org/u/ivg)\
**Post date:** [June 11, 2021, 3:18pm UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/4 "2021-06-11T15:18:56Z")

</div>

The .so file shouldn’t be installed as native dynamic library is packaged as cmxs file. A cmxs file is a normal shared library, with several sections specific to OCaml.

> [@maiste](#):
>
> My issue is when I try to use it, I have an error because the shared libraries are not included.  
> Is there a way to tell dune to not care about them?

Probably you’re looking in a wrong direction, what’s that the error that you’re getting? And how do you build and run your program?

> [@nojb](#):
>
> but the shared library is only built for use with the bytecode interpreter.

That’s not true, OCaml supports native dynamic linking since 3.03, IIRC, and is capable of building and loading shared libraries.

---

<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:** [June 11, 2021, 3:53pm UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/5 "2021-06-11T15:53:19Z")

</div>

> [@ivg](#):
>
> That’s not true, OCaml supports native dynamic linking since 3.03, IIRC, and is capable of building and loading shared libraries.

Indeed, I forgot about `.cmxs`! Thanks for the correction.

Best,  
Nicolás

---

<div class="post-metadata">

**Author:** ![maiste](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/maiste/32/3919_2.png) [@maiste](https://discuss.ocaml.org/u/maiste)\
**Post date:** [June 11, 2021, 4:31pm UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/6 "2021-06-11T16:31:56Z")

</div>

> [@ivg](#):
>
> The .so file shouldn’t be installed as native dynamic library is packaged as cmxs file. A cmxs file is a normal shared library, with several sections specific to OCaml.

Is it the case even with c++ stubs? The part which is not built is the static c++ library. The issue is it’s built when I do a `dune build` but not with `opam install` (it uses `dune` to create the package.

> [@ivg](#):
>
> Probably you’re looking in a wrong direction, what’s that the error that you’re getting? And how do you build and run your program?

As the `.so` file is not present, it says `libmammut.so` is missing.

---

<div class="post-metadata">

**Author:** ![ivg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ivg/32/103_2.png) [@ivg](https://discuss.ocaml.org/u/ivg)\
**Post date:** [June 11, 2021, 5:17pm UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/7 "2021-06-11T17:17:20Z")

</div>

> [@maiste](#):
>
> Is it the case even with c++ stubs? The part which is not built is the static c++ library. The issue is it’s built when I do a `dune build` but not with `opam install` (it uses `dune` to create the package.

Yes, because the opam package that is distributing bindings to the library is not responsible for distribution the actual library. In fact, there are two approaches. You can distribute only the bindings code and assume that the bound library is linked by the user code, or you can statically link the bound library and distributed in one big cmxs file.

Before dune, the build systems were able to notice in the META file that an OCaml library has an extra dependency on a foreign shared library and automatically pass the corresponding command-line options during the linking phase. In addition, cma and cmxa files (OCaml library archives) contain information about the libraries that has to be linked and about the C compiler options that has to be used during linking via the `-cclib` and `-ccopt` command-line options.

Unfortunately, the library that you’re using is doing neither so it is you task to specify the extra dependencies1. In general you can use the `link_flags` (or `flags`) stanza, e.g., `(link_flags -cclib -lfoo)` to link the `libfoo.so` library to your library (executable). But in case of `ocaml_mammut` I think you would need to add much more than that, e.g., this is what I think you need to add,

```makefile
-cclib -lstdc++ -cclib -lraplcap-msr -cclib -lsmartgauge -cclib -lusb-1.0 -cclib -lmammut

```

E.g., if you’re building a binary that uses `ocaml_mamut` then add to the executable stanza the following line,

```auto
(flags (:standard -w -49 -cclib -lstdc++ -cclib -lraplcap-msr -cclib -lsmartgauge -cclib -lusb-1.0 -cclib -lmammut))

```

* * *

1) when we link with `libc` or `lm` we don’t have to specify their dependencies as well, it is the responsibility of the linked library to specify their dependencies. So `mamut_ocaml` shall pass those options as `link_flags` when they define the `mammut` library. If they would do this, then you we wouldn’t need to write those options in the code that use their library. I would suggest you to open an issue or suggest a PR with the fix.

---

<div class="post-metadata">

**Author:** ![maiste](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/maiste/32/3919_2.png) [@maiste](https://discuss.ocaml.org/u/maiste)\
**Post date:** [June 11, 2021, 6:13pm UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/8 "2021-06-11T18:13:58Z")

</div>

Thanks for this really detail reply, it helps me a lot! I will see with the maintainer if I can add the flags directly in the library.

I have a last question about your suggestion to embed the library directly in a cmxs file. Is it still possible to do it with `dune` and how should you then link the code in the executable dune?

---

<div class="post-metadata">

**Author:** ![ivg](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/ivg/32/103_2.png) [@ivg](https://discuss.ocaml.org/u/ivg)\
**Post date:** [June 11, 2021, 6:26pm UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/9 "2021-06-11T18:26:31Z")

</div>

> [@maiste](#):
>
> I have a last question about your suggestion to embed the library directly in a cmxs file. Is it still possible to do it with `dune` and how should you then link the code in the executable dune?

Of course, just link statically with the mammut library. You can do it both in `ocaml_mammut` or in your application, if you want to make it self-contained. The only caveat is that the `mammut` library should distribute `.a` files. If they are provided, e.g., there is `libmammut.a` at some directory `/foo/bar/mammut` then passing `-cclib -L -cclib /foo/bar/mammut -cclib libmammut.a` to the `flags` (`link_flags`) stanza will take the libmammut code and copy it into your binary (library). For bytedcode it will create a special `dll<yourlib>.so` library that will be loaded by the OCaml runtime.

---

<div class="post-metadata">

**Author:** ![maiste](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/maiste/32/3919_2.png) [@maiste](https://discuss.ocaml.org/u/maiste)\
**Post date:** [June 11, 2021, 6:31pm UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/10 "2021-06-11T18:31:14Z")

</div>

Ok, I see! Thanks so much for your help!

---

<div class="post-metadata">

**Author:** ![maiste](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/maiste/32/3919_2.png) [@maiste](https://discuss.ocaml.org/u/maiste)\
**Post date:** [June 16, 2021, 8:22am UTC](https://discuss.ocaml.org/t/stubs-c-shared-and-static-libs/7987/11 "2021-06-16T08:22:22Z")

</div>

Hi,  
I’m sorry to reopen this ticket, I seem to still struggle with it ([lib](https://gitlab.com/maiste/tezos-oxymeter)). When I insert the cflags directly in the lib dune file it’s not able to find it whereas when I use it in the example dune file, there is no  
error.

Dune from the lib directory (flags generate errors here) :

```auto
(library
  (public_name tezos_oxymeter)
  (name tezos_oxymeter)
  (flags (:standard -w -49
                    -cclib -lstdc++
                    -cclib -lraplcap-msr
                    -cclib -lsmartgauge
                    -cclib -lusb-1.0
                    -cclib -lmammut
                    -linkall))
  (libraries re
             yojson
             lwt
             lwt.unix
             mammut
             mammut.generated
             data-encoding))

```

Dune from the example directory :

```auto
(executable
  (name main)
  (flags (:standard -w -49
                    -cclib -lstdc++
                    -cclib -lraplcap-msr
                    -cclib -lsmartgauge
                    -cclib -lusb-1.0
                    -cclib -lmammut))
  (libraries tezos_oxymeter))

```

Because of it, I’m not able to build a self contain library… Would you have any suggestions ?
