Dune 1.9.0

The dune team is pleased to announce the dune 1.9.0 release which introduces the concept of library variants. Changes include:

  • Coloring in the watch mode (#1956)
  • $ dune init command to create or update project boilerplate (#1448)
  • Allow “.” in c_names and cxx_names (#2036)
  • Experimental Coq support
  • Support for library variants and default implementations (#1900)


In dune 1.7.0, the concept of virtual library was introduced: https://dune.build/blog/virtual-libraries/. This feature allows to mark some abstract library as virtual, and then have several implementations for it. These implementations could be for multiple targets (unix, xen, js), using different algorithms, using C code or not. However each implementation in a project dependency tree had to be manually selected. Dune 1.9.0 introduces features for automatic selection of implementations.

Library variants

Variants is a tagging mechanism to select implementations on the final linking step. There’s not much to add to make your implementation use variants. For example, you could decide to design a bar_js library which is the javascript implementation of bar, a virtual library. All you need to do is specificy a js tag using the variant option.

 (name bar_js)
 (implements bar)
 (variant js)); <-- variant specification

Now any executable that depend on bar can automatically select the bar_js library variant using the variants option in the dune file.

 (name foo)
 (libraries bar baz)
 (variants js)); <-- variants selection

Common variants

Language selection

In your projects you might want to trade off speed for portability:

  • ocaml: pure OCaml
  • c: OCaml accelerated by C

JavaScript backend

  • js: code aiming for a Node backend, using Js_of_ocaml

Mirage backends

The Mirage project (mirage.io) will make extensive use of this feature in order to select the appropriate dependencies according to the selected backend.

  • unix: Unikernels as Unix applications, running on top of mirage-unix
  • xen: Xen backend, on top of mirage-xen
  • freestanding: Freestanding backend, on top of mirage-solo5

Default implementation

To facilitate the transition from normal libraries into virtuals ones, it’s possible to specify an implementation that is selected by default. This default implementation is selected if no implementation is chosen after variant resolution.

 (name bar)
 (virtual_modules hello)
 (default_implementation bar_unix)); <-- default implementation selection

Selection mechanism

Implementation is done with respect to some priority rules:

  • manual selection of an implementation overrides everything
  • after that comes selection by variants
  • finally unimplemented virtual libraries can select their default implementation

Libraries may depend on specific implementations but this is not recommended. In this case, several things can happen:

  • the implementation conflicts with a manually selected implementation: resolution fails.
  • the implementation overrides variants and default implementations: a cycle check is done and this either resolves or fails.


Variant libraries and default implementations are fully documented here. This feature improves the usability of virtual libraries.

This commit shows the amount of changes needed to make a virtual library use variants.

Coq support

Dune now supports building Coq projects. To enable the experimental Coq extension, add (using coq 0.1) to your dune-project file. Then, you can use the (coqlib ...) stanza to declare Coq libraries.

A typical dune file for a Coq project will look like:

(include_subdirs qualified) ; Use if your development is based on sub directories

  (name Equations)                  ; Name of wrapper module
  (public_name equations.Equations) ; Generate an .install file
  (synopsis "Equations Plugin")     ; Synopsis
  (libraries equations.plugin)      ; ML dependencies (for plugins)
  (modules :standard \ IdDec)       ; modules to build
  (flags -w -notation-override))    ; coqc flags

See the documentation of the extension for more details.