The dune team is currently preparing the 2.0.0 release of Dune and we wanted to share our plans for it. As always, we put a lot of effort into backward compatibility and we expect that the 2.0.0 release will be barely noticeable for existing users, just as the renaming from Jbuilder to Dune was.
However, in order to keep the project modern and prepare it for the future, we are planning to do a couple of changes in Dune 2.0.0. We invite all Dune users to read this post in order to understand the changes and how these changes could affect them. If you do not have time to read this whole post, you can read this quick summary instead.
At a high level, we encourage everyone to switch to the Dune 2 binary
for local development as soon as it is released. However, if you care
a lot about compatibility with older OCaml compilers, we advise that
you keep the (lang dune ...)
line in your dune-project
as (lang
dune 1.x)
. This will forbid you access to the Dune 2 features and
will ensure that your project is compatible with Dune >= 1.x.
On our side, we will make sure to add a lot of cool new features in Dune 2 to convince all users to switch to the new dune language :)
Quick summary
- Dune 2.0.0 will be 99% backward compatible with Dune 1.x
- Jbuilder and Dune 2.0.0 will be co-installable
- a
dune-project
file will now be necessary to mark the root of a project - a few default behaviors will change in dune 2.0.0 but will not affect existing released packages
- Dune 1.x will receive an additional year of support, possibly 2
- Dune 2.0.0 will require OCaml 4.08 to build, however it still be able to build projects using older compilers and will be installable in older opam switches
dune.configurator
will now be released asdune-configurator
, however the namedune.configurator
will still exist for backward compatibility reasons- lots of new exciting features in preparation!
Dropping official support for Jbuilder
The main motivation for bumping the major version number is dropping the support for jbuilder, as announced in previous posts:
This means that starting from Dune 2.0.0, the dune
binary will no
longer be guaranteed to understand projects with jbuild
files. We
originally planned that Dune 2 would fail hard when seeing a jbuild
file and would install a dummy jbuilder
binary that would
systematically fail on startup.
However, given the large number of projects that haven’t switched from
Jbuilder to Dune yet, we decided to adapt our plans. First of all,
Dune 2 will not install a dummy jbuilder
binary. In fact, it will
not install a jbuilder
binary at all. This means that Dune 2 and
Jbuilder will be co-installable. In particular, in opam it will be
possible to install packages using Jbuilder alongside packages using
Dune 2.
Additionally, Dune will still be able to understand Jbuilder projects
to some extent. More precisely, it will use the same code as dune
upgrade
to convert jbuild
files to dune
files on the fly. This is
not enough to provide full compatibility with jbuilder
when
installed via opam. However, it will be enough when a Jbuilder project
is vendored inside a Dune project.
With this plan, the Dune 2 release should be smooth for users and Jbuilder backward compatibility will not get in the way of new Dune developments.
But really, we strongly encourage everybody maintaining a package
still using jbuilder
to release a new version using dune
:)
Upgrading from jbuilder
to dune
is extremely easy and automated as
desribed in this post.
Note for Mono-repository users
While Dune will still be able to understand Jbuilder projects vendored
inside Dune ones, it will now require the presence of a dune-project
to mark the root of such projects. Up to now, the presence of at least
one <package>.opam
file was enough to mark the root of a project
inside a bigger workspace. Marking the root of projects inside
workspaces is important as otherwise private libraries of vendored
projects will be globally visible and might clash with private
libraries of other vendored projects.
Since older projects are likely to not have such a file, you should
add one when vendoring a Jbuilder project inside a Dune one. This
dune-project
file can simply contain (lang dune 1.0)
.
99% backward compatibility with Dune 1.x
When Dune sees (lang dune x.y)
in a dune-project
file, it adapts
itself to behave as the x.y
versoin of Dune. This is how we provide
full backward compatibility in Dune.
As a result we are expecting that Dune 2.0 will not break
anything. Projects currently using (lang dune 1.x)
will continue to
build with all versions of Dune from 1.x onwards.
There is one exception I can think of to this rule: currently if you
have a file that is both generated by a rule and present in the source
tree, this is a warning with older versions of the dune
language. However, making this a warning rather than a hard error is
costly and requires maintainig a complex piece of code in Dune. What
is more, this scenario often led to confusion in the past so it is not
a good thing to accept it. As a result, for this particular case we
will make it a systematic error starting from Dune 2.0.0. This means
that projects relying on the current behaviour will not build with
Dune 2.x. For the record, the way to fix this is to add a (mode
promote)
or (mode fallback)
field to the relevant stanza so that
Dune knows what the intent is.
Appart from that, things that currently trigger a warning will
continue to trigger a warning when using (lang dune 1.x)
, however
they will become hard errors when using (lang dune 2.x)
. We will
also change a few defaults behaviors in Dune 2.x. We don’t have the
full list yet, but a few things that one has to enable explicitly now
in the dune-project
file will become the default, such as
auto-formatting. Another example is what dune builds by default. It
will be @all
rather than @install
since @all
is now a more
appropriate default.
You can think of the (lang dune x.y)
line in dune-project
files as
follow: while working on a project, you should use the latest version
you can use. This will give you access to the most recent features of
Dune and will give you the most up-to-date commonly accepted defaults.
When not working on a project, this line is a way to remember which version of Dune was used the last time you worked on the project so that future versions of Dune can continue to understand it without you taking action.
dune.configurator will now be dune-configurator
We want to make Dune a pure binary so that it is easier to distribute.
For this reason, the dune.configurator
library will now be
distributed as a separate dune-configurator
package in opam. The
name dune.configurator
will still exist for backward compatibility
reasons, however you should use the name dune-configurator
rather
than dune.configurator
in new code.
At least the first release of the dune-configurator
package will be
compatible with Dune 1, so projects that want to keep compatibility
with Dune 1 can depend on dune-configurator
.
Requiring a recent version of OCaml to build Dune
At the moment, Dune can build projects using all versions of OCaml since 4.02.3 and can also built itself using all versions of OCaml since 4.02.3. More precisely, Dune is aware of all past OCaml bugs and can work around them when building projects using an old compiler, and the code of Dune itself is compatible with older compilers.
This makes Dune an easy dependency for authors who want their project to be compatible with older OCaml versions. However, making Dune itself compatible with older compilers is a heavy constraint on the development of Dune. In particular, it means that we need to increase our testing with each new compiler release and also that we cannot use new features of the language. The second constraint is particularly annoying given that Dune is actively developed and its code base could definitely benefit from the new language features.
For this reason, starting from version 2.0.0 Dune will require a recent version of OCaml to build itself. Dune 2.0.0 will require 4.08.0, when 4.09.0 is released we will immediately start using its new features and so on. But more importantly, we will immediatly start using multicore when it becomes available, since Dune is a project that is likely to benefit from it.
However, we will continue to support building projects using Dune with older compilers. For instance, it will still be possible to build Dune using OCaml 4.08.0 and use the resulting binary to build projects with OCaml 4.02.3. In particular, we will rely on this fact to make Dune 2.0.0 available in older opam switches. The only downside is that installing Dune 2 in an older opam switch will be slightly slower as it will need to first install a secondary compiler. However, we hope that this secondary compiler could be used by other platform tools who would want to adopt the same approach as Dune.
Since this is method is new and might require some time before it is properly rolling, we will provide an additional 1 year of support for Dune 1, and possibly 2 if the burden is not too high on the Dune team. By support we mean the following: we will continue doing bugfix releases and making sure that the latest release of Dune 1.x builds will new OCaml compilers released during that period of time.
What’s next?
There are a lot of new exciting features planned or in development. An
important one is the integration of a shared artefacts cache in
Dune. In a nutshell, it will make opam install
cached and fast,
which will be particularly useful for users of local switches. It will
also be useful for non-opam users. We will talk more about this
subject in a dedicated post.
We are also continuing the work on the Core of Dune, and in particular improving and getting more out of the memorisation system we introduced last year. We plan to rely on it to make Dune scale and preserve the user experience when using Dune in large workspaces.
And as always, we will continue formalising and integrating new features that will improve the workflow of Dune users!