caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Including a C library statically in an Ocaml library
@ 2016-01-08 14:14 Malcolm Matalka
  2016-01-08 14:58 ` Christopher Zimmermann
  2016-01-08 15:15 ` David Sheets
  0 siblings, 2 replies; 6+ messages in thread
From: Malcolm Matalka @ 2016-01-08 14:14 UTC (permalink / raw)
  To: caml-list

The core problem I am having is a C library I want to bind has a number
of macros which I need the value of.  Here is how I am trying to solve
it, but perhaps there is a better way:

I have a small C library which gets compiled to libfoo.a which provides
functions that return the macro values, like:

int macro1() { return MACRO1; }

I then have an ocaml library, called ofoo, that uses Ctypes to bind to macro1:

let macro1 = foreign "macro" (void @-> returning int)

Where I am having issues is this small library, I'd prefer it to not
have to be installed on the system but just compiled into the Ocaml
library so that a user just has to link against that library.  Right
now, none of the symbols (macro1) are being included in the library, I'm
guessing because the linker sees no direct use of them.  And I'm not
even sure if I can get it included in the ocaml library.  I'm also not
able to get the libfoo symbols linked into a final executable, I'm
guessing for similar reasons.

What are my options here?

If I've missed any useful information, let me know.  I haven't interoped
much with C directory in Ocaml so I'm not sure what information is
important.

/Malcolm

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

* Re: [Caml-list] Including a C library statically in an Ocaml library
  2016-01-08 14:14 [Caml-list] Including a C library statically in an Ocaml library Malcolm Matalka
@ 2016-01-08 14:58 ` Christopher Zimmermann
  2016-01-08 15:08   ` Malcolm Matalka
  2016-01-08 15:15 ` David Sheets
  1 sibling, 1 reply; 6+ messages in thread
From: Christopher Zimmermann @ 2016-01-08 14:58 UTC (permalink / raw)
  To: caml-list; +Cc: Malcolm Matalka

On Fri, 08 Jan 2016 14:14:22 +0000 Malcolm Matalka <mmatalka@gmail.com>
wrote:

> The core problem I am having is a C library I want to bind has a
> number of macros which I need the value of.  Here is how I am trying
> to solve it, but perhaps there is a better way:
> 
> I have a small C library which gets compiled to libfoo.a which
> provides functions that return the macro values, like:
> 
> int macro1() { return MACRO1; }
> 
> I then have an ocaml library, called ofoo, that uses Ctypes to bind
> to macro1:
> 
> let macro1 = foreign "macro" (void @-> returning int)
> 
> Where I am having issues is this small library, I'd prefer it to not
> have to be installed on the system but just compiled into the Ocaml
> library so that a user just has to link against that library.  Right
> now, none of the symbols (macro1) are being included in the library,

That's no surprise. Macros are evaluated at compile time. You won't see
their name (only their value) in the compiled object file.

> I'm guessing because the linker sees no direct use of them.  And I'm
> not even sure if I can get it included in the ocaml library.  I'm
> also not able to get the libfoo symbols linked into a final
> executable, I'm guessing for similar reasons.
> 
> What are my options here?
> 
> If I've missed any useful information, let me know.  I haven't
> interoped much with C directory in Ocaml so I'm not sure what
> information is important.

You could hardcode the value of the macros into your ocaml code like
this:

let macro1 = 4096;;

But I don't see anything wrong with your approach. If you have really
many macros and don't want to add that many functions you could create 
a static record of all the macro values in your C stub code like this 
(not tested):

value get_constants(value) {
  static value constants[5] = {
    (4 << 10), /* header for block of size 4 */
     Val_long(Macro1),
     Val_long(Macro2),
     NULL,
     Val_long(Macro4)
  };

  if (constants.3 == NULL) {
    constants.3 = caml_copy_string(Macro3);
  }

  return (constants + 1);
}


Christopher



-- 
http://gmerlin.de
OpenPGP: http://gmerlin.de/christopher.pub
F190 D013 8F01 AA53 E080  3F3C F17F B0A1 D44E 4FEE

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

* Re: [Caml-list] Including a C library statically in an Ocaml library
  2016-01-08 14:58 ` Christopher Zimmermann
@ 2016-01-08 15:08   ` Malcolm Matalka
  0 siblings, 0 replies; 6+ messages in thread
From: Malcolm Matalka @ 2016-01-08 15:08 UTC (permalink / raw)
  To: Christopher Zimmermann; +Cc: caml-list

Christopher Zimmermann <christopher@gmerlin.de> writes:

> On Fri, 08 Jan 2016 14:14:22 +0000 Malcolm Matalka <mmatalka@gmail.com>
> wrote:
>
>> The core problem I am having is a C library I want to bind has a
>> number of macros which I need the value of.  Here is how I am trying
>> to solve it, but perhaps there is a better way:
>> 
>> I have a small C library which gets compiled to libfoo.a which
>> provides functions that return the macro values, like:
>> 
>> int macro1() { return MACRO1; }
>> 
>> I then have an ocaml library, called ofoo, that uses Ctypes to bind
>> to macro1:
>> 
>> let macro1 = foreign "macro" (void @-> returning int)
>> 
>> Where I am having issues is this small library, I'd prefer it to not
>> have to be installed on the system but just compiled into the Ocaml
>> library so that a user just has to link against that library.  Right
>> now, none of the symbols (macro1) are being included in the library,
>
> That's no surprise. Macros are evaluated at compile time. You won't see
> their name (only their value) in the compiled object file.

This is why I'm creating a function that returns the macro value.

>
>> I'm guessing because the linker sees no direct use of them.  And I'm
>> not even sure if I can get it included in the ocaml library.  I'm
>> also not able to get the libfoo symbols linked into a final
>> executable, I'm guessing for similar reasons.
>> 
>> What are my options here?
>> 
>> If I've missed any useful information, let me know.  I haven't
>> interoped much with C directory in Ocaml so I'm not sure what
>> information is important.
>
> You could hardcode the value of the macros into your ocaml code like
> this:
>
> let macro1 = 4096;;
>
> But I don't see anything wrong with your approach. If you have really
> many macros and don't want to add that many functions you could create 
> a static record of all the macro values in your C stub code like this 
> (not tested):
>
> value get_constants(value) {
>   static value constants[5] = {
>     (4 << 10), /* header for block of size 4 */
>      Val_long(Macro1),
>      Val_long(Macro2),
>      NULL,
>      Val_long(Macro4)
>   };
>
>   if (constants.3 == NULL) {
>     constants.3 = caml_copy_string(Macro3);
>   }
>
>   return (constants + 1);
> }
>
>
> Christopher

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

* Re: [Caml-list] Including a C library statically in an Ocaml library
  2016-01-08 14:14 [Caml-list] Including a C library statically in an Ocaml library Malcolm Matalka
  2016-01-08 14:58 ` Christopher Zimmermann
@ 2016-01-08 15:15 ` David Sheets
  2016-01-08 15:19   ` Malcolm Matalka
  1 sibling, 1 reply; 6+ messages in thread
From: David Sheets @ 2016-01-08 15:15 UTC (permalink / raw)
  To: Malcolm Matalka; +Cc: O Caml

On Fri, Jan 8, 2016 at 2:14 PM, Malcolm Matalka <mmatalka@gmail.com> wrote:
> The core problem I am having is a C library I want to bind has a number
> of macros which I need the value of.  Here is how I am trying to solve
> it, but perhaps there is a better way:
>
> I have a small C library which gets compiled to libfoo.a which provides
> functions that return the macro values, like:
>
> int macro1() { return MACRO1; }
>
> I then have an ocaml library, called ofoo, that uses Ctypes to bind to macro1:
>
> let macro1 = foreign "macro" (void @-> returning int)
>
> Where I am having issues is this small library, I'd prefer it to not
> have to be installed on the system but just compiled into the Ocaml
> library so that a user just has to link against that library.  Right
> now, none of the symbols (macro1) are being included in the library, I'm
> guessing because the linker sees no direct use of them.  And I'm not
> even sure if I can get it included in the ocaml library.  I'm also not
> able to get the libfoo symbols linked into a final executable, I'm
> guessing for similar reasons.
>
> What are my options here?

I'd recommend using ctypes 0.4+ stub generation support which can bind
macro values and detect struct layout at an early compilation stage.
You can see it in use to do this in my ocaml-unix-errno library
<https://github.com/dsheets/ocaml-unix-errno>. One benefit with this
approach is greater static checking and c <-> ocaml type safety.

If you continue using dynamic bindings, two lonker flags may be of use to you:

--no-as-needed : on recent Ubuntu distributions, gcc automatically
includes the --as-needed flag which drops symbols that are not
referenced. Unfortunately, clang does not understand this flag so you
need to have a conditional in your build system to detect the compiler
in use if you want a cross-platform library.

-E : The Exports local symbols which are statically linked into a
binary into the dynamic symbol table so that they can be found with
dlsym.

You can use these with gcc like -Wl,-E for example.

Hope this helps,

David Sheets


> If I've missed any useful information, let me know.  I haven't interoped
> much with C directory in Ocaml so I'm not sure what information is
> important.
>
> /Malcolm
>
> --
> 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] 6+ messages in thread

* Re: [Caml-list] Including a C library statically in an Ocaml library
  2016-01-08 15:15 ` David Sheets
@ 2016-01-08 15:19   ` Malcolm Matalka
  2016-01-08 15:24     ` David Sheets
  0 siblings, 1 reply; 6+ messages in thread
From: Malcolm Matalka @ 2016-01-08 15:19 UTC (permalink / raw)
  To: David Sheets; +Cc: O Caml

David Sheets <sheets@alum.mit.edu> writes:

> On Fri, Jan 8, 2016 at 2:14 PM, Malcolm Matalka <mmatalka@gmail.com> wrote:
>> The core problem I am having is a C library I want to bind has a number
>> of macros which I need the value of.  Here is how I am trying to solve
>> it, but perhaps there is a better way:
>>
>> I have a small C library which gets compiled to libfoo.a which provides
>> functions that return the macro values, like:
>>
>> int macro1() { return MACRO1; }
>>
>> I then have an ocaml library, called ofoo, that uses Ctypes to bind to macro1:
>>
>> let macro1 = foreign "macro" (void @-> returning int)
>>
>> Where I am having issues is this small library, I'd prefer it to not
>> have to be installed on the system but just compiled into the Ocaml
>> library so that a user just has to link against that library.  Right
>> now, none of the symbols (macro1) are being included in the library, I'm
>> guessing because the linker sees no direct use of them.  And I'm not
>> even sure if I can get it included in the ocaml library.  I'm also not
>> able to get the libfoo symbols linked into a final executable, I'm
>> guessing for similar reasons.
>>
>> What are my options here?
>
> I'd recommend using ctypes 0.4+ stub generation support which can bind
> macro values and detect struct layout at an early compilation stage.
> You can see it in use to do this in my ocaml-unix-errno library
> <https://github.com/dsheets/ocaml-unix-errno>. One benefit with this
> approach is greater static checking and c <-> ocaml type safety.
>
> If you continue using dynamic bindings, two lonker flags may be of use to you:
>
> --no-as-needed : on recent Ubuntu distributions, gcc automatically
> includes the --as-needed flag which drops symbols that are not
> referenced. Unfortunately, clang does not understand this flag so you
> need to have a conditional in your build system to detect the compiler
> in use if you want a cross-platform library.
>
> -E : The Exports local symbols which are statically linked into a
> binary into the dynamic symbol table so that they can be found with
> dlsym.
>
> You can use these with gcc like -Wl,-E for example.

Will these approaches require that I have the C library installed to
compile against any binary using my library or will the symbols be part
of the ocaml library?  In my current version I have a libfoo.a that gets
created in the project and then linked against the library.

>
> Hope this helps,
>
> David Sheets
>
>
>> If I've missed any useful information, let me know.  I haven't interoped
>> much with C directory in Ocaml so I'm not sure what information is
>> important.
>>
>> /Malcolm
>>
>> --
>> 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] 6+ messages in thread

* Re: [Caml-list] Including a C library statically in an Ocaml library
  2016-01-08 15:19   ` Malcolm Matalka
@ 2016-01-08 15:24     ` David Sheets
  0 siblings, 0 replies; 6+ messages in thread
From: David Sheets @ 2016-01-08 15:24 UTC (permalink / raw)
  To: Malcolm Matalka; +Cc: O Caml

On Fri, Jan 8, 2016 at 3:19 PM, Malcolm Matalka <mmatalka@gmail.com> wrote:
> David Sheets <sheets@alum.mit.edu> writes:
>
>> On Fri, Jan 8, 2016 at 2:14 PM, Malcolm Matalka <mmatalka@gmail.com> wrote:
>>> The core problem I am having is a C library I want to bind has a number
>>> of macros which I need the value of.  Here is how I am trying to solve
>>> it, but perhaps there is a better way:
>>>
>>> I have a small C library which gets compiled to libfoo.a which provides
>>> functions that return the macro values, like:
>>>
>>> int macro1() { return MACRO1; }
>>>
>>> I then have an ocaml library, called ofoo, that uses Ctypes to bind to macro1:
>>>
>>> let macro1 = foreign "macro" (void @-> returning int)
>>>
>>> Where I am having issues is this small library, I'd prefer it to not
>>> have to be installed on the system but just compiled into the Ocaml
>>> library so that a user just has to link against that library.  Right
>>> now, none of the symbols (macro1) are being included in the library, I'm
>>> guessing because the linker sees no direct use of them.  And I'm not
>>> even sure if I can get it included in the ocaml library.  I'm also not
>>> able to get the libfoo symbols linked into a final executable, I'm
>>> guessing for similar reasons.
>>>
>>> What are my options here?
>>
>> I'd recommend using ctypes 0.4+ stub generation support which can bind
>> macro values and detect struct layout at an early compilation stage.
>> You can see it in use to do this in my ocaml-unix-errno library
>> <https://github.com/dsheets/ocaml-unix-errno>. One benefit with this
>> approach is greater static checking and c <-> ocaml type safety.
>>
>> If you continue using dynamic bindings, two lonker flags may be of use to you:
>>
>> --no-as-needed : on recent Ubuntu distributions, gcc automatically
>> includes the --as-needed flag which drops symbols that are not
>> referenced. Unfortunately, clang does not understand this flag so you
>> need to have a conditional in your build system to detect the compiler
>> in use if you want a cross-platform library.
>>
>> -E : The Exports local symbols which are statically linked into a
>> binary into the dynamic symbol table so that they can be found with
>> dlsym.
>>
>> You can use these with gcc like -Wl,-E for example.
>
> Will these approaches require that I have the C library installed to
> compile against any binary using my library or will the symbols be part
> of the ocaml library?  In my current version I have a libfoo.a that gets
> created in the project and then linked against the library.

In the stub generation case, you will not have symbols that represent
the macros. Instead, C code will be generated which generates OCaml
code which contains the macro constants.

In the dlsym static linking case, you would build regular cm(x)a files
and a .a file and install them all with ocamlfind. Your users don't
have to know about C libraries or have them installed globally on the
system.

David

>>
>> Hope this helps,
>>
>> David Sheets
>>
>>
>>> If I've missed any useful information, let me know.  I haven't interoped
>>> much with C directory in Ocaml so I'm not sure what information is
>>> important.
>>>
>>> /Malcolm
>>>
>>> --
>>> 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] 6+ messages in thread

end of thread, other threads:[~2016-01-08 15:24 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-08 14:14 [Caml-list] Including a C library statically in an Ocaml library Malcolm Matalka
2016-01-08 14:58 ` Christopher Zimmermann
2016-01-08 15:08   ` Malcolm Matalka
2016-01-08 15:15 ` David Sheets
2016-01-08 15:19   ` Malcolm Matalka
2016-01-08 15:24     ` David Sheets

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