Am Dienstag, den 10.09.2013, 12:41 +0000 schrieb David Allsopp: > Tom Ridge wrote: > > Dear List, > > > > I want to use my ocaml code from a C program. > > > > I have read the section "Interfacing C with OCaml" in the manual: > > > > http://caml.inria.fr/pub/docs/manual-ocaml/manual033.html > > > > The example in section 19.8 works fine. The compilation commands are (in a > > Makefile; OCAMLPATH points to /home/tr61/.opam/4.00.1): > > > > ocamlc -custom -output-obj -o modcaml.o mod.ml > > ocamlc -c modwrap.c > > cp $(OCAMLPATH)/lib/ocaml/libcamlrun.a mod.a > > ar r mod.a modcaml.o modwrap.o > > cc -o prog main.c mod.a -lcurses -lm -ldl > > > > (I had to add -lm and -ldl to get the example to work). > > The documentation is arguably deficient here - you can get those two extra switches from the output of ocamlc -config (cf bytecomp_c_libraries and native_c_libraries) > > > If my code makes use of the OCaml Unix library, I do: > > > > cc -o prog main.c mod.a -lcurses -lm -ldl -L$(OCAMLPATH)/lib/ocaml -lunix > > > > And if my code makes use of threads, I do: > > > > cc -o prog main.c mod.a -lcurses -lm -ldl -L$(OCAMLPATH)/lib/ocaml -lunix > > -lthreads -lpthread > > > > So far, so good. The real code I want to use makes use of the Core > > library. The compilation commands I finally got working are: > > > > ocamlfind ocamlc -package core -package str -linkpkg -thread -custom - > > output-obj -o modcaml.o pqueue.ml mod.ml > > ocamlc -c modwrap.c > > cp $(OCAMLPATH)/lib/ocaml/libcamlrun.a mod.a > > ar r mod.a modcaml.o modwrap.o > > cc -pthread -Xlinker --allow-multiple-definition -o prog main.c mod.a - > > lcurses -lm -ldl -lpthread -L$(OCAMLPATH)/lib/ocaml -lunix -lthreads - > > lbigarray -lcamlstr -lnums -L$(OCAMLPATH)/lib/core_kernel - > > lcore_kernel_stubs -L$(OCAMLPATH)/lib/core -lcore_stubs - > > L$(OCAMLPATH)/lib/bin_prot -lbin_prot_stubs -lrt > > > > For the last "cc" command, tt took quite a long time to figure out all > > these flags and options (I do not know very much about linkers etc). > > The errors I got were: > > General tip for these: ocamlobjinfo library.cm[x]a will include in its output the required additional linking switches will save a few of these... > > Adding -verbose (or using ocamlfind query) will allow you to locate the appropriate .cma or .cmxa for the findlib package in question. > > I don't *think* that ocamlfind itself can help you with compilation in this direction (i.e. compiling OCaml to be used in C). No, it cannot help here, because it cannot look inside the cma's to find out the linker flags. What I recommend here is to create an empty dummy.ml module, and do ocamlfind ocamlc -verbose -package core,str -linkpkg -linkall -thread -custom which will print the final cc command ocamlc uses itself to link the program. You can even intercept this command if you also pass -cc ./my_own_script so that this script is called instead of cc. Just keep all the -L and -l switches (and select other ones like -pthread). The order of the -l switches matters: if you pass -lfoo -lbar to the linker, library foo can use bar but not the other way round (note that this is the opposite order you are used from ocaml). > > /home/tr61/.opam/4.00.1/lib/core/libcore_stubs.a(unix_stubs.o): In > > function `unix_initgroups': > > unix_stubs.c:(.text+0x3b90): multiple definition of `unix_initgroups' > > /home/tr61/.opam/4.00.1/lib/ocaml/libunix.a(initgroups.o):initgroups.c:(.t > > ext+0x0): > > first defined here > > /home/tr61/.opam/4.00.1/lib/core/libcore_stubs.a(unix_stubs.o): In > > function `unix_nice': > > unix_stubs.c:(.text+0x46bc): multiple definition of `unix_nice' > > /home/tr61/.opam/4.00.1/lib/ocaml/libunix.a(nice.o):nice.c:(.text+0x0): > > first defined here > > > > fixed by adding -Xlinker --allow-multiple-definition to cc options > > Are you definitely allowed to use both Core and Unix in the same program (i.e. can you link on OCaml program that way?). Core is an stdlib replacement so I wouldn't expect to be allowed to use both standard library and core modules in the same program. If you are supposed to be able to do, then that sounds like a possible bug in core... Looks like Core uses the same symbols as Unix. IMHO a bug in Core. Of course you can use Core with other libraries (which will in turn use the normal Unix module), because it's not a stdlib replacement, and you have to open Core before you can see its definitions. Gerd > > > -- > > > > My real question is: what command *should* I be using to compile my > > example? Or is the above more-or-less expected? > > They look fine - I hope that the ocamlobjinfo tip allows for less trial-and-error in the future! > > > David > -- ------------------------------------------------------------ Gerd Stolpmann, Darmstadt, Germany gerd@gerd-stolpmann.de My OCaml site: http://www.camlcity.org Contact details: http://www.camlcity.org/contact.html Company homepage: http://www.gerd-stolpmann.de ------------------------------------------------------------