# C code calls OCaml (which uses an external library)

**URL:** <https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048>\
**Category:** Learning\
**Created:** [July 5, 2019, 10:48pm UTC](https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048 "2019-07-05T22:48:39Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bar](https://avatars.discourse-cdn.com/v4/letter/b/b77776/32.png) [@Bar](https://discuss.ocaml.org/u/Bar)\
**Post date:** [July 5, 2019, 10:48pm UTC](https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048/1 "2019-07-05T22:48:39Z")

</div>

Hi,

We are trying to compile the following piece of code that involves both C code and OCaml code.  
The C code calls the OCaml code, which in turns uses Batteries.  
Our problem comes form using such external libraries in OCaml (such as Batteries here).  
Without that everything works fine.  
Here’s the code:

In foo.ml:

* * *

let foo (n : int) = Batteries.String.of\_list []  
let \_ = Callback.register “foo” foo

* * *

In bar.c:

* * *

#include \<caml/mlvalues.h\>  
#include \<caml/callback.h\>  
#include \<caml/memory.h\>

int main(int argc , char \*\*argv) {  
caml\_startup(argv);  
static value \* out = NULL;  
if (out == NULL) { out = caml\_named\_value(“foo”); }  
value v = caml\_callback(\*out, Val\_int(0));  
return 0;  
}

* * *

We tried to compile the code as follows:

* * *

ocamlfind ocamlc -o foo\_obj.o -package unix,bigarray,batteries -output-obj -thread unix.cma bigarray.cma nums.cma batteries.cma foo.ml  
ocamlc -c bar.c  
cc foo\_obj.o bar.o -o foo -L`ocamlc -where` -lcamlrun -ldl -lm -lncurses -lunix -Wall

* * *

Unfortunately, we get the following undefined references:

* * *

/usr/bin/ld: foo\_obj.o:(.data.rel+0xeb8): undefined reference to `caml_ba_reshape' /usr/bin/ld: foo_obj.o:(.data.rel+0xec0): undefined reference to`caml\_ba\_get\_3’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xec8): undefined reference to `caml_ba_get_2' /usr/bin/ld: foo_obj.o:(.data.rel+0xed0): undefined reference to`caml\_ba\_get\_1’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xed8): undefined reference to `caml_ba_get_generic' /usr/bin/ld: foo_obj.o:(.data.rel+0xee0): undefined reference to`caml\_ba\_num\_dims’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xee8): undefined reference to `caml_ba_set_3' /usr/bin/ld: foo_obj.o:(.data.rel+0xef0): undefined reference to`caml\_ba\_slice’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xef8): undefined reference to `caml_ba_dim_3' /usr/bin/ld: foo_obj.o:(.data.rel+0xf00): undefined reference to`caml\_ba\_dim\_2’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf08): undefined reference to `caml_ba_dim_1' /usr/bin/ld: foo_obj.o:(.data.rel+0xf10): undefined reference to`caml\_ba\_kind’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf18): undefined reference to `caml_ba_create' /usr/bin/ld: foo_obj.o:(.data.rel+0xf20): undefined reference to`caml\_ba\_set\_2’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf28): undefined reference to `caml_ba_set_1' /usr/bin/ld: foo_obj.o:(.data.rel+0xf30): undefined reference to`caml\_ba\_layout’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf38): undefined reference to `caml_ba_set_generic' /usr/bin/ld: foo_obj.o:(.data.rel+0xf40): undefined reference to`caml\_ba\_map\_file\_bytecode’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf48): undefined reference to `caml_ba_dim' /usr/bin/ld: foo_obj.o:(.data.rel+0xf50): undefined reference to`caml\_ba\_init’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf58): undefined reference to `set_digit_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0xf60): undefined reference to`mult\_digit\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf68): undefined reference to `blit_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0xf70): undefined reference to`num\_digits\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf78): undefined reference to `create_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0xf80): undefined reference to`div\_digit\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf88): undefined reference to `square_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0xf90): undefined reference to`set\_to\_zero\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xf98): undefined reference to `is_digit_zero' /usr/bin/ld: foo_obj.o:(.data.rel+0xfa0): undefined reference to`is\_digit\_int’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xfa8): undefined reference to `nth_digit_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0xfb0): undefined reference to`div\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xfb8): undefined reference to `add_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0xfc0): undefined reference to`shift\_right\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xfc8): undefined reference to `num_leading_zero_bits_in_digit' /usr/bin/ld: foo_obj.o:(.data.rel+0xfd0): undefined reference to`complement\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xfd8): undefined reference to `compare_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0xfe0): undefined reference to`initialize\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xfe8): undefined reference to `lxor_digit_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0xff0): undefined reference to`lor\_digit\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0xff8): undefined reference to `land_digit_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0x1000): undefined reference to`incr\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0x1008): undefined reference to `set_digit_nat_native' /usr/bin/ld: foo_obj.o:(.data.rel+0x1010): undefined reference to`decr\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0x1018): undefined reference to `shift_left_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0x1020): undefined reference to`mult\_nat’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0x1028): undefined reference to `compare_digits_nat' /usr/bin/ld: foo_obj.o:(.data.rel+0x1030): undefined reference to`is\_digit\_odd’  
/usr/bin/ld: foo\_obj.o:(.data.rel+0x1038): undefined reference to `nth_digit_nat_native' /usr/bin/ld: foo_obj.o:(.data.rel+0x1040): undefined reference to`sub\_nat’

* * *

What are we doing wrong here?

Thanks.

---

<div class="post-metadata">

**Author:** ![lindig](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lindig/32/532_2.png) [@lindig](https://discuss.ocaml.org/u/lindig)\
**Post date:** [July 6, 2019, 9:57am UTC](https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048/2 "2019-07-06T09:57:02Z")

</div>

The symbols with `_ba_` refer to BigArray. So the linker in the call to `cc` can’t seem to find them. Looking at symbols in `*.a` files, I believe they are defined in `stdlib.a`, which you are not linking.

---

<div class="post-metadata">

**Author:** ![Bar](https://avatars.discourse-cdn.com/v4/letter/b/b77776/32.png) [@Bar](https://discuss.ocaml.org/u/Bar)\
**Post date:** [July 6, 2019, 2:02pm UTC](https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048/3 "2019-07-06T14:02:31Z")

</div>

Hi,

Thank you for your reply!

We tried something like that:  
“cc /usr/lib/ocaml/bigarray.a foo\_obj.o bar.o -o foo -L`ocamlc -where` -lcamlrun -ldl -lm -lncurses -lunix -Wall”.  
Unfortunately that did not work. We got the same errors including the \_ba\_errors.

Is that what you meant?

---

<div class="post-metadata">

**Author:** ![lindig](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/lindig/32/532_2.png) [@lindig](https://discuss.ocaml.org/u/lindig)\
**Post date:** [July 6, 2019, 2:10pm UTC](https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048/4 "2019-07-06T14:10:08Z")

</div>

I would try to link `stdlib.a`.

---

<div class="post-metadata">

**Author:** ![let-def](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/let-def/32/2948_2.png) [@let-def](https://discuss.ocaml.org/u/let-def)\
**Post date:** [July 6, 2019, 2:11pm UTC](https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048/5 "2019-07-06T14:11:34Z")

</div>

Or `-lbigarray -lnums` (bigarray for ba symbols, nums for nat ones).

---

<div class="post-metadata">

**Author:** ![dbuenzli](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/dbuenzli/32/18_2.png) [@dbuenzli](https://discuss.ocaml.org/u/dbuenzli)\
**Post date:** [July 6, 2019, 2:17pm UTC](https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048/6 "2019-07-06T14:17:22Z")

</div>

> [@Bar](#):
>
> We tried something like that:  
> “cc /usr/lib/ocaml/bigarray.a foo\_obj.o bar.o -o foo -L `ocamlc -where` -lcamlrun -ldl -lm -lncurses -lunix -Wall”.  
> Unfortunately that did not work. We got the same errors including the \_ba\_errors.

You need to put the archive after the objects that uses it.

---

<div class="post-metadata">

**Author:** ![Bar](https://avatars.discourse-cdn.com/v4/letter/b/b77776/32.png) [@Bar](https://discuss.ocaml.org/u/Bar)\
**Post date:** [July 6, 2019, 8:03pm UTC](https://discuss.ocaml.org/t/c-code-calls-ocaml-which-uses-an-external-library/4048/7 "2019-07-06T20:03:40Z")

</div>

Thank you so very much!

This worked!!!
