caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] static C library of wrappers: compilation issues
@ 2012-04-26  7:58 Xavier ALLAMIGEON
  2012-04-26  8:33 ` Török Edwin
  0 siblings, 1 reply; 5+ messages in thread
From: Xavier ALLAMIGEON @ 2012-04-26  7:58 UTC (permalink / raw)
  To: caml-list

Dear caml-list,

I'd like to build a static C library implementing an interface to an 
OCaml library, but I get some compilation errors. Here's an example of 
the problem.

1) The ml_code.* files contain a hello_world function which I'd like to 
provide in C.

<ml_code.ml>
let ml_hello_world () =
   print_endline "Hello world!"

let _ =
   Callback.register "ml_hello_world" ml_hello_world

<ml_code.mli>
val ml_hello_world: unit -> unit

2) On the C part, I created .c/.h files calling the ml function with 
camlback:
<c_code.c>
#include <caml/callback.h>
#include <caml/memory.h>

void init(void) {
   char* dummy = '\0';
   caml_main(&dummy);
}

void c_hello_world(void) {
   CAMLparam0();
   static value *closure_ml_hello_world = NULL;
   if (closure_ml_hello_world == NULL) {
     closure_ml_hello_world = caml_named_value("ml_hello_world");
   }
   caml_callback(*closure_ml_hello_world, Val_unit);
   CAMLreturn0;
}

<c_code.h>
void init(void);
void c_hello_world(void);

3) Finally, I created a test file in C:
<test.c>
#include "c_code.h"

int main(int argc, char **argv) {
   init();
   c_hello_world();
}

Here's the way I'm compiling everything. It builds a libhello_world.a 
static library from ml_code.obj.o and c_code.o.
ocamlc -c ml_code.mli
ocamlopt -c ml_code.ml
ocamlopt -output-obj ml_code.cmx -o ml_code.obj.o
gcc -c c_code.c -I"`ocamlc -where`"
ar rcs libhello_world.a ml_code.obj.o c_code.o
gcc -o test -L. -L"`ocamlc -where`" test.c -lhello_world -lasmrun -lm -ldl

The compilation error happens at the last line, where I get the 
following messages:
/home/allamigeon/Applications/godi/lib/ocaml/std-lib/libasmrun.a(startup.o): 
In function `caml_main':
startup.c:(.text+0x239): undefined reference to `caml_data_segments'
startup.c:(.text+0x243): undefined reference to `caml_data_segments'
startup.c:(.text+0x249): undefined reference to `caml_data_segments'
startup.c:(.text+0x297): undefined reference to `caml_code_segments'
startup.c:(.text+0x2a5): undefined reference to `caml_code_segments'
startup.c:(.text+0x2b3): undefined reference to `caml_code_segments'
startup.c:(.text+0x2c9): undefined reference to `caml_code_segments'
startup.c:(.text+0x2ce): undefined reference to `caml_code_segments'
/home/allamigeon/Applications/godi/lib/ocaml/std-lib/libasmrun.a(roots.o): 
In function `caml_init_frame_descriptors':
roots.c:(.text+0x22b): undefined reference to `caml_frametable'
roots.c:(.text+0x23a): undefined reference to `caml_frametable'
/home/allamigeon/Applications/godi/lib/ocaml/std-lib/libasmrun.a(roots.o): 
In function `caml_do_roots':
roots.c:(.text+0x3a6): undefined reference to `caml_globals'
roots.c:(.text+0x3b2): undefined reference to `caml_globals'
/home/allamigeon/Applications/godi/lib/ocaml/std-lib/libasmrun.a(roots.o): 
In function `caml_oldify_local_roots':
roots.c:(.text+0x505): undefined reference to `caml_globals'
roots.c:(.text+0x511): undefined reference to `caml_globals'
/home/allamigeon/Applications/godi/lib/ocaml/std-lib/libasmrun.a(amd64.o): 
In function `caml_start_program':
(.text+0x251): undefined reference to `caml_program'
...

Which is really weird is that the problem happens only with Linux, and 
not with Mac OS. Of course, if I replace the last line by:
gcc -o test -L"`ocamlc -where`" test.c ml_code.obj.o c_code.o -lasmrun 
-lm -ldl
then it works like a charm:
./test
"Hello world!"

Any idea?

Thanks in advance for your help!

Xavier

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] static C library of wrappers: compilation issues
  2012-04-26  7:58 [Caml-list] static C library of wrappers: compilation issues Xavier ALLAMIGEON
@ 2012-04-26  8:33 ` Török Edwin
  2012-04-26 10:08   ` Xavier ALLAMIGEON
  0 siblings, 1 reply; 5+ messages in thread
From: Török Edwin @ 2012-04-26  8:33 UTC (permalink / raw)
  To: caml-list

On 04/26/2012 10:58 AM, Xavier ALLAMIGEON wrote:
> Dear caml-list,
> 
> I'd like to build a static C library implementing an interface to an OCaml library, but I get some compilation errors. Here's an example of the problem.
> 
> 1) The ml_code.* files contain a hello_world function which I'd like to provide in C.
> 
> <ml_code.ml>
> let ml_hello_world () =
>   print_endline "Hello world!"
> 
> let _ =
>   Callback.register "ml_hello_world" ml_hello_world
> 
> <ml_code.mli>
> val ml_hello_world: unit -> unit
> 
> 2) On the C part, I created .c/.h files calling the ml function with camlback:
> <c_code.c>
> #include <caml/callback.h>
> #include <caml/memory.h>
> 
> void init(void) {
>   char* dummy = '\0';
>   caml_main(&dummy);
> }
> 
> void c_hello_world(void) {
>   CAMLparam0();
>   static value *closure_ml_hello_world = NULL;
>   if (closure_ml_hello_world == NULL) {
>     closure_ml_hello_world = caml_named_value("ml_hello_world");
>   }
>   caml_callback(*closure_ml_hello_world, Val_unit);
>   CAMLreturn0;
> }
> 
> <c_code.h>
> void init(void);
> void c_hello_world(void);
> 
> 3) Finally, I created a test file in C:
> <test.c>
> #include "c_code.h"
> 
> int main(int argc, char **argv) {
>   init();
>   c_hello_world();
> }
> 
> Here's the way I'm compiling everything. It builds a libhello_world.a static library from ml_code.obj.o and c_code.o.
> ocamlc -c ml_code.mli
> ocamlopt -c ml_code.ml
> ocamlopt -output-obj ml_code.cmx -o ml_code.obj.o
> gcc -c c_code.c -I"`ocamlc -where`"
> ar rcs libhello_world.a ml_code.obj.o c_code.o
> gcc -o test -L. -L"`ocamlc -where`" test.c -lhello_world -lasmrun -lm -ldl

You need -Wl,--whole-archive -Wl,--no-whole-archive around the link of your .a, like this:
gcc -o test -L. -L"`ocamlc -where`" test.c -Wl,--whole-archive -lhello_world -Wl,--no-whole-archive -lasmrun -lm -ldl

Otherwise the functions from your .a are dropped because nothing else before it needs it (-lasmrun would, but its after your .a).


Best regards,
--Edwin

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] static C library of wrappers: compilation issues
  2012-04-26  8:33 ` Török Edwin
@ 2012-04-26 10:08   ` Xavier ALLAMIGEON
  2012-04-26 12:23     ` Alain Frisch
  0 siblings, 1 reply; 5+ messages in thread
From: Xavier ALLAMIGEON @ 2012-04-26 10:08 UTC (permalink / raw)
  To: caml-list

Dear Edwin,

Le 26/04/12 10:33, Török Edwin a écrit :
>> Here's the way I'm compiling everything. It builds a libhello_world.a static library from ml_code.obj.o and c_code.o.
>> ocamlc -c ml_code.mli
>> ocamlopt -c ml_code.ml
>> ocamlopt -output-obj ml_code.cmx -o ml_code.obj.o
>> gcc -c c_code.c -I"`ocamlc -where`"
>> ar rcs libhello_world.a ml_code.obj.o c_code.o
>> gcc -o test -L. -L"`ocamlc -where`" test.c -lhello_world -lasmrun -lm -ldl
>
> You need -Wl,--whole-archive -Wl,--no-whole-archive around the link of your .a, like this:
> gcc -o test -L. -L"`ocamlc -where`" test.c -Wl,--whole-archive -lhello_world -Wl,--no-whole-archive -lasmrun -lm -ldl
Thanks a lot, it works now!

> Otherwise the functions from your .a are dropped because nothing else before it needs it (-lasmrun would, but its after your .a).
What do you mean exactly? I imagine that test.o needs some functions of 
the libhello_world.a. But I don't see why libasmrun would need some 
other functions of libhello_world...

What about the following alternative where libasmrun is directly 
appended to the .a file?
cp "`ocamlc -where`"/libasmrun.a libhello_world.a
ar rcs libhello_world.a ml_code.obj.o c_code.o
gcc -o test -L. -L"`ocamlc -where`" test.c -lhello_world -lm -ldl

Best regards.
Xavier

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] static C library of wrappers: compilation issues
  2012-04-26 10:08   ` Xavier ALLAMIGEON
@ 2012-04-26 12:23     ` Alain Frisch
  2012-04-26 14:30       ` Xavier ALLAMIGEON
  0 siblings, 1 reply; 5+ messages in thread
From: Alain Frisch @ 2012-04-26 12:23 UTC (permalink / raw)
  To: Xavier ALLAMIGEON; +Cc: caml-list

On 04/26/2012 12:08 PM, Xavier ALLAMIGEON wrote:
> What do you mean exactly? I imagine that test.o needs some functions of
> the libhello_world.a. But I don't see why libasmrun would need some
> other functions of libhello_world...

Well, this is the case. libasmrun contains the runtime system for OCaml 
code (compiled with ocamlopt) and, as you can see in the error message 
from the linker, it depends on symbols provided by the OCaml program. 
For instance, the garbage collector (in libasmrum) needs to find special 
symbols, to locate some data structures (in libhello_world.a) created by 
the compiler.

> What about the following alternative where libasmrun is directly
> appended to the .a file?
> cp "`ocamlc -where`"/libasmrun.a libhello_world.a
> ar rcs libhello_world.a ml_code.obj.o c_code.o
> gcc -o test -L. -L"`ocamlc -where`" test.c -lhello_world -lm -ldl

This looks fine to me.

-- Alain

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] static C library of wrappers: compilation issues
  2012-04-26 12:23     ` Alain Frisch
@ 2012-04-26 14:30       ` Xavier ALLAMIGEON
  0 siblings, 0 replies; 5+ messages in thread
From: Xavier ALLAMIGEON @ 2012-04-26 14:30 UTC (permalink / raw)
  To: Alain Frisch; +Cc: caml-list

Le 26/04/12 14:23, Alain Frisch a écrit :
> On 04/26/2012 12:08 PM, Xavier ALLAMIGEON wrote:
>> What do you mean exactly? I imagine that test.o needs some functions of
>> the libhello_world.a. But I don't see why libasmrun would need some
>> other functions of libhello_world...
>
> Well, this is the case. libasmrun contains the runtime system for OCaml
> code (compiled with ocamlopt) and, as you can see in the error message
> from the linker, it depends on symbols provided by the OCaml program.
> For instance, the garbage collector (in libasmrum) needs to find special
> symbols, to locate some data structures (in libhello_world.a) created by
> the compiler.
Ok, now I understand, thanks a lot for your explanation.

Best regards.
Xavier

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-04-26 14:30 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-26  7:58 [Caml-list] static C library of wrappers: compilation issues Xavier ALLAMIGEON
2012-04-26  8:33 ` Török Edwin
2012-04-26 10:08   ` Xavier ALLAMIGEON
2012-04-26 12:23     ` Alain Frisch
2012-04-26 14:30       ` Xavier ALLAMIGEON

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