Skip to content

[new release] dune (18 packages) (3.24.0) - #30092

Merged
raphael-proust merged 1 commit into
ocaml:masterfrom
shonfeder:release-dune-3.24.0
Jun 30, 2026
Merged

[new release] dune (18 packages) (3.24.0)#30092
raphael-proust merged 1 commit into
ocaml:masterfrom
shonfeder:release-dune-3.24.0

Conversation

@shonfeder

Copy link
Copy Markdown
Member

Fast, portable, and opinionated build system

CHANGES:

Fixed

Added

Changed

CHANGES:

### Fixed

- Fix promotion failure when a target changes from a directory to a file
  between builds, causing "Is a directory" errors.
  (ocaml/dune#14371, fixes ocaml/dune#5647, fixes ocaml/dune#6575, @Alizter)

- Make `dune build @doc` pick up an odoc installed via `dune tools install
  odoc` even without `DUNE_CONFIG__LOCK_DEV_TOOL=enabled`, mirroring how
  `dune fmt` consumes a locked ocamlformat (ocaml/dune#14426, fixes ocaml/dune#14235, @mt-caret)

- Reject `(package ...)` inside a named dependency binding
  (`(deps (:name (package foo)))`). Previously this was silently accepted but
  `%{name}` would resolve to an empty path list. (ocaml/dune#14499, @Alizter)

- Fix incorrect dependency in the `.cmxs` build for libraries with
  mode-dependent foreign stubs: the rule depended on the byte stubs archive
  instead of the native one, so parallel builds could fail to find
  `-l<lib>_stubs_native`. (ocaml/dune#14500, fixes ocaml/dune#12964, @Alizter)

- Fix `dune build` failing with "No rule found" when `lock_dir` paths in
  `dune-workspace` contain a subdirectory (e.g. `(path sub/dune.lock)`).
  (ocaml/dune#14524, fixes ocaml/dune#14523, @Alizter)

- Artifact substitution repairs executable bit if it's not set correctly in the workspace
  (ocaml/dune#14556, @rgrinberg)

- Ignore `EINVAL` when accepting sockets on MacOS (ocaml/dune#14612, fixes ocaml/dune#12660, @rgrinberg)

- Validate profile names. Profile names must be non-empty and can only contain
  letters, digits, `_` and `-`. The name `_` is reserved as a wildcard in
  `(env ...)` stanzas. (ocaml/dune#14657, fixes ocaml/dune#14630, @rlepigre)

### Added

- Add `%{pkg:<package>:<section>:<path>}` pform for resolving package install
  files. Works with workspace packages, lock-file packages, and installed
  packages. (ocaml/dune#14200, fixes ocaml/dune#14193, fixes ocaml/dune#3378, @Alizter)

- Enable the relocatable compiler by default for package management (ocaml/dune#14357,
  fixes ocaml/dune#14012, @Alizter)

- Add changed source files to the `build-start` trace event for watch-mode
  restarts, showing the paths that triggered the rebuild (ocaml/dune#14396, @rgrinberg)

- Add dune's rusage information in start/finish build trace events (ocaml/dune#14402, @rgrinberg)

- Add a status message for RPC clients that manage to connect (ocaml/dune#14424, @rgrinberg)

- Allow blang expressions in the `runtest_alias` field in the `cram` stanza (ocaml/dune#14425, @rgrinberg)

- Extend the stat based cache to cache the contents of directories and not just
  source files (ocaml/dune#14469, @rgrinberg).

- Show the number of connected RPC clients in the watch mode status line
  (ocaml/dune#14489, @rgrinberg)

- Promote directory targets from experimental to generally available in 3.24
  (ocaml/dune#14579, @rgrinberg)

### Changed

- Use `/` as directory separator when appending local paths to external paths,
  making path construction consistent across platforms. (ocaml/dune#14278, @Alizter)
- On Windows, normalise process paths to `\` before passing them to
  `CreateProcessW` so that programs which scan `argv[0]` (notably `cmd.exe`)
  do not misparse mixed separators. (ocaml/dune#14278, @Alizter)

- `%{bin:NAME}` now resolves to the build artifact path rather than
  the install staging path. Rules with `%{bin:NAME}` deps additionally
  get a per-rule `.binaries` directory prepended to the action's
  `PATH`, containing correctly-named symlinks for each declared bin
  pform dep. (ocaml/dune#14432, fixes ocaml/dune#3324, @Alizter)

- Replace the Rocq language field `(stdlib ...)` with the presence-only field
  `(no_corelib)` in Rocq language 0.14. (ocaml/dune#14452, fixes ocaml/dune#14358, @Durbatuluk1701)

- Throttle sandbox creation to 250 concurrent sandboxes. (ocaml/dune#14464, @rgrinberg)

- The package solver now uses cached revision store lookups for improved
  performance. (ocaml/dune#14494, fixes ocaml/dune#12637, @Alizter, @rgrinberg)

- Remove the deprecated `(lang coq)` Coq Build Language. Use the
  Rocq Build Language (`(using rocq <version>)`) instead. Projects that
  still declare `(using coq <version>)` now get an error pointing them
  at Rocq. (ocaml/dune#14525, fixes ocaml/dune#12788, @Alizter)
@shonfeder

Copy link
Copy Markdown
Member Author

Prior two rounds of pre-releases:

All issues and regressions have been fixed, to the best of our knowledge, and this PR now presents our minor version release.

Prior triaging of CI errors can be found on the above draft PRs. I will perform another round of analysis here once CI has completed, and we share the results, either recommending merge or detailing the plans for any other needed fixes.

@shonfeder shonfeder mentioned this pull request Jun 21, 2026
30 tasks
@olafhering

olafhering commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

This breaks cppo (test suite), camomile and lablgtk3. Sorry for not testing -rc. Maybe the CI will recognize this as well?

[   13s] --- test/missing_endscope.ref
[   13s] +++ test/missing_endscope.err
[   13s] @@ -1,2 +1,2 @@
[   13s] -Error: File "missing_endscope.cppo", line 3, characters 0-6
[   13s] +Error: File "./missing_endscope.cppo", line 3, characters 0-6
[   13s]  Error: This #scope is never closed: perhaps #endscope is missing
[   29s] File "src/charmaps/dune.inc", lines 804-807, characters 0-111:
[   29s] 804 | (rule
[   29s] 805 |  (targets EBCDIC-PT.mar)
[   29s] 806 |  (deps    EBCDIC-PT)
[   29s] 807 |  (action  (run ../tools/camomilecharmap.exe -d . %{deps})))
[   29s] Error: Rule failed to generate the following targets:
[   29s] - src/charmaps/EBCDIC-PT.mar
[   41s] File "src/dune-prop.sexp", lines 6-8, characters 0-100:
[   41s] 6 | (rule
[   41s] 7 |  (targets gtkActionProps.ml ogtkActionProps.ml)
[   41s] 8 |  (action (run propcc %{dep:gtkAction.props})))
[   41s] Command [194] exited with code 2:
[   41s] $ (cd _build/default/src && ../.bin/propcc ./gtkAction.props)
[   41s] Uncaught exception: Sys_error("o./gtkActionProps.ml: No such file or directory")
[   41s] Fatal error: exception Sys_error("o./gtkActionProps.ml: No such file or directory")

@shonfeder

Copy link
Copy Markdown
Member Author

Thanks for the input!

There is a breaking change in this release, but it is only expected to impact packages that make invalid assumptions, or incorrect use, of the %{bin:...} variable. I'll dig in to these results to be sure, but at first glance it looks like all these packages fall into that bucket. I think we'll need upper bounds or patch releases for the affected packages, unless we decided we need to backtrack on this change (which I would not currently advocate for). I'll right up a summary and proposed action plan once the results are in here.

@olafhering

Copy link
Copy Markdown
Contributor

The missing_endscope failure suggests that not only cppo becomes ./cppo, but also the argument $1 may becomes ./$1 (via (run %{bin:cppo} %{<})). Maybe I misinterpret the cppo sources. As you said, people familiar with the sources need to work this out.

@shonfeder

shonfeder commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

not only cppo becomes ./cppo, but also the argument $1 may becomes ./$1 (via (run %{bin:cppo} %{<})).

That's correct. The underlying issues is that prior to dune 3.24, paths to files in the current directory were not represented with a preceding ./, which meant the representation was ambiguous (in many shells) between executables to be looked up in the environment and paths. We have fixed this ambiguity in dune 3.24, but tests or build rules that where making invalid assumptions about the concrete representation of these paths are now breaking as a result.

See ocaml/dune#15156 for details.

@olafhering

Copy link
Copy Markdown
Contributor

Hopefully this change did consider the arguments for executables. It is up to each one how something that is (or looks like) a path is processed by that executable. As it can be seen in the case of cppo, it may process a relative path just fine.

@shonfeder

shonfeder commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

Hopefully this change did consider the arguments for executables. It is up to each one how something that is (or looks like) a path is processed by that executable. As it can be seen in the case of cppo, it may process a relative path just fine.

As it can be seen in the case of cppo, it may process a relative path just fine.

I am not sure what you mean here. Indeed it was in consideration for arguments to executables that this change was made. See ocaml/dune#15147 and ocaml/dune#14724 for prior discussion.

The general view we have converged on is as follows: these variables have always expanded to paths, but the path representation was not unambiguous. It is now unambiguous. If build configurations were making invalid assumptions about the path representation that breaks once we make the representation unambiguous, this is a misconfiguration.

@shonfeder

Copy link
Copy Markdown
Member Author

Here's the initial error analysis. Failures are grouped by error message. Tons of these are downstream of just a few libraries (e.g., the ones we have already identified). Patches and bounds will be needed (unless we reverse course on the release, but I am still convinced about our analysis):

https://gist.github.com/shonfeder/09f28716f60bcf4d1a2eb3b066ddc825

@shonfeder

Copy link
Copy Markdown
Member Author

Triage and remediation is now complete, with results and activities documented in https://gist.github.com/shonfeder/09f28716f60bcf4d1a2eb3b066ddc825 (the work reported there exceeds the character limit of github comments).

Since no regressions or unexpected breaking changes have been identified, I think that this release can be published as soon as the following remediation PR has been merged, adding with-test filters to affected packages:

#30157

The other PRs into the opam repo mentioning this one are unrelated cleanups to package data, which just happened to be caught by the CI here.

raphael-proust pushed a commit that referenced this pull request Jun 30, 2026
raphael-proust pushed a commit that referenced this pull request Jun 30, 2026
raphael-proust pushed a commit that referenced this pull request Jun 30, 2026
@raphael-proust

Copy link
Copy Markdown
Contributor

thanks for the release and all the work patching all the small issues that popped up <3

@raphael-proust
raphael-proust merged commit 8cd35ac into ocaml:master Jun 30, 2026
4 of 5 checks passed
@shonfeder
shonfeder deleted the release-dune-3.24.0 branch June 30, 2026 16:57
@shonfeder

Copy link
Copy Markdown
Member Author

Thanks for the review and merge!

craff pushed a commit to craff/opam-repository that referenced this pull request Jul 25, 2026
craff pushed a commit to craff/opam-repository that referenced this pull request Jul 25, 2026
craff pushed a commit to craff/opam-repository that referenced this pull request Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment