Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Caml-list] Building with OCamlMkLib

102 views
Skip to first unread message

John Whitington

unread,
Jan 20, 2009, 12:04:07 PM1/20/09
to caml...@yquem.inria.fr
Hi Folks,

I'm building a Plain C interface to our PDF libraries, but am stuck.
The idea is to build a library with Ocamlmklib containing the C
wrapper around the ocaml code.

I've used some test files (included below) in place of the real ones.

I can successfully build the library (I'm using OS x / intel):

ocamlc -c -cc "cc" -ccopt " -DNATIVE_CODE -o cpdflibwrapper.o"
cpdflibwrapper.c
ocamlc cpdflibc.mli
ocamlc cpdflibc.ml
ocamlmklib -o camlpdfc cpdflibc.ml cpdflibwrapper.a

(builds dllcamlpdfc.so, camlpdfc.a, camlpdfc.cma, camlpdfc.cmxa)

But trying to link a C program which uses the new library fails. Do I
need to include something else, or have I got the ocamlmklib stage
wrong?

feast:trunk john$ gcc test.c -o test_executable -L. -L/usr/local/lib/
ocaml -lcamlpdfc -lasmrun
Undefined symbols:
"_caml_code_area_end", referenced from:
_caml_code_area_end$non_lazy_ptr in libasmrun.a(signals_asm.o)
_caml_code_area_end$non_lazy_ptr in libasmrun.a(intern.o)
_caml_code_area_end$non_lazy_ptr in libasmrun.a(extern.o)
"_caml_program", referenced from:
_caml_start_program in libasmrun.a(i386.o)
"_caml_bucket_Out_of_memory", referenced from:
_caml_bucket_Out_of_memory$non_lazy_ptr in libasmrun.a(fail.o)

(many more lines)

Here are the input files forming the mixed ocaml/c library:

(* cpdflibc.mli *)
val twice : int -> int

(* cpdflibc.ml *)
let twice x = x * 2

/* cpdflibwrapper.h */
int twice (int);

/* cpdflibwrapper.c */
#include <stdio.h>
#include <caml/memory.h>
#include <caml/callback.h>

int twice_c (int i)
{
CAMLlocal1 (result);
result = caml_callback(*caml_named_value("twice"), Val_int(i));
return(0);
}

And here's the C program which will be using the libary:

/* test.c */
#include <stdio.h>
#include "cpdflibwrapper.h"

int main ()
{
printf("Twice two is %i\n", twice_c(2));
return(0);
}

Here's a zip containing those files: http://www.coherentpdf.com/files.zip

Any ideas?

--
John Whitington
Coherent Graphics Ltd
http://www.coherentpdf.com/

_______________________________________________
Caml-list mailing list. Subscription management:
http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
Archives: http://caml.inria.fr
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs

Alain Frisch

unread,
Jan 20, 2009, 12:22:44 PM1/20/09
to John Whitington, caml...@yquem.inria.fr
John Whitington wrote:
> Hi Folks,
>
> I'm building a Plain C interface to our PDF libraries, but am stuck. The
> idea is to build a library with Ocamlmklib containing the C wrapper
> around the ocaml code.
>
> I've used some test files (included below) in place of the real ones.
>
> I can successfully build the library (I'm using OS x / intel):
>
> ocamlc -c -cc "cc" -ccopt " -DNATIVE_CODE -o cpdflibwrapper.o"
> cpdflibwrapper.c
> ocamlc cpdflibc.mli
> ocamlc cpdflibc.ml
> ocamlmklib -o camlpdfc cpdflibc.ml cpdflibwrapper.a
>
> (builds dllcamlpdfc.so, camlpdfc.a, camlpdfc.cma, camlpdfc.cmxa)
>
> But trying to link a C program which uses the new library fails. Do I
> need to include something else, or have I got the ocamlmklib stage wrong?

You need to include an OCaml "main program" into your library. The
easiest way to build a library that include the OCaml runtime, some
OCaml code and custom C code is the -output-obj option:

ocamlc -output-obj -o camlpdfc.so cpdlibc.cmo cpdflibwrapper.o

Note that cpdflibrwrapper should define a function that calls
caml_startup in order to start the OCaml runtime and run the OCaml code.

If you want to build a static library, you can use "-output-obj -o
camlpdf.o" and then create the library yourself.

-- Alain

Matthieu Dubuget

unread,
Jan 20, 2009, 4:35:58 PM1/20/09
to John Whitington, caml...@inria.fr
My last patch was not usable…
Sorry
files-patch1

Stefano Zacchiroli

unread,
Jan 21, 2009, 9:43:40 AM1/21/09
to caml...@yquem.inria.fr
On Tue, Jan 20, 2009 at 05:03:55PM +0000, John Whitington wrote:
> I'm building a Plain C interface to our PDF libraries, but am
> stuck. The idea is to build a library with Ocamlmklib containing the
> C wrapper around the ocaml code.

I've been working on a similar task these days.

As Alain pointed out you were missing the -output-obj step. The actual
rules I'm using to build the (static) library which is my current
output are something like the following (Makefile excerpt):

libcudf.a: cudf-caml.o cudf.o
cp $(OCAML_LIBDIR)/libcamlrun.a $@
ar r $@ $^

cudf-caml.o: ../_build/cudf.cma ../_build/cudf_c.cmo
ocamlfind ocamlc -linkpkg -output-obj -o $@ $^

where the stuff coming from _build/ is the output of the OCaml-only
part of the library, and libcudf.a is the final C library to be
delivered to C programmers.

The real code from which this comes from is available at [1].

Note that the C programmers will then need to link in a peculiar way,
here are my current instructions for them:

cc -o test test.c `pkg-config --cflags cudf` `pkg-config --cflags cudf`

Which expands to something schematic like:

cc -o test test.c <INCLUDE PATHS> <LIB PATHS> -lcudf -lm -ldl -lunix -lncurses <OTHER -l FOR EXTERNAL LIBS>

The glitch here is that test.c, which contains the invocation to
caml_startup, must appear *before* -lcamlrun, as AFAICT it needs to
override the main() defined there. If you try to put it at the end of
the linking line, linking will fail.

Cheers.

[1] http://gforge.info.ucl.ac.be/plugins/scmsvn/viewcvs.php/trunk/updb/libcudf/c-lib/?root=mancoosi

--
Stefano Zacchiroli -o- PhD in Computer Science \ PostDoc @ Univ. Paris 7
zack@{upsilon.cc,pps.jussieu.fr,debian.org} -<>- http://upsilon.cc/zack/
Dietro un grande uomo c'è ..| . |. Et ne m'en veux pas si je te tutoie
sempre uno zaino ...........| ..: |.... Je dis tu à tous ceux que j'aime

John Whitington

unread,
Jan 22, 2009, 10:21:52 AM1/22/09
to caml...@yquem.inria.fr
Hi.

On 20 Jan 2009, at 17:03, John Whitington wrote:
> I'm building a Plain C interface to our PDF libraries, but am stuck.
> The idea is to build a library with Ocamlmklib containing the C
> wrapper around the ocaml code.

Thanks to those who helped me here - I finally settled on a modified
version of what's given in 18.8 in the manual.

Here are the new files:

http://www.coherentpdf.com/solution.tar.bz2

And here's what we ended up with...

ocamlc cpdflibc.mli
ocamlopt cpdflibc.ml
ocamlc cpdflibwrapper.c
ocamlopt -output-obj -o cpdflibc.o cpdflibc.cmx
cp /usr/local/lib/ocaml/libasmrun.a cpdflib.a
ar r cpdflib.a cpdflibc.o cpdflibwrapper.o

..producing the final cpdflib.a with which we can do...

cc -o test test.c cpdflib.a

..to use the library.

With Thanks,

0 new messages