caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: David Allsopp <dra-news@metastack.com>
To: caml-list <caml-list@inria.fr>
Subject: RE: [Caml-list] Using OCaml from C
Date: Tue, 10 Sep 2013 12:41:55 +0000	[thread overview]
Message-ID: <E51C5B015DBD1348A1D85763337FB6D9CCB9C92C@Remus.metastack.local> (raw)
In-Reply-To: <CABooLwMEP38swFGFG5NCH-_fsR6gGbYvRPn1d5SCcGv=3Jp16w@mail.gmail.com>

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).

> --
> 
> /home/tr61/.opam/4.00.1/lib/ocaml/libthreads.a(st_stubs_b.o): In function
> `caml_thread_initialize':
> st_stubs.c:(.text+0xed1): undefined reference to `pthread_atfork
> 
> fixed by adding -pthread after cc command
> 
> --
> 
> /home/tr61/.opam/4.00.1/lib/core/libcore_stubs.a(unix_stubs.o): In
> function `unix_clock_gettime':
> unix_stubs.c:(.text+0x2776): undefined reference to `clock_gettime'
> 
> I had -lrt after -lpthread, but the error was still reported; when I moved
> -lrt to end of command line things seemed to work; why?

Linker options for libraries should always be last (see gcc docs). I expect (but I'm sure a compiler expert can confirm/deny) that it's because the linker only pulls in symbols which it knows are needed (or at least it's allowed to do that - i.e. you need to specify foo.o requiring symbol bar before specifying -lfoo).

> --
> 
> /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...

> --
> 
> 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 

  reply	other threads:[~2013-09-10 12:41 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-10 12:21 Tom Ridge
2013-09-10 12:41 ` David Allsopp [this message]
2013-09-10 13:21   ` Gerd Stolpmann
2013-09-10 13:09 ` Stéphane Glondu
2013-09-10 13:30   ` David Allsopp
2013-09-10 13:59     ` Tom Ridge
2013-09-10 14:21     ` Stéphane Glondu
     [not found]       ` <CABooLwPmKWc0KAOZ2weuwAfBbXUUKhBa7rxJ+=LASVL-0KeBmA@mail.gmail.com>
2013-09-10 17:21         ` Fwd: " Tom Ridge
2013-09-10 17:27           ` Adrien Nader
2013-09-12  9:51             ` Stéphane Glondu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=E51C5B015DBD1348A1D85763337FB6D9CCB9C92C@Remus.metastack.local \
    --to=dra-news@metastack.com \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).