How to get OCamlbuild to compile and link a C file to an OCaml project?

I am trying to create the OCaml binary main.native from main.ml , which also uses a single C custom.c file to implement a new primitive. This C file needs to be compiled and linked. Is there a way to do this only with the _tags file? The obvious problem is that OCamlbuild does not detect dependencies when scanning main.ml and, therefore, this dependency should be explicitly said.

 ocamlbuild main.native 

OCamlbuild knows the rule for compiling a * .c file into a * .o file, but I don't know how to add a dependency.

+6
source share
2 answers

There are a number of resources out there .

First, you need to mark main.native to create a dependency on c-stubs and links respectively. (By the way, this assumes that the c-library is called cstub , but it could be anything you want).

_tags :

 <*.{byte,native}> : use_cstub <**/*.cm{x,}a> : use_cstub 

Then in myocamlbuild.ml create a c library dependency with tagged tags,

 dep ["link";"ocaml";"use_cstub"] ["libcstub.a"] 

OCamlbuild has rules for creating library files (* .so and * .a), but you will need to add a list of files to be created in the .clib file,

cstub.clib :

 cobjfile1.o cobjfile2.o ... 

Any header files must also be copied from the main directory to the _build/ directory. This is done by indicating that they depend on compilation in c (in myocamlbuild.ml , where headers is a list of lines that fill the header files in the project.

 dep ["c"; "compile"] headers; 

and, finally, adding flags when linking the project to the c-stub library (also in myocamlbuild.ml ),

 flag ["link";"ocaml";"use_cstub"] (S[A"-dllib";A"-lcstub";A"-cclib";A"-lcstub"]); 
+6
source

I accepted the answer above, but would like to document the solution. As mentioned in the comment, I created a new parameterized linkdep() tag using myocamlbuild.ml :

 open Ocamlbuild_plugin;; dispatch ( function | After_rules -> pdep ["link"] "linkdep" (fun param -> [param]) | _ -> () ) 

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

It depends on the built-in rules for compiling a C file into an object file. However, this will still skip the dependencies on the header files (which I don't have).

+2
source

Source: https://habr.com/ru/post/956898/


All Articles