Generating C code from OCaml ppx

(I guess the answer is “no!” but let’s ask the question in case anyone has any ideas …)

nbdkit has a concept of “debug flags”. From C code, a debug flag is just a global int with a specially formatted name.

eg. the debug flag -D foo.bar=1 would be:

int foo_debug_bar;

(nbdkit uses dlsym to find the symbol in the program symbol table and set the int value directly. These flags don’t have to be registered.)

Translating this concept into OCaml is awkward, manual and error-prone. Here’s my attempt which consists of some C code containing the debug flag and an accessor function which gets called from OCaml to read the value:

Ideally all of that could be generated somehow, so naturally I’m thinking that maybe PPX can do it. Can PPX generate C code? I don’t see anything obvious in ppxlib.

A corollary question is whether this could all be done in pure OCaml. The problem is having OCaml create an extern symbol with a very specific name (by default OCaml symbols appear in the symbol table but they all have the wrong form like camlFoo__bar_123). And the content of the symbol is another issue since nbdkit expects it to be an int, but OCaml would expect it to be a block.

Any thoughts or ideas gratefully received …

My assumption is that you can’t use PPXes to write a separate C file. Well … as a side-effect of running the PPX you can write to a file but that sounds brittle.

Although I didn’t document my use cases in my recent DkCoder scripting article ([ANN] DkCoder 0.1.0), I have one use case where I need to compile OCaml into larger C executables while simultaneously not requiring a C compiler. Eventually I’ll be adding a feature to do linking (irrelevant to you) and do some light symbol modifications (perhaps relevant) inside DkCoder.

I have been looking into LIEF to perform those symbol modifications on existing ELF/Mach-O/PE libraries: 04 - ELF Hooking — LIEF Documentation. Kinda like patchelf but cross-platform and not as buggy. (The linked example is Python but it has a C++ API and a limited C API). So …

  1. Perhaps a small make_nbkit_ocaml_plugin executable can take your users’ OCaml-compiled libraries and add/rename/duplicate the symbols you need to make it a full-fledged nbdkit plugin. LIEF can help do that.
  2. If your plugin needs are light enough that bytecode compiled plugins are sufficient, ping me offline.