Using CMake to compile OCaml code

BLOT: I would like to know how can I trigger generation / invocation of dynamic dependency extraction for Non-FORTRAN source projects ?

I am interested in compiling OCaml sources using CMake + Ninja.

I have come across old posts where doing so has been attempted, however, as per my understanding, the approach which has been followed so far is to use the custom commands for invoking the compiler.

What I would like to do is to provide support for OCaml in a way such that we can still use the commands like add_executable etc. I followed the AddNewLanguage doc in the modules folder and after referring to some internet resources, was able to hack together basic setup where I can take a single source file and compile it to generate an executable.

The next challenge I need to address is regarding multi source projects, where one source can export OCaml modules which can be consumed by the other modules. This is similar to the Fortran compilation model which has been described in How CMake supports Fortran modules and its applicability to C++.

OCaml provides ocamldep program which given a set of sources can infer the modules it depends on, so I think I can leverage it to generate the .dd file which can be consumed by Ninja as part of it’s dynamic dependencies later on. Note: I might still have to massage the output of ocamldep to match the dyndep file format for Ninja.

I would like to know how can I trigger generation / invocation of dynamic dependency extraction for Non-FORTRAN source projects ?

Thanks!

It seems ocamldep generates dependencies in make format, so it is not the same as Fortran (it is not a dyndep) but you can manage easily dependencies generation by using variables CMAKE_<LANG>_DEPENDS_EXTRA_COMMANDS and CMAKE_<LANG>_DEPFILE_FORMAT. Note: it requires at least version 3.20.

The first one enables to define a command to execute to generate dependencies. In your case, something like:

set(CMAKE_OCaml_DEPENDS_EXTRA_COMMANDS "ocamldep <DEFINES> <INCLUDES> <FLAGS> <SOURCE> > <DEP_FILE>"

set(CMAKE_OCaml_DEPFILE_FORMAT gcc)

You can have a look at file Modules/Compiler/NVIDIA-CUDA.cmake for an example.

Thanks for your response @marc.chevrier !

The reason I found OCaml and Fortran dependencies to be similar was, firstly, as I have mentioned, that OCaml has the concept of modules which are generated from the sources, and secondly, ( I should have mentioned this in the original post ) Compiling OCaml sources can also sometimes generate both, the compiled object, and the compiled interface file. I could map the generated compiled interface file to the implicit output concept of Ninja-dyndep.

Is there a way to represent such implicit outputs as part of standard cmake commands ( I know add_custom_command has a documented field, but couldn’t find anything for other commands ) ?

In anycase, I’ll definitely lookup the references you have provided here.

Thanks again !

The dyndep logic is not supported for custom commands or languages as it ends up requiring CMake support to “collate” the dependency information at a target level so that modules can be found between targets. Additionally, it only works for the Ninja generators and the Makefiles generators use a slightly different process (generating snippets that are included at build-time).

I suppose that ocamldep is able to handle dependencies over modules? If so, the generated dependencies file will take care of this.

Now for multiple output files, I am afraid it is not possible, for now, to specify a such behavior by customizing cmake files.

Thanks @ben.boeckel & @marc.chevrier , I’ll try to see how far setting the variables can take me just post again if I get stuck. :slight_smile: