caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* C libs from Ocaml libs
@ 2007-11-21  7:43 viktor tron
  2007-11-21  9:45 ` [Caml-list] " Alain Frisch
  0 siblings, 1 reply; 11+ messages in thread
From: viktor tron @ 2007-11-21  7:43 UTC (permalink / raw)
  To: Caml Mailing List

[-- Attachment #1: Type: text/plain, Size: 4416 bytes --]

Dear list,

Let me share with you my frustration over compiling a c library out of an
ocaml project. [apologies for long post]

This is now my third project where an ocaml implementation needs a c binding
and I keep on struggling
with the right build environment.

While it is very well documented how to compile and build applications with
ocaml bindings to
c implementations, the opposite way is a neglected topic.
sections 18.7-8 of the manual
http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html
plus a couple of pages of the o-reilly book is devoted to this topic.
The sporadic info found on mailing lists is not enough so I need your help.

The well known abstract problem is the following:

foo.ml: the ocaml routine root (responsible for foo.cmxa)
foo_export.ml the C API (register callback, exceptions, etc)
foo_stub.c the C bindings referring to the callbacks, containing init code
(foo_wrapper.ml the ocaml wrapper to foo)

clearly what I want is the following:

* foo.cmxa ocaml lib with ocaml entrypoints
* (foo: standalone executable from foo.cmxa and foo_wrapper.ml)
* libfoo: static and dynamic C library out of foo.cmxa, foo_export and
foo_stub

what do I do? now more or less according to the manual:

ocamlc -a <all files> fib.ml
ocamlc -custom -output-obj -o fib_caml.o fib.cma fib_export.ml
ocamlc -c fib_stub.c
cp /usr/local/lib/ocaml/libcamlrun.a fib.a
ar r fib.a fib_caml.o fib_stub.o
ranlib fib.a

or

ocamlc -a <all files> foo.ml
ocamlc -custom -output-obj -o foo_caml.o foo.cma foo_export.ml
ocamlc -c foo_stub.c
libtool -o libfoo.a foo_caml.o foo_stub.o /usr/local/lib/ocaml/libcamlrun.a

and then link the c program with foo

* I know that building on several platforms is always a challange but this
is such a simple routine.
if I have to use random command lines in my Makefile, I run into an autoconf
hell.
is their a truly plantform independent routine to do this?

* can someone explain to me how the how exactly .a file created with .cmxa
differ from an archive?
is it the ocaml sturtup code?

* why does the bytecode need the curses library when linking and why the
native doesn't?

* why does ocamlc have a -custom option and why does ocamlopt does not? do I
need the -custom options at all here?

* what do I do if I don't want to compile the ocaml runtime into my lib,
since they might use several
of my modules so just link at the end with the runtime lib
* what if I want to share ocaml code for the same reason?

and most importantly:

* how do I create dynamic libs, dlls for windows?

In general, I found not much help from the existing build tools:

* OCamlMake does not support creation of c libraries

* omake is serious overkill (after hours of reading through the manual, I
still don't know how the gtk example is relevant, plus omake creates an
extra problem for portability, please correct me if I am wrong)

* ocamlbuild? I have problems with this piece of software. I found it
frustatingly underdocumented and buggy.
I read the manual, help and the -documentation, and still don't understand
anything.
The examples on the wiki page
http://brion.inria.fr/gallium/index.php/C_stub_functions
give 100 lines of ocaml code for a similar problem?
- I still don't know the most basic thing, how to build an output-obj o
file.
- I found no way to convince ocamlbuild to use the local library (in this
example we build
ocamlbuild foo.cmxa
and then would simply want
ocamlopt -o foo foo.cmxa foo_wrapper.ml
but 'ocamlbuild foo_wrapper.native' rebuilds it all the way.

* I even tried to get inpiration from rocaml (a nice ruby binding for ocaml,
which is mediated by a c, and all build is automated, but
it was too complicated to delineate the ruby-relevant things from the
c-ocaml interface)

* why are the c object files end in .o irrespective of whether they are byte
or native?
this makes it impossible to write rules on them?
In fact 'ocamlbuild foo.o' will build both and it overwrites the targets of
the first round!!!
(since it matches both cmo & o and cmx & o rules?)


I know it is a lot of questions, but any help or comment is appreciated.

Something constructive:
Does the community not feel that we should somehow support this export much
more within our existing build tools and documentation? If something
reassuring comes out of this discussion I promise I write up a tutorial.
(At least I understand how to write the code)

Thanks very much.

viktor

[-- Attachment #2: Type: text/html, Size: 5517 bytes --]

^ permalink raw reply	[flat|nested] 11+ messages in thread
* RE: [Caml-list] C libs from Ocaml libs
@ 2007-11-22 16:41 RABIH.ELCHAAR
  0 siblings, 0 replies; 11+ messages in thread
From: RABIH.ELCHAAR @ 2007-11-22 16:41 UTC (permalink / raw)
  To: viktor.tron.ml, caml-list

[-- Attachment #1: Type: text/plain, Size: 5752 bytes --]

Hello Viktor,

I think that some libraries are missing in the link phase.

 

When a x.cmxa is generated, a x.lib is also generated. You need to pass it to the linker when you are generating a c executable or dll, even if you use the .cmxas in your output-obj, because all the relevant code is not just there.

 

I am appending the makefile of some internal code that generated a C Win32 dll.

 

Hope this helps.

 

JAVA_INC=$(JNIINCLUDES)

DIRS=-w y -w p -I +camljava -I +gsl -I +schedule -I +ocamlDM -I ../common/        

LIBS=rschedule.cmxa ocamlDMManager.cmxa jni_init.cmxa common.cmxa 

all: Engine.dll

 

install: all

            cp Engine.dll ../../bin

 

# supposes that the linker has access to the j2sdk lib

# rabih /libpath:"d:/appli/j2sdk1.4.1_05/lib" 

Engine.dll: ocamllib.obj Engine.obj

            link /nologo /dll /out:Engine.dll \

            /libpath:$(OCAML_LIB) /libpath:$(OCAML_CAMLJAVA) /libpath:$(JDKHOME)/lib \

            /libpath:$(OCAML_LIB)/schedule /libpath:$(OCAML_LIB)/ocamlDM /libpath:$(OCAML_LIB)/gsl /NODEFAULTLIB:libc \

            jvm.lib jni.lib  rschedule.lib ocamlDMManager.lib \

            Engine.obj  ocamllib.obj \

            libasmrun.lib libcamljni.lib

 

Engine.obj: Engine.h Engine.c

            cl /c $(JAVA_INC) -I$(OCAML_LIB) Engine.c

 

 

%.cmx: %.mf

            ocamlopt $(DIRS) -c -dtypes $<

 

 

ocamllib.obj:ocaml _Engine.cmx

            ocamlopt -dtypes $(DIRS) -output-obj -o ocamllib.obj  $(LIBS) $^

 

depend:

            echo -n > .depend

            ocamldep $(DIRS) ocaml_Engine.mf >.depend

 

clean:

            rm -f *.obj

            rm -f *.dll

            rm -f *.lib

            rm -f *.exp

            rm -f *.cm*

            rm -f *.h

            rm -f *~

 

include .depend

include ../Makefile.config

 

________________________________

De : caml-list-bounces@yquem.inria.fr [mailto:caml-list-bounces@yquem.inria.fr] De la part de viktor tron
Envoyé : mercredi 21 novembre 2007 19:35
À : Caml Mailing List
Objet : Re: [Caml-list] C libs from Ocaml libs

 

 

On 21/11/2007, Alain Frisch <alain@frisch.fr > wrote:

viktor tron wrote:
> This is super! how is this on MacOS, I recall one of your comment earlier (on this list?)
> that it doesn't work or something.

Everything should work fine under Mac OS X x86. For PowerPC, I believe 
that "ocamlc -output-obj -o XXX.so" should be ok but that "ocamlopt
-output-obj -o XXX.so" does not work.

> well, I tried.
> ar -rs foo_caml.o foo_stub.o
> gcc -o foo_test.native foo_test.c -L. -lchainfreq_native -L/sw/lib/ocaml 

What is the name of the library you want to produce?


sorry, let me be very explicit then:

0) 
I believed that the following 
creates the c object containing: 
(a) main ocaml implementation of foo (b) export API (c) C binding to API (d) ocaml startup code 

$ ocamlopt -output-obj -o foo_caml.o foo.cmxa foo_stub.c foo_export.ml

now I create a lib

$ ar rs libfoo.a foo_caml.o

and happy ever after. Nope.
No matter how I link it with a main c test, I get undefined symbols for startup code 

$ gcc -o foo_test foo_test.c -L. -lfoo -lasmrun

In fact, the following variants don't work:

1) 
$ ocamlopt -output-obj -o foo_caml.o foo.cmxa foo_stub.c foo_export.ml
$ ar -rs libfoo.a /sw/lib/ocaml/libasmrun.a foo_caml.o 
$ gcc -o foo_test foo_test.c -L. -lfoo

2)
$ ocamlopt -output-obj -o foo_caml.o foo.cmxa foo_stub.c foo_export.ml
$ cp /sw/lib/ocaml/libasmrun.a libfoo.a 
$ ar -rs libfoo.a foo_caml.o 
$ gcc -o foo_test foo_test.c -L. -lfoo 

so it seems I have to compile foo_stub.o separately...

but even if I do:

3)
$ ocamlopt -output-obj -o foo_caml.o foo.cmxa foo_stub.c foo_export.ml
$ ocamlopt foo_stub.c
$ ar -rs libfoo.a foo_caml.o foo_stub.o 
$ gcc -o foo_test foo_test.c -L. -lfoo -L/sw/lib/ocaml -lasmrun

4)
$ ocamlopt -output-obj -o foo_caml.o foo.cmxa foo_stub.c foo_export.ml
$ ocamlopt foo_stub.c
$ ar -rs libfoo.a /sw/lib/ocaml/libasmrun.a foo_caml.o 
$ gcc -o foo_test foo_test.c -L. -lfoo

both fail, the only thing that works is when
(a) I compile stub and caml objects separately AND 
(b) use copy to bootstrap the runtime

$ ocamlopt -output-obj -o foo_caml.o foo.cmxa foo_stub.c foo_export.ml
$ ocamlopt foo_stub.c
$ cp /sw/lib/ocaml/libasmrun.a libfoo.a 
$ ar -rs libfoo.a foo_caml.o foo_stub.o
$ gcc -o foo_test foo_test.c -L. -lfoo

In fact ocamlopt does pretty enigmatic things in the background and ar is an entire mystery with this 
copy thing. 
If anyone can make me understand the above, I'd be forever grateful.

thanks
Viktor

 

Ce message et toutes les pieces jointes (ci-apres le "message") sont confidentiels et etablis a l'intention exclusive de ses destinataires. 
Toute utilisation ou diffusion non autorisee est interdite. 
Tout message electronique est susceptible d'alteration. 
Societe Generale Asset Management et ses filiales declinent toute responsabilite au titre de ce message s'il a ete altere, deforme ou falsifie. 
  
Decouvrez l'offre et les services de Societe Generale Asset Management sur le site www.sgam.fr 
  
                                ******** 
  
This message and any attachments (the "message") are confidential and intended solely for the addressees. 
Any unauthorised use or dissemination is prohibited. 
E-mails are susceptible to alteration. 
Neither Societe Generale Asset Management nor any of its subsidiaries or affiliates shall be liable for the message if altered, changed or falsified. 
 
Find out more about Societe Generale Asset Management's proposal on www.sgam.com

[-- Attachment #2: Type: text/html, Size: 17844 bytes --]

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

end of thread, other threads:[~2007-11-26 17:20 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-21  7:43 C libs from Ocaml libs viktor tron
2007-11-21  9:45 ` [Caml-list] " Alain Frisch
2007-11-21 11:21   ` Matthieu Dubuget
2007-11-21 12:05     ` Alain Frisch
2007-11-21 19:48       ` Jon Harrop
2007-11-21 17:06   ` viktor tron
2007-11-21 17:33     ` Alain Frisch
2007-11-21 18:35       ` viktor tron
2007-11-22 17:21         ` Alain Frisch
2007-11-26 17:20         ` Alain Frisch
2007-11-22 16:41 RABIH.ELCHAAR

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