diff --git a/doc/howto/index.rst b/doc/howto/index.rst index ca3fb49843f..15f85a69552 100644 --- a/doc/howto/index.rst +++ b/doc/howto/index.rst @@ -22,3 +22,4 @@ These guides will help you use Dune's features in your project. bundle toplevel rule-generation + override-default-entrypoint diff --git a/doc/howto/override-default-entrypoint.rst b/doc/howto/override-default-entrypoint.rst new file mode 100644 index 00000000000..3b6be55d9cc --- /dev/null +++ b/doc/howto/override-default-entrypoint.rst @@ -0,0 +1,63 @@ +How to Override the Default C Entrypoint With C Stubs +----------------------------------------------------- + +In some cases, it may be necessary to override the default C entry point of an +OCaml program. For example, this is the case if you want to let your program +handle argument wildcards expansion on Windows. + +Let's consider a trivial "Hello world" program contained in a ``hello.ml`` +file: + +.. code:: ocaml + + let () = print_endline "Hello, world!" + +The default C entry point is a ``main`` function, originally defined in +`runtime/main.c `_. It +can be overriden by defining a ``main`` function that will at some point call +the OCaml runtime. Let's write such a minimal example in a ``main.c`` file: + +.. code:: C + + #include + + #define CAML_INTERNALS + #include "caml/misc.h" + #include "caml/mlvalues.h" + #include "caml/sys.h" + #include "caml/callback.h" + + /* This is the new entry point */ + int main(int argc, char_os **argv) + { + /* Here, we just print a statement */ + printf("Doing stuff before calling the OCaml runtime\n"); + + /* Before calling the OCaml runtime */ + caml_main(argv); + caml_do_exit(0); + return 0; + } + +The :doc:`foreign_stubs ` stanza can be leveraged to +compile and link our OCaml program with the new C entry point defined in +``main.c``: + +.. code:: dune + + (executable + (name hello) + (foreign_stubs + (language c) + (names main))) + +With this ``dune`` file, the whole program can be compiled by merely calling +``dune build``. When run, the output shows that it calls the custom entry point +we defined: + +.. code:: shell-session + + $ dune build + $ _build/default/hello.exe + Doing stuff before calling the OCaml runtime + Hello, world!