[ANN] Dune Developer Preview Updates

Yes, but it says (throughout) that all the user needs to do is install Dune. The only recommendation (in G1) is that the “recommended way to get started with OCaml would be to install Dune through system package managers”. Certainly for me (as one of the co-authors of that document), that’s a much weaker statement than the “blessed” way. The 2026 target in that roadmap is to be at the stage that it is “as simple as”, while supporting and maturing existing workflows.

3 Likes

As @dra27 notes, the roadmap isn’t exclusive; in this era of OCaml 5, it’s entirely possible for different subgroups to work on things in parallel :slight_smile: And the roadmap is just that: a direction of travel, following certain principles. Dune (née jbuilder) itself started outside of any roadmap, as a side project that accrued momentum as it solved a problem with build systems for OCaml, and found users. And if the roadmap is wrong and/or incomplete, we’ll just change it.

One thing I really like about Dune package management is that it reduces the lockin to dune. The new client features allow dune to build opam packages, which eliminates any pressure on forcing all OCaml users to use dune as the sole build system! I’m currently getting Docker’s widely deployed vpnkit to build using it at the moment, and there is a heady combination of dune, ocamlbuild, makefiles and shell commands all being wrapped by the new dune frontend now. It also means we can stop maintaining the dune-overlays org as it will be unnecessary, and tools like mirage can be much simpler in how they generate code.

There’s some way to go, but I think this is a very positive direction of travel for OCaml. We’ve got both Windows support now (via opam 2.2) and a unified frontend (via the Dune devex), and both are compatible!

6 Likes

When I have tried to install the new dune from a Cygwin terminal (using the curl …| bash command), it says Cygwin is not supported.

1 Like

I meant that both are compatible from an architectural perspective (they both use the same opam package repository under the hood). The Dune devex doesn’t currently work on Windows, but will in the future.

1 Like

If we check how “blessed” is defined by Merriam Webster it’s

  • of or enjoying happiness
  • bringing pleasure, contentment, or good fortune

or in other words “the happy path”. Which also, as far as I understand, align with every point in the OCaml platform outlines. There’s a blessed, happy path for newcomers to get started and up and running quickly, as well as alternative ways to do things if needed.

As an outsider who mostly spend my free time dabbling in OCaml, but am trying to keep tabs on the community, so granted I might lack some context, these remarks come across as somewhere between undermining these Dune efforts to aggressive, as well as in contradiction of the roadmap for the OCaml platform.

My guess is that you’re reading more into “blessed” than what it really means in this context, but I think some further explanations might be necessary, because I agree with @yawaramin that the messaging and reactions are coming across as incredibly confusing.

4 Likes

As CEO of Tarides (and the original author of opam), I want to reiterate that at Tarides, our goal is to balance supporting existing OCaml users while also opening up new workflows and opportunities. No one is being forced to adopt a unified toolchain, but we believe that when the unified tool is fully ready, it could be a game-changer for the community.

We are committed to co-maintaining opam and its infrastructure on all platforms where the OCaml compiler is supported for the foreseeable future. With the help of other opam maintainers, we recently released opam 2.2, which (finally) brings proper Windows support to our ecosystem. We also maintain the opam-repository CI infrastructure, ensuring the OCaml ecosystem remains of the highest quality (especially for every new OCaml release).

At the same time, we’re focused on improving the next-generation user experience of OCaml. This is why we are fully aligned with the OCaml Platform roadmap (shared and iterated on this forum) and are working toward building a unified toolchain for OCaml. If you have any feedback, please contact Leo using this feedback form. I also encourage you to try the new experimental tools in your projects and see for yourself the progress we’re making.

I just managed (almost :sweat_smile:) to build irmin without any issues on macOS, so the future is looking bright! However, the reality is that only Jane Street is currently financially supporting Tarides for both the opam maintenance and the new workflow experiments, and we need more help. If you’re interested in sponsoring these efforts, please get in touch with me directly.

15 Likes

May I ask you about what in these files looks noisy to you? We try the generate these files with just the necessary information that is required for building. As such they contain a good amount less than the .opam files the information originates from.

1 Like

Each file in these *.lock dir seems to contain version + cache of the-info-needed-to-build-the-package, so I don’t understand if these .lock dirs are just an extension of _build (in which case: why aren’t they in _build?), or if they are meant to be committed (in which case: why do they contain the build-command and build-deps etc, which are derived from version+package, and which is what I was referring to as being noisy).
I would expect the list of (package name * version) to be its own file, similar to opam lock files (possibly with hashes), and the rest of the information to be computed from that file and stored under _build (or wherever the actual packages go) because it’s derived information like build artifacts, not source information.

2 Likes

Thanks. We were talking about this when designing the feature in its current form and:

The lock files contain all the information to build it without a need for the opam-repository, hence the build commands need to live somewhere.

In theory one could save the repository version(s) and read the information from the opam files in the repository, but the problem is then that at build time one would need to have access to the opam-repository (thus potentially need to download it). Also if the repository is not in git, then there would be no way to reproduce the same build.

if they are meant to be committed

I think in the long-run we’re aiming for the files to be committed, so multiple users on the same project would have the same dependencies (unless explicitely updated via lockfile). This matches the best practices of other package ecosystems like Node (package-lock.json and yarn.lock).

2 Likes

Ok, thanks.

The lock files contain all the information to build it without a need for the opam-repository, hence the build commands need to live somewhere.

In theory one could save the repository version(s) and read the information from the opam files in the repository, but the problem is then that at build time one would need to have access to the opam-repository (thus potentially need to download it). Also if the repository is not in git, then there would be no way to reproduce the same build.

I’m not familiar with the data formats of opam, but I’m guessing from your response that there’s no mechanism to cheaply resolve (package-name * version) to opam file, and that you can’t retrieve the opam files from the source url either because they don’t even have to be in there, and even if they are, nothing describes where.

Not if you want to reach a particular state of a repo directly. With opam-repository as shared on Github you could get the data via HTTP, but we don’t want to add too many requirements what kind of repos we support.

While a lot of packages do come with their .opam files, they often get improved in opam-repository after they get submitted, so using one version of the opam files to lock and then another version for the build instructions would be quite unpleasant to deal with and confusing, especially given Dune aims to play well with existing repos.

Shameless plug: I’m writing up an explanation on how package management works under the hood, so I encourage people to submit things they find unusual or baffling. That way I hope this document can explain the reasoning behind why things work the way they do. I believe understanding the reasoning why a tool works like it does makes a tool easier to use and less frustrating.

1 Like

This was the key part that was initially confusing to me. The lock files are big because the build information inside the 3rd-party source package archives is often inaccurate. Thanks for clearing that up.

(Although that suggests there should be some independent effort to identify and fix that problem long-term. Source package archives should be hermetic.)

1 Like

The packages are the 1st-party I’d say. Package archives are not required to have any OPAM files at all, the canonical source for OPAM metadata is the opam-repository, this is where the information is copied from. It is of course good manners to submit the fixes in opam-repository back upstream, e.g so that the next release can be updated but some packages haven’t been updated in a long time, there had been no new release in a long time or old versions need new constraints etc. All valid reasons to update the metadata in OPAM.

(Although that suggests there should be some independent effort to identify and fix that problem long-term. Source package archives should be hermetic.)

There are of some good reasons to keep the metadata files in the repo and most projects do, e.g. it is necessary for pinning packages. The same is true when pinning packages using Dune package management. But you need to be aware that in that case you don’t get the updates from the OPAM repository maintainers.

1 Like

I’ve thought about this for a while, and with the current approach to opam-repository, where rarely anyone specifies upper bounds for a dependency – this is unlikely to happen. If you release today a package A which depends on B, all the CI will check whether your lower bound (let’s say >= “2.4.0”) is fine – i.e. there’s some B which can be installed, and B in 2.4.0 works fine (the lower-bounds CI run), as well as B at the latest version works fine.

Now, you already established your A tarball. Now, some days later B gets released in 3.0.0, which - surprisingly - has some API breaking changes… This means the opam-repository-ci will detect that A is no longer compiling with B 3.0.0 and some brave soul will add an upper bound – B {>= “2.4.0” & < “3.0.0”} – to the opam-repository. If lucky, there’s a PR for A in the development repository. But the tarball of the release of A won’t have this upper bound.

Of course, this can change. It depends very much on the community. And strict upper bounds lead to lots of PRs to remove these (since your use of a package may not touch the API breaking changes). I’m personally undecided which approach I prefer, but I guess the OCaml/opam one with no upper bounds is fine (and I wouldn’t invest time to change it).

Just my 2 cents, sorry for hijacking the topic… back to the topic:

# curl -v https://dune.ci.dev/install
* Host dune.ci.dev:443 was resolved.
* IPv6: (none)
* IPv4: 51.159.152.205
*   Trying 51.159.152.205:443...
* Connected to dune.ci.dev (51.159.152.205) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256 / X25519 / id-ecPublicKey
* ALPN: server accepted h2
* Server certificate:
*  subject: CN=dune.ci.dev
*  start date: Oct  2 13:12:11 2024 GMT
*  expire date: Dec 31 13:12:10 2024 GMT
*  subjectAltName: host "dune.ci.dev" matched cert's "dune.ci.dev"
*  issuer: C=US; O=Let's Encrypt; CN=E5
*  SSL certificate verify ok.
*   Certificate level 0: Public key type EC/prime256v1 (256/128 Bits/secBits), signed using ecdsa-with-SHA384
*   Certificate level 1: Public key type EC/secp384r1 (384/192 Bits/secBits), signed using sha256WithRSAEncryption
*   Certificate level 2: Public key type RSA (4096/152 Bits/secBits), signed using sha256WithRSAEncryption
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://dune.ci.dev/install
* [HTTP/2] [1] [:method: GET]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: dune.ci.dev]
* [HTTP/2] [1] [:path: /install]
* [HTTP/2] [1] [user-agent: curl/8.5.0]
* [HTTP/2] [1] [accept: */*]
> GET /install HTTP/2
> Host: dune.ci.dev
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/2 301 
< alt-svc: h3=":443"; ma=2592000
< location: https://preview.dune.build/install
< server: Caddy
< content-length: 0
< date: Wed, 02 Oct 2024 19:09:28 GMT
< 
* Connection #0 to host dune.ci.dev left intact


# curl https://preview.dune.build/install
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>

Looks like I’m getting nothing. Surely I’m missing something.

1 Like

(@Leonidas @hannes Agreed. Too complicated and may not be feasible.)

Back to the main thread.

1 Like

Sorry, yesterday the preview moved under the dune.build homepage as preview.dune.build. We’ve set up a redirect but only for the page and not for the script. It’s returning a 301 to the right location (needs curl -L or curl https://get.dune.build/install | bash) and the page has the updated instructions.

It’s all a bit in the flow at the moment as we are getting a lot of feedback and are trying to incorporate it all.

2 Likes

Thanks for your reply.

# curl https://get.dune.build/install | bash
bash: Command not found.
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0  5061    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
curl: (23) Failure writing output to destination

And then after further looking into “install”, I figured I won’t be run it on any of the systems I use (FreeBSD/amd64). But I guess that’s a niche I’m in.

Yes, at the moment the install script does not support FreeBSD users that don’t have bash installed and the binary distribution is limited to the types of runners that Github offers.

However the preview website documents the necessary flags to build it from source which should most likely also work on FreeBSD.

Random observations from someone who tried this out yesterday.

  • Tried it out from a blank setup - no opam installed.
  • It seemed to install ocaml etc fine, although it took a while.
  • Built my (simple) projects just fine.
  • Did fail at certain points where some header-files weren’t installed. I seem to remember opam-cli being more helpful here + suggesting apt packages to install to fix that.
  • Unless I’m doing something stupid, I can’t install tools (e.g. “utop”) without making them a dependency of a project.
    Adding “utop” as a dependency doesn’t feel right. It isn’t required to either run or build the project.
  • Neovim didn’t seem to like running the LSP as dune tools exec... and I had to wrap that in a shell-script. That is probably my poor understanding of vim/neovim config though.
  • The caching seems to work, but disk usage looks huge if you have several different variations of a project, or several similar projects. Can’t think that there is anything you can do about the tooling, but maybe a note in the docs?

The initial seemed to build everything from scratch? That makes sense I suppose but did mean that I had no real idea how long it was going to take. If I was just checking ocaml out I’d probably have hit Ctrl+C and given it up as too much effort.

2 Likes

Overall the experience is very smooth, and this makes the outlook of OCaml development look very positive (especially once this hits Debian stable).

That said:

% du -chs dune.lock
744K	dune.lock/
744K	total

Contrast with a go.sum file:

github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=
github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
...
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

I hope the decision to have an entire lock directory, and to copy all this information from opam-repositry could be reconsidered. In particular:

  • For dune packages, the dune/dune-project files can be the source of truth, and only a url and checksum need to be stored.
  • For maintained non-dune packages, the opam file in the package can be the source of truth, and this could be checked using a lint step on PRs in opam-repository. Note that upper bounds are not needed at build time, as the lock file already points to a fixed version. Again, only a url and checksum need to be stored.
  • For non-maintained packages, opam-overlays could be the source of truth. Or we keep using the current solution.
1 Like