C code calls OCaml (which uses an external library)

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 -Locamlc -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 tocaml_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 tocaml_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 tocaml_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 tocaml_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 tocaml_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 tocaml_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 tocaml_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 tocaml_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 tocaml_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 tocaml_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 tomult_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 tonum_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 todiv_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 toset_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 tois_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 todiv_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 toshift_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 tocomplement_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 toinitialize_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 tolor_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 toincr_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 todecr_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 tomult_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 tois_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 tosub_nat’


What are we doing wrong here?

Thanks.

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.

Hi,

Thank you for your reply!

We tried something like that:
“cc /usr/lib/ocaml/bigarray.a foo_obj.o bar.o -o foo -Locamlc -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?

I would try to link stdlib.a.

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

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

1 Like

Thank you so very much!

This worked!!!