Hi, I’m looking for a tool that automatically computes the fine-grained dependencies between the
.ml files of a dune project. Does such a tool exist already ?
More precisely: given a dune-managed source tree, the tool I’m looking for would give me a dependency graph between the modules (along with actual paths of the
.cmt files) that belong to the dune project, and also dependencies to the modules of the standard library, and to the modules of external libraries as well. In other words : a complete, self-contained dependency graph.
The purpose of this dependency graph is to provide a structured description of a source tree, that serves as a starting point to perform analyses on a complete source tree.
To avoid reinventing the wheel, I have skimmed related projects, that solve similar problems (but not quite the problem I’m looking for). Here is what I’ve found so far:
dune describe: this command provided by dune gives a description of a dune project, that includes dependencies at the level of dune libraries or executables. This is already a very good start. Unfortunately, some info are missing (dependencies to external libraries, or to modules of the standard library) and the dependencies are not fine-grained enough (e.g., within a library, the dependencies between
.mlfiles are not provided).
dune-deps: this tool produces a graph that describes the structure of a dune project (at the level of dune libraries and executables). It does so by transforming the output of
dune describeinto a
.dotgraph. It has the same limitations as
dune describe + ocamldep: dune produces
.ml.dfiles, that contain the output of
ocamldep, and give the modules a given
.mlfile depends on. Unfortunately, not all
.ml.dcompanion file in the
_builddirectory (this is the case of files generated by dune, that have the
.ml-genextension). Also, the dependency info does not include the paths of the modules (though I could probably retrieve the paths, based on the module names and on the include dirs).
Use info recorded in
.cmi) files: here I must admit I do not really understand what is recorded in the list of “imported interfaces” or “required globals”. I am surprised that there are more modules in the “imported interfaces” than what is detected by
ocamldep, for instance, and also that a module always seems to belong to the list of its own “imported interfaces”. Is there any extensive documentation on that part somewhere, that I might have missed ?
cmgraph: this tool exploits the info recorded in compiled files (
.cmx) to produce a fine-grained dependency graph. Looking at the source code, it seems some heuristic is used to determine which dependencies are actually relevant. I have not been able to compile this tool, unfortunately (it depends on
ppx_meta_conv, that requires caml < 4.03.0, for which the installation of
omakefails… again, I might have missed an obvious solution).
codept: this tool aims at computing dependency information, that is more precise than what
ocamldepcould provide. While it could serve as a replacement for
ocamldep, it does not seem to fit my needs : for example, like
ocamldep, it was not designed to understand the structure of a dune project.
Have I missed a tool or technique that is already available or could be easily adapted ? Or have I drawn any incorrect conclusions for some items in the list ? Any feedback and advice is welcome.
I feel that, ideally, the build system (dune) could provide more specific info about the dependency graph : after all, it is dune’s job to discover the dependencies, and an external tool could only do its best to mimic dune’s behavior (and keeping such tool consistent with dune could be painful). Do you think
dune describe or the new dune RPC system could be extended to support this ?