Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stubgen: support cross compilation of generated modules #666

Open
mbacarella opened this issue Mar 19, 2021 · 3 comments
Open

stubgen: support cross compilation of generated modules #666

mbacarella opened this issue Mar 19, 2021 · 3 comments

Comments

@mbacarella
Copy link

Hi there,

One way of using ctypes stubgen involves building and running this OCaml program:

let () =
  print_endline "#include <mpg123.h>";
  Cstubs_structs.write_c Format.std_formatter
    (module Mpg123_c_type_descriptions.Types)
;;

that outputs a C program like this:

#include <mpg123.h>
#include <stdio.h>
#include <stddef.h>
#include "ctypes_cstubs_internals.h"

int main(void)
{

  puts("include Ctypes");
  puts("let lift x = x");
  puts("open Ctypes_static");
  puts("");
  puts("let rec field : type t a. t typ -> string -> a typ -> (a, t) field =");
  puts("  fun s fname ftype -> match s, fname with");
  puts("  | Struct ({ tag = \"`Id3v2\"} as s'), \"comment\" ->");
  ctypes_printf("    let f = {ftype; fname; foffset = %zu} in \n",
               offsetof(mpg123_id3v2, comment));
  puts("    (s'.fields <- BoxedField f :: s'.fields; f)");
  puts("  | Struct ({ tag = \"`Id3v2\"} as s'), \"genre\" ->");
  ctypes_printf("    let f = {ftype; fname; foffset = %zu} in \n",
               offsetof(mpg123_id3v2, genre));
  puts("    (s'.fields <- BoxedField f :: s'.fields; f)");
  puts("  | Struct ({ tag = \"`Id3v2\"} as s'), \"year\" ->");
  ctypes_printf("    let f = {ftype; fname; foffset = %zu} in \n",
               offsetof(mpg123_id3v2, year));
  puts("    (s'.fields <- BoxedField f :: s'.fields; f)");
  puts("  | Struct ({ tag = \"`Id3v2\"} as s'), \"album\" ->");
  ctypes_printf("    let f = {ftype; fname; foffset = %zu} in \n",
               offsetof(mpg123_id3v2, album));
  puts("    (s'.fields <- BoxedField f :: s'.fields; f)");
  puts("  | Struct ({ tag = \"`Id3v2\"} as s'), \"artist\" ->");
  ctypes_printf("    let f = {ftype; fname; foffset = %zu} in \n",
               offsetof(mpg123_id3v2, artist));
...
  return 0;
}

which, when built and run outputs an ocaml module that should be built into your project to use the C stubs.

This doesn't work for cross compilation. I notice @whitequark did some sweet hack to get ctypes itself to cross compile #383

Would be nice to do something like this for ctypes users as well. I would like to add this to dune's upcoming native ctypes rules generation support ocaml/dune#3905

Any thoughts on proceeding?

@nojb
Copy link

nojb commented Mar 19, 2021

Note that the "hack" that you mention is already in dune's codebase, it is used in configurator, see https://github.com/ocaml/dune/blob/bdfe5291bf2e080d64d8543c41ba55dd281bee22/otherlibs/configurator/src/v1.ml#L531-L537 and the code around it.

@mbacarella
Copy link
Author

mbacarella commented Mar 19, 2021

To be clear I mean hack in the best possible meaning of the term :)

It's true dune does do something like this to discover definitions and values from compiled C code but it is not apparently easily adapted to letting us pluck that substantial OCaml module out of a compiled binary. Also Cstubs_structs.write_c_for_cross_compilation seems like a better home for it.

@yallop
Copy link
Owner

yallop commented Mar 20, 2021

This would be nice to have, and Cstubs_structs.write_c_for_cross_compilation seems like a reasonable place to put it.

One question is whether to switch the whole process over to use @whitequark's approach or maintain two distinct flows for type stubs generation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants