I'm trying to build an OCaml binary main.native
from main.ml
that also relies on a single C file custom.c
to implement a new primitive. This C file needs to be compiled and linked. Is there a way to do this just with a _tags
file? The obvious problem is that OCamlbuild does not detect the dependency when scanning main.ml
and hence needs to be told explicitly about the dependency.
ocamlbuild main.native
OCamlbuild knows a rule to compile a *.c file to a *.o file but I don't know how to add the dependency.
There are a number of resources out there.
The first thing is that you need to tag the main.native
as to create a dependency on the c-stubs and link accordingly. (By the way, this assumes the c-library is called cstub
, but it can be anything you'd like).
_tags
:
<*.{byte,native}> : use_cstub
<**/*.cm{x,}a> : use_cstub
Then, in myocamlbuild.ml
create a dependency of a c-library to the things tagged,
dep ["link";"ocaml";"use_cstub"] ["libcstub.a"]
OCamlbuild has rules for creating library files (*.so and *.a), but you would need to add a listing of the files to be built against in a .clib
file,
cstub.clib
:
cobjfile1.o
cobjfile2.o
...
Any header files also need to be copied over from the main directory to the _build/
directory. This is done by specifying they are a dependency on compilation in c (in myocamlbuild.ml
, where headers
is a list of strings naming the header files in the project.
dep ["c"; "compile"] headers;
and finally, adding flags to when we link the project with the c-stub library (also in myocamlbuild.ml
),
flag ["link";"ocaml";"use_cstub"] (S[A"-dllib";A"-lcstub";A"-cclib";A"-lcstub"]);
I have accepted the answer above but would like to document the solution. As mentioned in a comment, I have created a new parametrized tag linkdep()
using myocamlbuild.ml
:
open Ocamlbuild_plugin;;
dispatch
( function
| After_rules -> pdep ["link"] "linkdep" (fun param -> [param])
| _ -> ()
)
The newly created tag is used in _tags
to add a link dependency:
<*.ml>: annot
<*.byte>: linkdep(custom_unix_stubs.o),custom
<*.native>: linkdep(custom_unix_stubs.o)
This relies on built-in rules to compile a C file to an object file. However, this would still miss dependencies on header files (which I don't have).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With