caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Static linking via Ctypes?
@ 2014-03-25 14:54 dbenjamin
  2014-03-25 15:04 ` Bruno Deferrari
  2014-03-25 15:10 ` Daniel Bünzli
  0 siblings, 2 replies; 12+ messages in thread
From: dbenjamin @ 2014-03-25 14:54 UTC (permalink / raw)
  To: caml-list

I'm using Ctypes to interface with a dynamic library, but in addition to the
interface provided the library I have some helper functions (written in C,
against the same library) that I'd also like to call via Ctypes.  Is there any
way to achieve this via static linking or am I required to build another
shared object?

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 14:54 [Caml-list] Static linking via Ctypes? dbenjamin
@ 2014-03-25 15:04 ` Bruno Deferrari
  2014-03-25 15:11   ` Dan Benjamin
  2014-03-25 15:10 ` Daniel Bünzli
  1 sibling, 1 reply; 12+ messages in thread
From: Bruno Deferrari @ 2014-03-25 15:04 UTC (permalink / raw)
  To: dbenjamin; +Cc: caml-list

On Tue, Mar 25, 2014 at 11:54 AM,  <dbenjamin@janestreet.com> wrote:
> I'm using Ctypes to interface with a dynamic library, but in addition to the
> interface provided the library I have some helper functions (written in C,
> against the same library) that I'd also like to call via Ctypes.  Is there any
> way to achieve this via static linking or am I required to build another
> shared object?
>

Static linking works. I was in this same situation yesterday, and
adding the .o files that were generated from C sources to the linking
step did the trick.

If you are trying to link a .a file, you may have to pass the
-force_load option to the linker to force it to include it, otherwise
it may see that none of the symbols there are being referenced
directly and decide to not include it (this happened to me when using
clang in OSX).

> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs



-- 
BD

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 14:54 [Caml-list] Static linking via Ctypes? dbenjamin
  2014-03-25 15:04 ` Bruno Deferrari
@ 2014-03-25 15:10 ` Daniel Bünzli
  1 sibling, 0 replies; 12+ messages in thread
From: Daniel Bünzli @ 2014-03-25 15:10 UTC (permalink / raw)
  To: dbenjamin; +Cc: caml-list

Le mardi, 25 mars 2014 à 15:54, dbenjamin@janestreet.com a écrit :
> I'm using Ctypes to interface with a dynamic library, but in addition to the
> interface provided the library I have some helper functions (written in C,
> against the same library) that I'd also like to call via Ctypes. Is there any
> way to achieve this via static linking or am I required to build another
> shared object?

If you are using ctype's libffi backend you don't need in theory to build a shared dllmylib.so shared object to put in ocaml's lib/stublib. However in practice this is still useful to do even if that shared object is empty as it allows you to record the correct link flags for the dlled C library you bind to.  Doing so allows your users to simply use the ocamlfind package or #require it in the toplevel and everything works correctly, no C link flags to mess with when the binding is used.

This empty dll could be the place to put your helper functions. See this comment on how to proceed:

https://github.com/ocamllabs/ocaml-ctypes/issues/51#issuecomment-30729675

e.g. in that case you would put your helper functions in that empty tsdl_stub.c file.  

Best,

Daniel



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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 15:04 ` Bruno Deferrari
@ 2014-03-25 15:11   ` Dan Benjamin
  2014-03-25 15:24     ` David Sheets
  0 siblings, 1 reply; 12+ messages in thread
From: Dan Benjamin @ 2014-03-25 15:11 UTC (permalink / raw)
  To: Bruno Deferrari; +Cc: caml-list

I am passing -force_load, as well as --whole-archive (in case that
makes a difference), and I have the following situation:

- readelf -s shows that the function that I wish to call exists in the
executable
- running the executable results in Dl.DL_error("undefined symbol")
for the same function, corresponding to the line of code where I call
Foreign.foreign.

Am I going about this wrongly?

On Tue, Mar 25, 2014 at 11:04 AM, Bruno Deferrari <utizoc@gmail.com> wrote:
> On Tue, Mar 25, 2014 at 11:54 AM,  <dbenjamin@janestreet.com> wrote:
>> I'm using Ctypes to interface with a dynamic library, but in addition to the
>> interface provided the library I have some helper functions (written in C,
>> against the same library) that I'd also like to call via Ctypes.  Is there any
>> way to achieve this via static linking or am I required to build another
>> shared object?
>>
>
> Static linking works. I was in this same situation yesterday, and
> adding the .o files that were generated from C sources to the linking
> step did the trick.
>
> If you are trying to link a .a file, you may have to pass the
> -force_load option to the linker to force it to include it, otherwise
> it may see that none of the symbols there are being referenced
> directly and decide to not include it (this happened to me when using
> clang in OSX).
>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa.inria.fr/sympa/arc/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>
>
>
> --
> BD

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 15:11   ` Dan Benjamin
@ 2014-03-25 15:24     ` David Sheets
  2014-03-25 17:55       ` Dan Benjamin
  0 siblings, 1 reply; 12+ messages in thread
From: David Sheets @ 2014-03-25 15:24 UTC (permalink / raw)
  To: Dan Benjamin; +Cc: Bruno Deferrari, O Caml

On Tue, Mar 25, 2014 at 3:11 PM, Dan Benjamin <dbenjamin@janestreet.com> wrote:
> I am passing -force_load, as well as --whole-archive (in case that
> makes a difference), and I have the following situation:
>
> - readelf -s shows that the function that I wish to call exists in the
> executable
> - running the executable results in Dl.DL_error("undefined symbol")
> for the same function, corresponding to the line of code where I call
> Foreign.foreign.
>
> Am I going about this wrongly?

I did

<https://github.com/dsheets/ocaml-unix-unistd/blob/master/lib/unix_unistd_stubs.c#L61>

and

<https://github.com/dsheets/ocaml-unix-unistd/blob/master/lib/ctypes/unix_unistd.ml#L32>

to require a static link without stub generation in addition to
ocamlmklib on the .ml and .o files.

Unfortunately, this is not very portable (or sane). I believe that
<https://github.com/ocamllabs/ocaml-ctypes/issues/96> may be related.

Hope this helps,

David

> On Tue, Mar 25, 2014 at 11:04 AM, Bruno Deferrari <utizoc@gmail.com> wrote:
>> On Tue, Mar 25, 2014 at 11:54 AM,  <dbenjamin@janestreet.com> wrote:
>>> I'm using Ctypes to interface with a dynamic library, but in addition to the
>>> interface provided the library I have some helper functions (written in C,
>>> against the same library) that I'd also like to call via Ctypes.  Is there any
>>> way to achieve this via static linking or am I required to build another
>>> shared object?
>>>
>>
>> Static linking works. I was in this same situation yesterday, and
>> adding the .o files that were generated from C sources to the linking
>> step did the trick.
>>
>> If you are trying to link a .a file, you may have to pass the
>> -force_load option to the linker to force it to include it, otherwise
>> it may see that none of the symbols there are being referenced
>> directly and decide to not include it (this happened to me when using
>> clang in OSX).
>>
>>> --
>>> Caml-list mailing list.  Subscription management and archives:
>>> https://sympa.inria.fr/sympa/arc/caml-list
>>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>
>>
>>
>> --
>> BD
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 15:24     ` David Sheets
@ 2014-03-25 17:55       ` Dan Benjamin
  2014-03-25 21:19         ` Jeremy Yallop
  0 siblings, 1 reply; 12+ messages in thread
From: Dan Benjamin @ 2014-03-25 17:55 UTC (permalink / raw)
  To: David Sheets; +Cc: Bruno Deferrari, O Caml

That does work, thanks very much.  Are there plans to add anything
similar to Ctypes?

On Tue, Mar 25, 2014 at 11:24 AM, David Sheets <sheets@alum.mit.edu> wrote:
> On Tue, Mar 25, 2014 at 3:11 PM, Dan Benjamin <dbenjamin@janestreet.com> wrote:
>> I am passing -force_load, as well as --whole-archive (in case that
>> makes a difference), and I have the following situation:
>>
>> - readelf -s shows that the function that I wish to call exists in the
>> executable
>> - running the executable results in Dl.DL_error("undefined symbol")
>> for the same function, corresponding to the line of code where I call
>> Foreign.foreign.
>>
>> Am I going about this wrongly?
>
> I did
>
> <https://github.com/dsheets/ocaml-unix-unistd/blob/master/lib/unix_unistd_stubs.c#L61>
>
> and
>
> <https://github.com/dsheets/ocaml-unix-unistd/blob/master/lib/ctypes/unix_unistd.ml#L32>
>
> to require a static link without stub generation in addition to
> ocamlmklib on the .ml and .o files.
>
> Unfortunately, this is not very portable (or sane). I believe that
> <https://github.com/ocamllabs/ocaml-ctypes/issues/96> may be related.
>
> Hope this helps,
>
> David
>
>> On Tue, Mar 25, 2014 at 11:04 AM, Bruno Deferrari <utizoc@gmail.com> wrote:
>>> On Tue, Mar 25, 2014 at 11:54 AM,  <dbenjamin@janestreet.com> wrote:
>>>> I'm using Ctypes to interface with a dynamic library, but in addition to the
>>>> interface provided the library I have some helper functions (written in C,
>>>> against the same library) that I'd also like to call via Ctypes.  Is there any
>>>> way to achieve this via static linking or am I required to build another
>>>> shared object?
>>>>
>>>
>>> Static linking works. I was in this same situation yesterday, and
>>> adding the .o files that were generated from C sources to the linking
>>> step did the trick.
>>>
>>> If you are trying to link a .a file, you may have to pass the
>>> -force_load option to the linker to force it to include it, otherwise
>>> it may see that none of the symbols there are being referenced
>>> directly and decide to not include it (this happened to me when using
>>> clang in OSX).
>>>
>>>> --
>>>> Caml-list mailing list.  Subscription management and archives:
>>>> https://sympa.inria.fr/sympa/arc/caml-list
>>>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>>>> Bug reports: http://caml.inria.fr/bin/caml-bugs
>>>
>>>
>>>
>>> --
>>> BD
>>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa.inria.fr/sympa/arc/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 17:55       ` Dan Benjamin
@ 2014-03-25 21:19         ` Jeremy Yallop
  2014-03-25 21:37           ` Milan Stanojević
  0 siblings, 1 reply; 12+ messages in thread
From: Jeremy Yallop @ 2014-03-25 21:19 UTC (permalink / raw)
  To: Dan Benjamin; +Cc: David Sheets, Bruno Deferrari, O Caml

David Sheets <sheets@alum.mit.edu> wrote:
> I did
>
> <https://github.com/dsheets/ocaml-unix-unistd/blob/master/lib/unix_unistd_stubs.c#L61>
>
> and
>
> <https://github.com/dsheets/ocaml-unix-unistd/blob/master/lib/ctypes/unix_unistd.ml#L32>
>
> to require a static link without stub generation in addition to
> ocamlmklib on the .ml and .o files.
>
> Unfortunately, this is not very portable (or sane).

On 25/03/2014, Dan Benjamin <dbenjamin@janestreet.com> wrote:
> That does work, thanks very much.  Are there plans to add anything
> similar to Ctypes?

Not exactly, since the stub generation support in the next ctypes
release resolves these issues in a different way.  In the current
release (0.2.3) setting up foreign calls and linking are both entirely
dynamic.  Stub generation will make it possible to link statically as
well.

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 21:19         ` Jeremy Yallop
@ 2014-03-25 21:37           ` Milan Stanojević
  2014-03-25 23:14             ` Jeremy Yallop
  0 siblings, 1 reply; 12+ messages in thread
From: Milan Stanojević @ 2014-03-25 21:37 UTC (permalink / raw)
  To: Jeremy Yallop; +Cc: Dan Benjamin, David Sheets, Bruno Deferrari, O Caml

> Not exactly, since the stub generation support in the next ctypes
> release resolves these issues in a different way.  In the current
> release (0.2.3) setting up foreign calls and linking are both entirely
> dynamic.  Stub generation will make it possible to link statically as
> well.

Can you tell us how would this work exactly?
Let's say I have a function "foo" in my C file (that I want to link
statically) and I want to give use it in ocaml with a ctype (void @->
returning int)
What would I need to say in my ocaml program and do I have to tell
anything to my build system?

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 21:37           ` Milan Stanojević
@ 2014-03-25 23:14             ` Jeremy Yallop
  2014-03-26 16:24               ` Travis Brady
  2014-03-26 17:25               ` Milan Stanojević
  0 siblings, 2 replies; 12+ messages in thread
From: Jeremy Yallop @ 2014-03-25 23:14 UTC (permalink / raw)
  To: Milan Stanojević; +Cc: Dan Benjamin, David Sheets, Bruno Deferrari, O Caml

I wrote:
> Not exactly, since the stub generation support in the next ctypes
> release resolves these issues in a different way.  In the current
> release (0.2.3) setting up foreign calls and linking are both entirely
> dynamic.  Stub generation will make it possible to link statically as
> well.

Milan Stanojević asked:
> Can you tell us how would this work exactly?
> Let's say I have a function "foo" in my C file (that I want to link
> statically) and I want to give use it in ocaml with a ctype (void @->
> returning int)
> What would I need to say in my ocaml program and do I have to tell
> anything to my build system?

With the current release of ctypes we'd bind 'foo' like this:

   let f = foreign "foo" (void @-> returning int)

The 'foreign' function searches for the symbol "foo" and sets up the
call; the return value is an OCaml function that we can call
immediately.

   val f : unit -> int

With stub generation as implemented in the git master branch the call
to 'foreign' changes slightly.  Instead of calling 'foreign' just
once, we're going to call it once for each stage of generation.  The
way we do this is to abstract over 'foreign' with a functor.  (Note
the similarity to the original binding of 'f' above.)

  module Bindings (F : Cstubs.FOREIGN) =
  struct
     let f = F.foreign "foo" (void @-> returning int)
  end

The first application of the functor generates C:

  Cstubs.write_c std_formatter ~prefix:"foo_" (module Bindings)

The output is a wrapper for the C function 'foo' that marshals and
unmarshals arguments and return values as needed.

The second application generates OCaml:

  Cstubs.write_ml std_formatter ~prefix:"foo_" (module Bindings)

The output is an OCaml module that we can pass to 'Bindings' for the
third and final application, which links together the declaration of
'f' and the generated code:

  Bindings(Generated_ML)

As with the dynamic binding, this gives us an OCaml function that we
can call without further ado:

  val f : unit -> int

The build process is reasonably straightforward.  Since we're
generating code, there are more steps than with the dynamic version,
but we're less likely to need obscure linker flags.  A typical
approach is to place the bindings functor in one file --
foo_binding.ml, say:

   module Bindings(F : Cstubs.FOREIGN) =
   struct
     let foo = F.foreign "foo" Ctypes.(void @-> returning int)
   end

and the calls to 'write_c' and 'write_ml' other files.  I'll put the
call to 'write_c' along with code to print out the headers used in
generate_c.ml:

   let () =
     print_endline "#include <ctypes/cstubs_internals.h>";
     print_endline "#include \"foo.h\"";
     Cstubs.write_c Format.std_formatter ~prefix:"foo_"
       (module Foo_binding.Bindings)

The call to 'write_ml' goes in generate_ml.ml:

   let () = Cstubs.write_ml Format.std_formatter ~prefix:"foo_"
     (module Foo_binding.Bindings)

Then we can compile and run the two programs to generate the stub code:

  $ ocamlfind ocamlc -c -package ctypes.stubs \
     foo_binding.ml generate_c.ml generate_ml.ml
  $ ocamlfind ocamlc -o generate_ml.native -linkpkg -package ctypes.stubs \
     foo_binding.cmo generate_ml.cmo
  $ ./generate_ml.native > generated.ml
  $ ocamlfind ocamlc -o generate_c.native -linkpkg -package ctypes.stubs \
     foo_binding.cmo generate_c.cmo
  $ ./generate_c.native > generated_c_stubs.c

We can then compile the stub code and link it in with the bindings
functor and the library containing 'foo':

  $ ocamlfind ocamlc -c -package ctypes.stubs -I `ocamlc -where`/.. \
     generated_c_stubs.c generated.ml
  $ ocamlfind ocamlmklib -o foo -linkpkg -package ctypes.stubs \
     generated_c_stubs.o generated.cmo foo_binding.cmo -L. -lfoo

Finally, we can load the code and call the 'foo' function:

   $ ocaml -short-paths
           OCaml version 4.01.0

   # #use "topfind";;
   [...]
   # #require "ctypes.stubs";;
   [...]
   # #load "foo.cma";;
   # include Foo_binding.Bindings(Generated);;
   val foo : unit -> int = <fun>
   # foo ();;
   foo called
   - : int = 3

The full stub generation interface (which is actually just the
'write_ml' and 'write_c' functions) is here:

   https://github.com/ocamllabs/ocaml-ctypes/blob/1e1634/src/cstubs/cstubs.mli

Jeremy

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 23:14             ` Jeremy Yallop
@ 2014-03-26 16:24               ` Travis Brady
  2014-03-26 17:17                 ` Daniel Bünzli
  2014-03-26 17:25               ` Milan Stanojević
  1 sibling, 1 reply; 12+ messages in thread
From: Travis Brady @ 2014-03-26 16:24 UTC (permalink / raw)
  To: Jeremy Yallop
  Cc: Milan Stanojević,
	Dan Benjamin, David Sheets, Bruno Deferrari, O Caml

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

This thread is timely for me because I'm attempting to get my ctypes-based
liblinear[1] bindings to behave (with oasis) but thus far have come up
short.
I've followed the instructions in [2] and tried to crib from onanomsg and
ocaml-picosat, but am only able to support either the toplevel OR linking
in binaries.  But not both.
So currently I can make binaries, but I'd love to be able to #require this
in utop for interactive ipython-like usage.

Is there a canonical solution to this problem for oasis users?
I'm considering trying what jane st did with re2 and bundling liblinear up
with my bindings and cribbing from their build process, but ideally this
would all just work with oasis.

thank you
Travis

[1] https://github.com/travisbrady/oliblinear
[2]
https://github.com/ocamllabs/ocaml-ctypes/issues/51#issuecomment-30729675




On Tue, Mar 25, 2014 at 6:14 PM, Jeremy Yallop <yallop@gmail.com> wrote:

> I wrote:
> > Not exactly, since the stub generation support in the next ctypes
> > release resolves these issues in a different way.  In the current
> > release (0.2.3) setting up foreign calls and linking are both entirely
> > dynamic.  Stub generation will make it possible to link statically as
> > well.
>
> Milan Stanojević asked:
> > Can you tell us how would this work exactly?
> > Let's say I have a function "foo" in my C file (that I want to link
> > statically) and I want to give use it in ocaml with a ctype (void @->
> > returning int)
> > What would I need to say in my ocaml program and do I have to tell
> > anything to my build system?
>
> With the current release of ctypes we'd bind 'foo' like this:
>
>    let f = foreign "foo" (void @-> returning int)
>
> The 'foreign' function searches for the symbol "foo" and sets up the
> call; the return value is an OCaml function that we can call
> immediately.
>
>    val f : unit -> int
>
> With stub generation as implemented in the git master branch the call
> to 'foreign' changes slightly.  Instead of calling 'foreign' just
> once, we're going to call it once for each stage of generation.  The
> way we do this is to abstract over 'foreign' with a functor.  (Note
> the similarity to the original binding of 'f' above.)
>
>   module Bindings (F : Cstubs.FOREIGN) =
>   struct
>      let f = F.foreign "foo" (void @-> returning int)
>   end
>
> The first application of the functor generates C:
>
>   Cstubs.write_c std_formatter ~prefix:"foo_" (module Bindings)
>
> The output is a wrapper for the C function 'foo' that marshals and
> unmarshals arguments and return values as needed.
>
> The second application generates OCaml:
>
>   Cstubs.write_ml std_formatter ~prefix:"foo_" (module Bindings)
>
> The output is an OCaml module that we can pass to 'Bindings' for the
> third and final application, which links together the declaration of
> 'f' and the generated code:
>
>   Bindings(Generated_ML)
>
> As with the dynamic binding, this gives us an OCaml function that we
> can call without further ado:
>
>   val f : unit -> int
>
> The build process is reasonably straightforward.  Since we're
> generating code, there are more steps than with the dynamic version,
> but we're less likely to need obscure linker flags.  A typical
> approach is to place the bindings functor in one file --
> foo_binding.ml, say:
>
>    module Bindings(F : Cstubs.FOREIGN) =
>    struct
>      let foo = F.foreign "foo" Ctypes.(void @-> returning int)
>    end
>
> and the calls to 'write_c' and 'write_ml' other files.  I'll put the
> call to 'write_c' along with code to print out the headers used in
> generate_c.ml:
>
>    let () =
>      print_endline "#include <ctypes/cstubs_internals.h>";
>      print_endline "#include \"foo.h\"";
>      Cstubs.write_c Format.std_formatter ~prefix:"foo_"
>        (module Foo_binding.Bindings)
>
> The call to 'write_ml' goes in generate_ml.ml:
>
>    let () = Cstubs.write_ml Format.std_formatter ~prefix:"foo_"
>      (module Foo_binding.Bindings)
>
> Then we can compile and run the two programs to generate the stub code:
>
>   $ ocamlfind ocamlc -c -package ctypes.stubs \
>      foo_binding.ml generate_c.ml generate_ml.ml
>   $ ocamlfind ocamlc -o generate_ml.native -linkpkg -package ctypes.stubs \
>      foo_binding.cmo generate_ml.cmo
>   $ ./generate_ml.native > generated.ml
>   $ ocamlfind ocamlc -o generate_c.native -linkpkg -package ctypes.stubs \
>      foo_binding.cmo generate_c.cmo
>   $ ./generate_c.native > generated_c_stubs.c
>
> We can then compile the stub code and link it in with the bindings
> functor and the library containing 'foo':
>
>   $ ocamlfind ocamlc -c -package ctypes.stubs -I `ocamlc -where`/.. \
>      generated_c_stubs.c generated.ml
>   $ ocamlfind ocamlmklib -o foo -linkpkg -package ctypes.stubs \
>      generated_c_stubs.o generated.cmo foo_binding.cmo -L. -lfoo
>
> Finally, we can load the code and call the 'foo' function:
>
>    $ ocaml -short-paths
>            OCaml version 4.01.0
>
>    # #use "topfind";;
>    [...]
>    # #require "ctypes.stubs";;
>    [...]
>    # #load "foo.cma";;
>    # include Foo_binding.Bindings(Generated);;
>    val foo : unit -> int = <fun>
>    # foo ();;
>    foo called
>    - : int = 3
>
> The full stub generation interface (which is actually just the
> 'write_ml' and 'write_c' functions) is here:
>
>
> https://github.com/ocamllabs/ocaml-ctypes/blob/1e1634/src/cstubs/cstubs.mli
>
> Jeremy
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>

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

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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-26 16:24               ` Travis Brady
@ 2014-03-26 17:17                 ` Daniel Bünzli
  0 siblings, 0 replies; 12+ messages in thread
From: Daniel Bünzli @ 2014-03-26 17:17 UTC (permalink / raw)
  To: Travis Brady
  Cc: Jeremy Yallop, Milan Stanojević,
	Dan Benjamin, David Sheets, Bruno Deferrari, O Caml



Le mercredi, 26 mars 2014 à 17:24, Travis Brady a écrit :

> So currently I can make binaries, but I'd love to be able to #require this in utop for interactive ipython-like usage.

What's the error ? Isn't it maybe because the stublib isn't installed in whathever .opam/$SWITCH/lib/stublib ?  

If you didn't install yet you can try to make it look it up in your build dir by adding that directory to CAML_LD_LIBRARY_PATH, see:

http://caml.inria.fr/pub/docs/manual-ocaml-4.01/runtime.html#sec256

Otherwise I'd suggest making it first working without oasis where you have control and understanding of what you do. You can then try to figure out later if you can retro fit what you have done in that cumbersome tool.  

Best,

Daniel



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

* Re: [Caml-list] Static linking via Ctypes?
  2014-03-25 23:14             ` Jeremy Yallop
  2014-03-26 16:24               ` Travis Brady
@ 2014-03-26 17:25               ` Milan Stanojević
  1 sibling, 0 replies; 12+ messages in thread
From: Milan Stanojević @ 2014-03-26 17:25 UTC (permalink / raw)
  To: Jeremy Yallop; +Cc: Dan Benjamin, David Sheets, Bruno Deferrari, O Caml

Interesting. Thanks for the explanation.

Just wanted to add that what David Sheets suggested worked for us
(Jane Street) without need for any special linker flags apart from
what our build system already does for C files which I think is pretty
standard (compiles all C files into a library that is then linked into
the packed ocaml library).
But it's just one specific linux distribution




On Tue, Mar 25, 2014 at 7:14 PM, Jeremy Yallop <yallop@gmail.com> wrote:
> I wrote:
>> Not exactly, since the stub generation support in the next ctypes
>> release resolves these issues in a different way.  In the current
>> release (0.2.3) setting up foreign calls and linking are both entirely
>> dynamic.  Stub generation will make it possible to link statically as
>> well.
>
> Milan Stanojević asked:
>> Can you tell us how would this work exactly?
>> Let's say I have a function "foo" in my C file (that I want to link
>> statically) and I want to give use it in ocaml with a ctype (void @->
>> returning int)
>> What would I need to say in my ocaml program and do I have to tell
>> anything to my build system?
>
> With the current release of ctypes we'd bind 'foo' like this:
>
>    let f = foreign "foo" (void @-> returning int)
>
> The 'foreign' function searches for the symbol "foo" and sets up the
> call; the return value is an OCaml function that we can call
> immediately.
>
>    val f : unit -> int
>
> With stub generation as implemented in the git master branch the call
> to 'foreign' changes slightly.  Instead of calling 'foreign' just
> once, we're going to call it once for each stage of generation.  The
> way we do this is to abstract over 'foreign' with a functor.  (Note
> the similarity to the original binding of 'f' above.)
>
>   module Bindings (F : Cstubs.FOREIGN) =
>   struct
>      let f = F.foreign "foo" (void @-> returning int)
>   end
>
> The first application of the functor generates C:
>
>   Cstubs.write_c std_formatter ~prefix:"foo_" (module Bindings)
>
> The output is a wrapper for the C function 'foo' that marshals and
> unmarshals arguments and return values as needed.
>
> The second application generates OCaml:
>
>   Cstubs.write_ml std_formatter ~prefix:"foo_" (module Bindings)
>
> The output is an OCaml module that we can pass to 'Bindings' for the
> third and final application, which links together the declaration of
> 'f' and the generated code:
>
>   Bindings(Generated_ML)
>
> As with the dynamic binding, this gives us an OCaml function that we
> can call without further ado:
>
>   val f : unit -> int
>
> The build process is reasonably straightforward.  Since we're
> generating code, there are more steps than with the dynamic version,
> but we're less likely to need obscure linker flags.  A typical
> approach is to place the bindings functor in one file --
> foo_binding.ml, say:
>
>    module Bindings(F : Cstubs.FOREIGN) =
>    struct
>      let foo = F.foreign "foo" Ctypes.(void @-> returning int)
>    end
>
> and the calls to 'write_c' and 'write_ml' other files.  I'll put the
> call to 'write_c' along with code to print out the headers used in
> generate_c.ml:
>
>    let () =
>      print_endline "#include <ctypes/cstubs_internals.h>";
>      print_endline "#include \"foo.h\"";
>      Cstubs.write_c Format.std_formatter ~prefix:"foo_"
>        (module Foo_binding.Bindings)
>
> The call to 'write_ml' goes in generate_ml.ml:
>
>    let () = Cstubs.write_ml Format.std_formatter ~prefix:"foo_"
>      (module Foo_binding.Bindings)
>
> Then we can compile and run the two programs to generate the stub code:
>
>   $ ocamlfind ocamlc -c -package ctypes.stubs \
>      foo_binding.ml generate_c.ml generate_ml.ml
>   $ ocamlfind ocamlc -o generate_ml.native -linkpkg -package ctypes.stubs \
>      foo_binding.cmo generate_ml.cmo
>   $ ./generate_ml.native > generated.ml
>   $ ocamlfind ocamlc -o generate_c.native -linkpkg -package ctypes.stubs \
>      foo_binding.cmo generate_c.cmo
>   $ ./generate_c.native > generated_c_stubs.c
>
> We can then compile the stub code and link it in with the bindings
> functor and the library containing 'foo':
>
>   $ ocamlfind ocamlc -c -package ctypes.stubs -I `ocamlc -where`/.. \
>      generated_c_stubs.c generated.ml
>   $ ocamlfind ocamlmklib -o foo -linkpkg -package ctypes.stubs \
>      generated_c_stubs.o generated.cmo foo_binding.cmo -L. -lfoo
>
> Finally, we can load the code and call the 'foo' function:
>
>    $ ocaml -short-paths
>            OCaml version 4.01.0
>
>    # #use "topfind";;
>    [...]
>    # #require "ctypes.stubs";;
>    [...]
>    # #load "foo.cma";;
>    # include Foo_binding.Bindings(Generated);;
>    val foo : unit -> int = <fun>
>    # foo ();;
>    foo called
>    - : int = 3
>
> The full stub generation interface (which is actually just the
> 'write_ml' and 'write_c' functions) is here:
>
>    https://github.com/ocamllabs/ocaml-ctypes/blob/1e1634/src/cstubs/cstubs.mli
>
> Jeremy
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

end of thread, other threads:[~2014-03-26 17:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-25 14:54 [Caml-list] Static linking via Ctypes? dbenjamin
2014-03-25 15:04 ` Bruno Deferrari
2014-03-25 15:11   ` Dan Benjamin
2014-03-25 15:24     ` David Sheets
2014-03-25 17:55       ` Dan Benjamin
2014-03-25 21:19         ` Jeremy Yallop
2014-03-25 21:37           ` Milan Stanojević
2014-03-25 23:14             ` Jeremy Yallop
2014-03-26 16:24               ` Travis Brady
2014-03-26 17:17                 ` Daniel Bünzli
2014-03-26 17:25               ` Milan Stanojević
2014-03-25 15:10 ` Daniel Bünzli

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