Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package ocaml-dune for openSUSE:Factory 
checked in at 2026-07-31 15:30:13
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/ocaml-dune (Old)
 and      /work/SRC/openSUSE:Factory/.ocaml-dune.new.2004 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "ocaml-dune"

Fri Jul 31 15:30:13 2026 rev:55 rq:1368507 version:3.24.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/ocaml-dune/ocaml-dune.changes    2026-07-17 
01:39:39.705510042 +0200
+++ /work/SRC/openSUSE:Factory/.ocaml-dune.new.2004/ocaml-dune.changes  
2026-07-31 16:09:23.728787503 +0200
@@ -1,0 +2,6 @@
+Wed Jul 22 22:22:22 UTC 2026 - [email protected]
+
+- Update to version 3.24.1
+  see included CHANGES.md file for details
+
+-------------------------------------------------------------------

Old:
----
  ocaml-dune-3.24.0.tar.xz

New:
----
  ocaml-dune-3.24.1.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ ocaml-dune.spec ++++++
--- /var/tmp/diff_new_pack.moP1Ae/_old  2026-07-31 16:09:24.292807123 +0200
+++ /var/tmp/diff_new_pack.moP1Ae/_new  2026-07-31 16:09:24.292807123 +0200
@@ -25,7 +25,7 @@
 %define     pkg ocaml-dune
 %global  _buildshell /bin/bash
 Name:           %pkg%nsuffix
-Version:        3.24.0
+Version:        3.24.1
 Release:        0
 %{?ocaml_preserve_bytecode}
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.moP1Ae/_old  2026-07-31 16:09:24.336808654 +0200
+++ /var/tmp/diff_new_pack.moP1Ae/_new  2026-07-31 16:09:24.344808932 +0200
@@ -1,7 +1,7 @@
 <services>
   <service name="tar_scm" mode="manual">
     <param name="filename">ocaml-dune</param>
-    <param name="revision">47f64de764078db6edb2698958b5270a17bffb05</param>
+    <param name="revision">a5d7d322823927dd5d85ae102fd7d442be2f7e66</param>
     <param name="scm">git</param>
     <param name="submodules">disable</param>
     <param name="url">https://github.com/ocaml/dune.git</param>

++++++ ocaml-dune-3.24.0.tar.xz -> ocaml-dune-3.24.1.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/.github/workflows/mirage.yml 
new/ocaml-dune-3.24.1/.github/workflows/mirage.yml
--- old/ocaml-dune-3.24.0/.github/workflows/mirage.yml  2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/.github/workflows/mirage.yml  2026-07-21 
09:29:37.000000000 +0200
@@ -21,8 +21,11 @@
       with:
         ocaml-compiler: 4.14.x
         opam-depext: false
-    - run: opam repo set-url default 
git+https://github.com/ocaml/opam-repository#a7b8d1036328cf727af175b657f3d2b732b4d868
+        opam-pin: false
+        opam-repositories: |
+          default: 
git+https://github.com/ocaml/opam-repository#38b8d4531633db2f927868caf84e5a9b8992229e
     - run: sed -i s/1.3/2.7/ dune-project
+    - run: opam pin add -n caldav.dev 
git+https://github.com/roburio/caldav#88077909aede711da1a0417f27fc8223c141f0fe
     - run: opam pin add -n dune.dev 
git+https://github.com/ocaml/dune#$GITHUB_SHA
     - run: sudo apt install libseccomp-dev
     - run: opam install mirage.4.10.5 opam-monorepo.0.4.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/.github/workflows/workflow.yml 
new/ocaml-dune-3.24.1/.github/workflows/workflow.yml
--- old/ocaml-dune-3.24.0/.github/workflows/workflow.yml        2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/.github/workflows/workflow.yml        2026-07-21 
09:29:37.000000000 +0200
@@ -368,7 +368,7 @@
         run: opam install --fake binaryen-bin
 
       - name: Install Wasm_of_ocaml
-        run: opam install "wasm_of_ocaml-compiler>=6.1" csexp pp re spawn uutf 
ppx_expect
+        run: opam install wasm_of_ocaml-compiler.6.3.2 csexp pp re spawn uutf 
ppx_expect
 
       - name: Set Git User
         run: |
@@ -437,7 +437,7 @@
           node-version: latest
 
       - name: Install deps
-        run: opam install csexp pp re spawn uutf ppx_expect ppx_inline_test 
wasm_of_ocaml-compiler
+        run: opam install csexp pp re spawn uutf ppx_expect ppx_inline_test 
wasm_of_ocaml-compiler.6.0.1+ox1
 
       - name: Build dune
         run: opam exec -- make bootstrap
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/.github/workflows/workflow.yml.in 
new/ocaml-dune-3.24.1/.github/workflows/workflow.yml.in
--- old/ocaml-dune-3.24.0/.github/workflows/workflow.yml.in     2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/.github/workflows/workflow.yml.in     2026-07-21 
09:29:37.000000000 +0200
@@ -367,7 +367,7 @@
         run: opam install --fake binaryen-bin
 
       - name: Install Wasm_of_ocaml
-        run: opam install "wasm_of_ocaml-compiler>=6.1" csexp pp re spawn uutf 
ppx_expect
+        run: opam install wasm_of_ocaml-compiler.6.3.2 csexp pp re spawn uutf 
ppx_expect
 
       - name: Set Git User
         run: |
@@ -436,7 +436,7 @@
           node-version: latest
 
       - name: Install deps
-        run: opam install csexp pp re spawn uutf ppx_expect ppx_inline_test 
wasm_of_ocaml-compiler
+        run: opam install csexp pp re spawn uutf ppx_expect ppx_inline_test 
wasm_of_ocaml-compiler.6.0.1+ox1
 
       - name: Build dune
         run: opam exec -- make bootstrap
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/CHANGES.md 
new/ocaml-dune-3.24.1/CHANGES.md
--- old/ocaml-dune-3.24.0/CHANGES.md    2026-06-21 22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/CHANGES.md    2026-07-21 09:29:37.000000000 +0200
@@ -1,5 +1,39 @@
 <!-- !!! DO NOT EDIT: generated by doc/changes/scripts/build_changelog.sh !!! 
-->
 <!-- Contributors: See 'Update the Changelog' in CONTRIBUTING.md. -->
+3.24.1 (2026-07-21)
+-------------------
+
+### Fixed
+
+- Fix an internal error (`modules_and_obj_dir: failed lookup`) when generating
+  `js_of_ocaml` archive rules for a dune file that defines two libraries with
+  the same name distinguished by mutually exclusive `enabled_if` clauses, as
+  `ocaml-re` does for `ppx_expect_common` (#14904, fixes #14775, @vouillon)
+
+- Fix passing environment variables to formatter actions  (#15386, @anmonteiro)
+
+- Fix missing source dependency in the sandbox when preprocessing Melange
+  sources (#15395, @anmonteiro)
+
+- Treat OCaml compiler packages version 5.5 or newer as relocatable so their
+  installations do not use the toolchain cache (#15444, fixes #15443, @Alizter)
+
+- Fix `build_runtime_flags` given in a `js_of_ocaml`/`wasm_of_ocaml` field of
+  an executable being silently ignored in separate compilation mode: such
+  executables were given the workspace-shared standalone runtime, which is
+  built with the default flags. Executables customizing `build_runtime_flags`
+  now get their own standalone runtime again. (#15455, @hhugo)
+
+- Use installed filenames for local package binaries in `%{bin:...}` PATH
+  layouts on Windows (#15518, fixes #15512, @Alizter)
+
+### Changed
+
+- Revert sandboxing Melange rules by default in the `(library ..)` and
+  `(melange.emit ..)` stanzas. In Melange libraries with many modules, sandbox
+  creation / destruction dominates build time and adds significant overhead to
+  build time (#15418, @anmonteiro)
+
 3.24.0 (2026-06-21)
 -------------------
 
@@ -89,6 +123,12 @@
   still declare `(using coq <version>)` now get an error pointing them
   at Rocq. (#14525, fixes #12788, @Alizter)
 
+- Path-valued pforms (`%{bin:...}`, `%{dep:...}`, `%{path:...}`, and
+  friends) now expand same-directory paths with a leading `./`, so that
+  shells like `bash` in `(bash ...)` and `(system ...)` actions execute
+  them directly instead of looking them up in `PATH`.
+  (#15156, fixes #15147, @Alizter)
+
 3.23.1 (2026-05-14)
 -------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/doc/changes/changed/15156.md 
new/ocaml-dune-3.24.1/doc/changes/changed/15156.md
--- old/ocaml-dune-3.24.0/doc/changes/changed/15156.md  2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/doc/changes/changed/15156.md  1970-01-01 
01:00:00.000000000 +0100
@@ -1,5 +0,0 @@
-- Path-valued pforms (`%{bin:...}`, `%{dep:...}`, `%{path:...}`, and
-  friends) now expand same-directory paths with a leading `./`, so that
-  shells like `bash` in `(bash ...)` and `(system ...)` actions execute
-  them directly instead of looking them up in `PATH`.
-  (#15156, fixes #15147, @Alizter)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/nix/revdeps.nix 
new/ocaml-dune-3.24.1/nix/revdeps.nix
--- old/ocaml-dune-3.24.0/nix/revdeps.nix       2026-06-21 22:57:05.000000000 
+0200
+++ new/ocaml-dune-3.24.1/nix/revdeps.nix       2026-07-21 09:29:37.000000000 
+0200
@@ -40,6 +40,22 @@
           flambdaSupport = false;
         };
 
+        cppo = osuper.cppo.overrideAttrs (_: {
+          src = final.fetchFromGitHub {
+            owner = "ocaml-community";
+            repo = "cppo";
+            rev = "fe1e27112d34fd9a7f68f268508663d436d41ac6";
+            hash = "sha256-BMYjsAKshiRGPHERF0/kP0heb8ZHlq5eCpMDQQJ+F4U=";
+          };
+        });
+
+        mdx = osuper.mdx.overrideAttrs (old: {
+          doCheck = false;
+          postInstall = (old.postInstall or "") + ''
+            mkdir -p $bin $lib
+          '';
+        });
+
         dune_3 = osuper.dune_3.overrideAttrs (old: {
           src = revdeps-dune;
           nativeBuildInputs = old.nativeBuildInputs ++ [ pkgs.git ];
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/opam/dune.opam 
new/ocaml-dune-3.24.1/opam/dune.opam
--- old/ocaml-dune-3.24.0/opam/dune.opam        2026-06-21 22:57:05.000000000 
+0200
+++ new/ocaml-dune-3.24.1/opam/dune.opam        2026-07-21 09:29:37.000000000 
+0200
@@ -50,8 +50,8 @@
   "lwt" { with-dev-setup & os != "win32" }
   "cinaps" { with-dev-setup }
   "csexp" { with-dev-setup & >= "1.3.0" }
-  "js_of_ocaml" { with-dev-setup & >= "6.1.0" & os != "win32" }
-  "js_of_ocaml-compiler" { with-dev-setup & >= "6.1.0" & os != "win32" }
+  "js_of_ocaml" { with-dev-setup & >= "6.1.0" & < "6.4" & os != "win32" }
+  "js_of_ocaml-compiler" { with-dev-setup & >= "6.1.0" & < "6.4" & os != 
"win32" }
   "mdx" { with-dev-setup & >= "2.3.0" & os != "win32" }
   "menhir" { with-dev-setup & os != "win32" }
   "ocamlfind" { with-dev-setup & os != "win32" }
@@ -63,7 +63,7 @@
   "ppxlib" { with-dev-setup & >= "0.37.0" & os != "win32" }
   "ctypes" { with-dev-setup & os != "win32" }
   "utop" { with-dev-setup & >= "2.6.0" & os != "win32" }
-  "melange" { with-dev-setup & >= "5.1.0-51" & os != "win32" }
+  "melange" { with-dev-setup & >= "5.1.0-51" & < "7.0" & os != "win32" }
   "uutf" { with-dev-setup }
   # the rev store negotiation test launches a git daemon, needs it to be
   # installed on some distributions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/opam/dune.opam.template 
new/ocaml-dune-3.24.1/opam/dune.opam.template
--- old/ocaml-dune-3.24.0/opam/dune.opam.template       2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/opam/dune.opam.template       2026-07-21 
09:29:37.000000000 +0200
@@ -11,8 +11,8 @@
   "lwt" { with-dev-setup & os != "win32" }
   "cinaps" { with-dev-setup }
   "csexp" { with-dev-setup & >= "1.3.0" }
-  "js_of_ocaml" { with-dev-setup & >= "6.1.0" & os != "win32" }
-  "js_of_ocaml-compiler" { with-dev-setup & >= "6.1.0" & os != "win32" }
+  "js_of_ocaml" { with-dev-setup & >= "6.1.0" & < "6.4" & os != "win32" }
+  "js_of_ocaml-compiler" { with-dev-setup & >= "6.1.0" & < "6.4" & os != 
"win32" }
   "mdx" { with-dev-setup & >= "2.3.0" & os != "win32" }
   "menhir" { with-dev-setup & os != "win32" }
   "ocamlfind" { with-dev-setup & os != "win32" }
@@ -24,7 +24,7 @@
   "ppxlib" { with-dev-setup & >= "0.37.0" & os != "win32" }
   "ctypes" { with-dev-setup & os != "win32" }
   "utop" { with-dev-setup & >= "2.6.0" & os != "win32" }
-  "melange" { with-dev-setup & >= "5.1.0-51" & os != "win32" }
+  "melange" { with-dev-setup & >= "5.1.0-51" & < "7.0" & os != "win32" }
   "uutf" { with-dev-setup }
   # the rev store negotiation test launches a git daemon, needs it to be
   # installed on some distributions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/artifacts.ml 
new/ocaml-dune-3.24.1/src/dune_rules/artifacts.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/artifacts.ml   2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/artifacts.ml   2026-07-21 
09:29:37.000000000 +0200
@@ -27,8 +27,9 @@
 
 type t =
   { context : Context.t
-  ; (* Mapping from executable names to their actual path in the workspace.
-       The keys are the executable names without the .exe, even on Windows.
+  ; (* Mapping from binary lookup names to their definitions. On Windows, a
+       trailing [.exe] is removed from lookup names, while [Origin.dst] retains
+       the actual install filename.
        Enumerating binaries from install stanzas may involve expanding globs,
        but the artifacts database is depended on by the logic which expands
        globs. The computation of this field is deferred to break the cycle. *)
@@ -120,11 +121,11 @@
        Ok (Path.build src))
 ;;
 
-let binary_package t ~dir name =
+let local_binary_install_name t ~dir name =
   analyze_binary t ~dir name
   >>| function
-  | `Origin { package; _ } -> package
-  | `Resolved _ | `None -> None
+  | `Origin { package = Some _; dst; _ } -> Some (Path.Local.basename dst)
+  | `Origin { package = None; _ } | `Resolved _ | `None -> None
 ;;
 
 let binary_available t ~dir name =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/artifacts.mli 
new/ocaml-dune-3.24.1/src/dune_rules/artifacts.mli
--- old/ocaml-dune-3.24.0/src/dune_rules/artifacts.mli  2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/artifacts.mli  2026-07-21 
09:29:37.000000000 +0200
@@ -39,7 +39,14 @@
   -> string
   -> Action.Prog.t Memo.t
 
-val binary_package : t -> dir:Path.Build.t -> string -> Package.Name.t option 
Memo.t
+(** Return the installed filename when the selected binary is from a local
+    package. *)
+val local_binary_install_name
+  :  t
+  -> dir:Path.Build.t
+  -> string
+  -> Filename.t option Memo.t
+
 val binary_available : t -> dir:Path.Build.t -> string -> bool Memo.t
 val add_binaries : t -> dir:Path.Build.t -> File_binding.Expanded.t list -> t
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/bin_layout.ml 
new/ocaml-dune-3.24.1/src/dune_rules/bin_layout.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/bin_layout.ml  2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/bin_layout.ml  2026-07-21 
09:29:37.000000000 +0200
@@ -1,24 +1,53 @@
 open Import
 
+module Entry = struct
+  module T = struct
+    type t =
+      { lookup_name : string
+      ; install_name : Filename.t
+      }
+
+    let repr =
+      Repr.record
+        "bin-layout-entry"
+        [ Repr.field "lookup_name" Repr.string ~get:(fun t -> t.lookup_name)
+        ; Repr.field "install_name" Filename.repr ~get:(fun t -> 
t.install_name)
+        ]
+    ;;
+
+    (* CR-someday Alizter: [Filename.t] is structurally a string and uses
+       [String.compare], but [Filename.repr] exposes it as a view, which
+       [Repr.Poly] conservatively rejects. Make its representation structural
+       so this comparison can be derived. *)
+    let compare x y =
+      let open Ordering.O in
+      let= () = String.compare x.lookup_name y.lookup_name in
+      Filename.compare x.install_name y.install_name
+    ;;
+  end
+
+  include T
+  include Repr.Make (T)
+
+  include Comparable.Make (struct
+      include T
+      include Repr.Make (T)
+    end)
+end
+
 module Key : sig
-  val encode : Filename.Set.t -> string
-  val decode : string -> Filename.Set.t
+  val encode : Entry.Set.t -> string
+  val decode : string -> Entry.Set.t
 end = struct
   (* [decode] is only called on digests produced by [encode] in the same
      process (deps are evaluated before paths under the layout dir are
      resolved), so the entry will always be present. Same pattern as
      [Ppx_driver.Key]. *)
-  let reverse_table : (Digest.t, Filename.Set.t) Table.t =
-    Table.create (module Digest) 128
-  ;;
+  let reverse_table : (Digest.t, Entry.Set.t) Table.t = Table.create (module 
Digest) 128
 
-  let encode bins =
-    let y =
-      Digest.repr
-        Repr.(list string)
-        (Filename.Set.to_list bins |> List.map ~f:Filename.to_string)
-    in
-    Table.set reverse_table y bins;
+  let encode entries =
+    let y = Digest.repr Repr.(list Entry.repr) (Entry.Set.to_list entries) in
+    Table.set reverse_table y entries;
     Digest.to_string y
   ;;
 
@@ -42,39 +71,48 @@
   Path.Build.L.relative (Install.Context.dir ~context) [ ".binaries"; key ]
 ;;
 
-let create context bins =
-  let bins = List.map bins ~f:Filename.of_string_exn |> Filename.Set.of_list in
-  let dir = Key.encode bins |> layout_dir ~context in
-  ( dir
-  , Filename.Set.to_list_map bins ~f:(fun name ->
-      Path.build (Path.Build.relative_fname dir name)) )
+let create context ~dir bin_names =
+  let open Memo.O in
+  let* artifacts =
+    let* sctx = Super_context.find_exn context in
+    Artifacts_db.get (Super_context.context sctx)
+  in
+  let+ entries =
+    Memo.List.filter_map bin_names ~f:(fun lookup_name ->
+      Artifacts.local_binary_install_name artifacts ~dir lookup_name
+      >>| Option.map ~f:(fun install_name -> { Entry.lookup_name; install_name 
}))
+  in
+  match entries with
+  | [] -> None
+  | _ :: _ ->
+    let entries = Entry.Set.of_list entries in
+    let layout_dir = Key.encode entries |> layout_dir ~context in
+    Some
+      ( layout_dir
+      , Entry.Set.to_list_map entries ~f:(fun { Entry.lookup_name = _; 
install_name } ->
+          Path.build (Path.Build.relative_fname layout_dir install_name)) )
 ;;
 
 let symlink_rules_for_key context_name ~dir key =
-  let bins = Key.decode key in
+  let entries = Key.decode key in
   let open Memo.O in
   let* artifacts =
     let* sctx = Super_context.find_exn context_name in
     Artifacts_db.get (Super_context.context sctx)
   in
-  Filename.Set.to_list bins
-  |> Memo.parallel_iter ~f:(fun name ->
+  Entry.Set.to_list entries
+  |> Memo.parallel_iter ~f:(fun ({ Entry.lookup_name; install_name } as entry) 
->
     let* prog =
-      Artifacts.binary
-        artifacts
-        ~where:Original_path
-        ~dir
-        ~loc:None
-        (Filename.to_string name)
+      Artifacts.binary artifacts ~where:Original_path ~dir ~loc:None 
lookup_name
     in
     match prog with
     | Error _ ->
       Code_error.raise
         "Bin_layout.gen_rules: binary not found"
-        [ "name", Filename.to_dyn name; "context", Context_name.to_dyn 
context_name ]
+        [ "entry", Entry.to_dyn entry; "context", Context_name.to_dyn 
context_name ]
     | Ok src ->
       let { Action_builder.With_targets.build; targets } =
-        Action_builder.symlink ~src ~dst:(Path.Build.relative_fname dir name)
+        Action_builder.symlink ~src ~dst:(Path.Build.relative_fname dir 
install_name)
       in
       Rules.Produce.rule (Rule.make ~targets build))
 ;;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/bin_layout.mli 
new/ocaml-dune-3.24.1/src/dune_rules/bin_layout.mli
--- old/ocaml-dune-3.24.0/src/dune_rules/bin_layout.mli 2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/bin_layout.mli 2026-07-21 
09:29:37.000000000 +0200
@@ -1,10 +1,18 @@
 open Import
 
-(** Create a .binaries directory for the given binary names. Returns the
-    directory and the list of symlink paths for dependency tracking. The
-    symlinks are created as build rules keyed by a digest of the sorted
-    binary names. *)
-val create : Context_name.t -> string list -> Path.Build.t * Path.t list
+(** [create context ~dir bin_names] creates a .binaries directory for the
+    [%{bin:...}] names resolved from [dir], covering the names that resolve to
+    local package binaries. [context] must be the host context in which the
+    binaries run. Returns [None] when no name does. Otherwise returns the
+    directory and the list of symlink paths for dependency tracking; depend on
+    the paths before putting the directory on [PATH]. The symlinks are created
+    as build rules keyed by a digest of the sorted (lookup name, installed
+    filename) pairs. *)
+val create
+  :  Context_name.t
+  -> dir:Path.Build.t
+  -> string list
+  -> (Path.Build.t * Path.t list) option Memo.t
 
 (** Dispatch a path under [_build/install/<context>/.binaries/...].
     [rest] is the components after [.binaries].
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/compilation_mode.ml 
new/ocaml-dune-3.24.1/src/dune_rules/compilation_mode.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/compilation_mode.ml    2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/compilation_mode.ml    2026-07-21 
09:29:37.000000000 +0200
@@ -34,8 +34,8 @@
 ;;
 
 let default_sandbox = function
-  | Ocaml -> Sandbox_config.no_special_requirements
-  | Melange -> Sandbox_config.needs_sandboxing
+  | Ocaml -> Dune_engine.Sandbox_config.no_special_requirements
+  | Melange -> Dune_engine.Sandbox_config.no_special_requirements
 ;;
 
 module By_mode = struct
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/dep_conf_eval.ml 
new/ocaml-dune-3.24.1/src/dune_rules/dep_conf_eval.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/dep_conf_eval.ml       2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/dep_conf_eval.ml       2026-07-21 
09:29:37.000000000 +0200
@@ -135,20 +135,10 @@
         (let open Memo.O in
          Expander.host_context expander >>| Context.name)
     in
-    let* origin_bin_names =
-      Action_builder.of_memo
-        (let open Memo.O in
-         let* artifacts =
-           let* sctx = Super_context.find_exn context in
-           Artifacts_db.get (Super_context.context sctx)
-         in
-         Memo.List.filter bin_names ~f:(fun name ->
-           Artifacts.binary_package artifacts ~dir name >>| Option.is_some))
-    in
-    (match origin_bin_names with
-     | [] -> Action_builder.return Env.empty
-     | _ ->
-       let layout_dir, files = Bin_layout.create context origin_bin_names in
+    let* layout = Action_builder.of_memo (Bin_layout.create context ~dir 
bin_names) in
+    (match layout with
+     | None -> Action_builder.return Env.empty
+     | Some (layout_dir, files) ->
        let+ () = Action_builder.paths files in
        (* The layout dir on PATH is an absolute build-tree path; dune's
           sandbox does not relocate PATH. See [bin-pform/sandbox.t]. *)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/format_rules.ml 
new/ocaml-dune-3.24.1/src/dune_rules/format_rules.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/format_rules.ml        2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/format_rules.ml        2026-07-21 
09:29:37.000000000 +0200
@@ -26,22 +26,26 @@
     in
     Build_system.dep_on_alias_definition (Rules.Dir_rules.Alias_spec.Action 
action)
   in
-  let formatter_stdout ~loc alias action =
+  let formatter_stdout sctx ~loc alias action =
+    let dir = Alias.dir alias in
     let action =
       let open Action_builder.O in
-      let+ action = action in
-      { Rule.Anonymous_action.action
-      ; loc
-      ; dir = Alias.dir alias
-      ; alias = Some (Alias.name alias)
-      }
+      let+ (action : Action.Full.t) = action
+      and+ env =
+        Super_context.env_node sctx ~dir
+        |> Memo.bind ~f:Env_node.external_env
+        |> Action_builder.of_memo
+      in
+      let env = Env_path.extend_env_concat_path env action.env in
+      let action = Action.Full.add_env env action in
+      { Rule.Anonymous_action.action; loc; dir; alias = Some (Alias.name 
alias) }
     in
     Build_system.execute_action_stdout action |> Action_builder.of_memo
   in
-  fun ~loc alias ~input formatter ->
+  fun sctx ~loc alias ~input formatter ->
     let open Action_builder.O in
     let action =
-      let+ formatter = formatter_stdout ~loc alias formatter
+      let+ formatter = formatter_stdout sctx ~loc alias formatter
       and+ () = Action_builder.path (Path.build input) in
       Action.chdir
         (Path.build (Path.Build.parent_exn input))
@@ -147,6 +151,7 @@
 ;;
 
 let setup_source_file
+      sctx
       (config : Format_config.t)
       ~dialects
       ~ocamlformat_is_locked
@@ -181,11 +186,11 @@
     let loc = Loc.in_file (Path.source file) in
     let input = Path.Build.relative_fname dir (Path.Source.basename file) in
     format_action format ~ocamlformat_is_locked ~input ~expander kind
-    |> formatter_diff_action ~loc alias ~input
+    |> formatter_diff_action sctx ~loc alias ~input
 ;;
 
 let setup_dune_files =
-  let setup_dune_file ~version ~dir alias path =
+  let setup_dune_file sctx ~version ~dir alias path =
     let input_build = Path.Build.relative_fname dir (Path.Source.basename 
path) in
     let build =
       let input = Path.build input_build in
@@ -194,12 +199,13 @@
       Action.Full.make (Format_dune_file.action_stdout ~version input)
     in
     formatter_diff_action
+      sctx
       ~loc:(Loc.in_file (Path.source path))
       alias
       ~input:input_build
       build
   in
-  fun (config : Format_config.t) ~version ~dir alias source_dir ->
+  fun sctx (config : Format_config.t) ~version ~dir alias source_dir ->
     match Format_config.includes config Dune with
     | false -> Action_builder.return ()
     | true ->
@@ -208,10 +214,11 @@
        | Some dune_file ->
          (match Source.Dune_file.path dune_file with
           | None -> Action_builder.return ()
-          | Some path -> setup_dune_file ~version ~dir alias path))
+          | Some path -> setup_dune_file sctx ~version ~dir alias path))
 ;;
 
 let setup_source_files
+      sctx
       config
       ~dialects
       ~ocamlformat_is_locked
@@ -224,11 +231,11 @@
   |> Filename.Array.Set.to_list
   |> List.map ~f:(fun file ->
     Path.Source.relative_fname (Source_tree.Dir.path source_dir) file
-    |> setup_source_file config ~dialects ~ocamlformat_is_locked ~expander 
~dir alias)
+    |> setup_source_file sctx config ~dialects ~ocamlformat_is_locked 
~expander ~dir alias)
   |> Action_builder.all_unit
 ;;
 
-let gen_format_alias (config : Format_config.t) ~version ~dialects ~expander 
~dir =
+let gen_format_alias sctx (config : Format_config.t) ~version ~dialects 
~expander ~dir =
   let open Action_builder.O in
   Action_builder.of_memo (Source_tree.find_dir 
(Path.Build.drop_build_context_exn dir))
   >>= function
@@ -240,6 +247,7 @@
     let alias = Alias.make Alias0.fmt ~dir in
     let+ () =
       setup_source_files
+        sctx
         config
         ~dialects
         ~ocamlformat_is_locked
@@ -247,7 +255,7 @@
         ~dir
         alias
         source_dir
-    and+ () = setup_dune_files config ~version ~dir alias source_dir in
+    and+ () = setup_dune_files sctx config ~version ~dir alias source_dir in
     ()
 ;;
 
@@ -285,7 +293,7 @@
       let* project = Action_builder.of_memo (Dune_load.find_project ~dir) in
       let dialects = Dune_project.dialects project in
       let version = Dune_project.dune_version project in
-      gen_format_alias config ~version ~dialects ~expander ~dir
+      gen_format_alias sctx config ~version ~dialects ~expander ~dir
     in
     Rules.Produce.Alias.add_deps (Alias.make Alias0.fmt ~dir) format)
 ;;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/src/dune_rules/jsoo/jsoo_archive_rules.ml 
new/ocaml-dune-3.24.1/src/dune_rules/jsoo/jsoo_archive_rules.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/jsoo/jsoo_archive_rules.ml     
2026-06-21 22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/jsoo/jsoo_archive_rules.ml     
2026-07-21 09:29:37.000000000 +0200
@@ -12,18 +12,21 @@
   let to_dyn (dir, name) = Dyn.Tuple [ Path.Build.to_dyn dir; Dyn.string name ]
 end
 
-let find_library ~dir ~lib_name =
+let find_library ~expander ~dir ~lib_name =
   Dune_load.stanzas_in_dir dir
   >>= function
   | None -> Memo.return None
   | Some dune_file ->
-    let+ stanzas = Dune_file.stanzas dune_file in
-    List.find_map stanzas ~f:(fun stanza ->
+    let* stanzas = Dune_file.stanzas dune_file in
+    Memo.List.find_map stanzas ~f:(fun stanza ->
       match Stanza.repr stanza with
-      | Library.T lib ->
-        let name = Lib_name.Local.to_string (snd lib.name) in
-        Option.some_if (String.equal name lib_name) lib
-      | _ -> None)
+      | Library.T lib when String.equal (Lib_name.Local.to_string (snd 
lib.name)) lib_name
+        ->
+        Expander.eval_blang expander lib.enabled_if
+        >>| (function
+         | true -> Some lib
+         | false -> None)
+      | _ -> Memo.return None)
 ;;
 
 let library_cctx_memo =
@@ -34,13 +37,13 @@
        let* sctx =
          Context.DB.by_dir lib_dir >>| Context.name >>= Super_context.find_exn
        in
-       find_library ~dir:lib_dir ~lib_name
+       let* expander = Super_context.expander sctx ~dir:lib_dir in
+       find_library ~expander ~dir:lib_dir ~lib_name
        >>= function
        | None -> Memo.return None
        | Some lib ->
          let* dir_contents = Dir_contents.get sctx ~dir:lib_dir in
          let* scope = Scope.DB.find_by_dir lib_dir in
-         let* expander = Super_context.expander sctx ~dir:lib_dir in
          (* [compile_context] may produce rules (via [modules_rules]) as 
implicit
             output. We collect and discard them here; they will be replayed by 
memo
             when the library directory is loaded through [Lib_rules.rules]. *)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/jsoo/jsoo_rules.ml 
new/ocaml-dune-3.24.1/src/dune_rules/jsoo/jsoo_rules.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/jsoo/jsoo_rules.ml     2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/jsoo/jsoo_rules.ml     2026-07-21 
09:29:37.000000000 +0200
@@ -1120,7 +1120,14 @@
     assert (Js_of_ocaml.Mode.select ~mode ~js:(wasm_files = []) ~wasm:true);
     let runtime_files = javascript_files @ wasm_files in
     let* eligible =
-      if List.is_empty runtime_files
+      if
+        List.is_empty runtime_files
+        (* The shared runtime is built with the default flags, so an
+           executable customizing [build_runtime_flags] needs its own
+           runtime. *)
+        && Ordered_set_lang.Unexpanded.equal
+             (Js_of_ocaml.Flags.build_runtime flags)
+             Ordered_set_lang.Unexpanded.standard
       then
         Resolve.Memo.peek (Compilation_context.requires_link cc)
         >>| function
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/src/dune_rules/melange/melange_rules.ml 
new/ocaml-dune-3.24.1/src/dune_rules/melange/melange_rules.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/melange/melange_rules.ml       
2026-06-21 22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/melange/melange_rules.ml       
2026-07-21 09:29:37.000000000 +0200
@@ -463,7 +463,6 @@
         in
         Command.run
           ~dir:(Super_context.context sctx |> Context.build_dir |> Path.build)
-          ~sandbox:Sandbox_config.needs_sandboxing
           compiler
           [ Command.Args.S obj_dir
           ; Command.Args.as_any includes
@@ -721,10 +720,6 @@
         | Some (Ok false) | Some (Error _) | None ->
           Left dst, Action_builder.copy ~src ~dst
       in
-      let builder =
-        let open Action_builder.With_targets.O in
-        builder >>| Action.Full.add_sandbox Sandbox_config.needs_sandboxing
-      in
       let+ () = add_rule sctx ~loc ~dir ~mode builder in
       dst
     | Some directory_target_ancestor ->
@@ -734,10 +729,6 @@
         Path.Build.relative dst rel
       in
       let builder = Action_builder.copy_dir ~src:new_src ~dst in
-      let builder =
-        let open Action_builder.With_targets.O in
-        builder >>| Action.Full.add_sandbox Sandbox_config.needs_sandboxing
-      in
       let+ () = add_rule sctx ~loc ~dir ~mode builder in
       Right dst)
   >>| List.partition_map ~f:Fun.id
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/pkg_rules.ml 
new/ocaml-dune-3.24.1/src/dune_rules/pkg_rules.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/pkg_rules.ml   2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/pkg_rules.ml   2026-07-21 
09:29:37.000000000 +0200
@@ -1405,29 +1405,12 @@
     { id : Id.t
     ; pkg_digest_table : Pkg_table.t
     ; system_provided : Package.Name.Set.t
-    ; is_relocatable_compiler_context : bool
     }
 
   let equal x y = Id.equal x.id y.id
 
-  let create =
-    (* A compiler is relocatable if the solution contains the
-       "relocatable-compiler" meta-package (from dra27's overlay repo) or
-       the "relocatable" virtual package (from upstream opam-repository). *)
-    let is_relocatable_meta_package name =
-      Package.Name.equal name (Package.Name.of_string "relocatable-compiler")
-      || Package.Name.equal name (Package.Name.of_string "relocatable")
-    in
-    fun ~pkg_digest_table ~system_provided ->
-      { id = Id.gen ()
-      ; pkg_digest_table
-      ; system_provided
-      ; is_relocatable_compiler_context =
-          Pkg_digest.Map.existsi
-            pkg_digest_table
-            ~f:(fun _ { Pkg_table.pkg = { info = { name; _ }; _ }; _ } ->
-              is_relocatable_meta_package name)
-      }
+  let create ~pkg_digest_table ~system_provided =
+    { id = Id.gen (); pkg_digest_table; system_provided }
   ;;
 
   let pkg_digest_of_name lock_dir platform pkg_name ~system_provided =
@@ -1556,6 +1539,27 @@
     | Action a -> Build_command.Action (relocate a)
   ;;
 
+  let is_relocatable_compiler_marker name =
+    let relocatable_compiler = Package.Name.of_string "relocatable-compiler" in
+    let relocatable = Package.Name.of_string "relocatable" in
+    Package.Name.equal name relocatable_compiler || Package.Name.equal name 
relocatable
+  ;;
+
+  let has_relocatable_compiler_marker (info : Pkg_info.t) depends =
+    is_relocatable_compiler_marker info.name
+    || Pkg.top_closure depends
+       |> List.exists ~f:(fun (pkg : Pkg.t) ->
+         is_relocatable_compiler_marker pkg.info.name)
+  ;;
+
+  let is_compiler_version_relocatable (info : Pkg_info.t) =
+    Pkg_toolchain.is_compiler_package_with_toolchains_enabled info.name
+    &&
+    match Package_version.compare info.version (Package_version.of_string 
"5.5.0") with
+    | Lt -> false
+    | Eq | Gt -> true
+  ;;
+
   let resolve_impl { Input.db; pkg_digest; universe = package_universe } =
     match Pkg_digest.Map.find db.pkg_digest_table pkg_digest with
     | None -> Memo.return None
@@ -1613,8 +1617,9 @@
       let paths =
         let paths = Paths.map_path write_paths ~f:Path.build in
         if
-          db.is_relocatable_compiler_context
-          || not (Pkg_toolchain.is_compiler_package_with_toolchains_enabled 
info.name)
+          (not (Pkg_toolchain.is_compiler_package_with_toolchains_enabled 
info.name))
+          || is_compiler_version_relocatable info
+          || has_relocatable_compiler_marker info depends
         then paths
         else (
           (* Modify the environment as well as build and install commands for
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/ocaml-dune-3.24.0/src/dune_rules/pp_spec_rules.ml 
new/ocaml-dune-3.24.1/src/dune_rules/pp_spec_rules.ml
--- old/ocaml-dune-3.24.0/src/dune_rules/pp_spec_rules.ml       2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/src/dune_rules/pp_spec_rules.ml       2026-07-21 
09:29:37.000000000 +0200
@@ -348,10 +348,15 @@
         let* ast = setup_dialect_rules sctx ~sandbox ~dir ~expander m in
         let* () = Memo.when_ lint (fun () -> lint_module ~ast ~source:m) in
         pped_module ast ~f:(fun ml_kind src dst ->
+          let loc_filename = pp_input_path m ~ml_kind in
           let loc_filename_arg =
-            loc_filename_arg_for_pp
-              ~input_path:(Path.build src)
-              ~loc_filename:(pp_input_path m ~ml_kind)
+            loc_filename_arg_for_pp ~input_path:(Path.build src) ~loc_filename
+          in
+          let hidden_deps =
+            let source =
+              Module.source m ~ml_kind |> Option.value_exn |> Module.File.path
+            in
+            Dep.Set.of_files [ source; loc_filename ]
           in
           Super_context.add_rule
             sctx
@@ -359,7 +364,7 @@
             ~dir
             (promote_correction_with_target
                ~suffix:(Filename.of_string_exn corrected_suffix)
-               (pp_input_path m ~ml_kind |> Path.as_in_build_dir_exn)
+               (loc_filename |> Path.as_in_build_dir_exn)
                (Action_builder.with_file_targets
                   ~file_targets:[ dst ]
                   (let open Action_builder.O in
@@ -378,12 +383,7 @@
                      ; loc_filename_arg
                      ; Command.Ml_kind.ppx_driver_flag ml_kind
                      ; Dep (Path.build src)
-                     ; Hidden_deps
-                         (Module.source m ~ml_kind
-                          |> Option.value_exn
-                          |> Module.File.path
-                          |> Dep.file
-                          |> Dep.Set.singleton)
+                     ; Hidden_deps hidden_deps
                      ; As flags
                      ])))))
 ;;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/setup-script.sh 
new/ocaml-dune-3.24.1/test/blackbox-tests/setup-script.sh
--- old/ocaml-dune-3.24.0/test/blackbox-tests/setup-script.sh   2026-06-21 
22:57:05.000000000 +0200
+++ new/ocaml-dune-3.24.1/test/blackbox-tests/setup-script.sh   2026-07-21 
09:29:37.000000000 +0200
@@ -29,6 +29,16 @@
        EOF
 }
 
+make_dune_project_with_package() {
+  local version="$1"
+  local package="$2"
+
+  make_dune_project "$version"
+  cat >> dune-project <<- EOF
+       (package (name ${package}))
+       EOF
+}
+
 make_dir_with_dune() {
   path="$1"
   mkdir -p "$path"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/bin-pform/dune 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/bin-pform/dune
--- old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/bin-pform/dune 
1970-01-01 01:00:00.000000000 +0100
+++ new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/bin-pform/dune 
2026-07-21 09:29:37.000000000 +0200
@@ -0,0 +1,5 @@
+(cram
+ (applies_to windows-install-names)
+ (enabled_if
+  (= %{os_type} Win32))
+ (alias runtest-windows))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/bin-pform/windows-install-names.t
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/bin-pform/windows-install-names.t
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/bin-pform/windows-install-names.t
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/bin-pform/windows-install-names.t
      2026-07-21 09:29:37.000000000 +0200
@@ -0,0 +1,50 @@
+On Windows, artifact lookup uses extensionless executable names while the
+layout must use the actual installed filenames. Non-executable bin entries
+retain their declared extensions.
+
+  $ make_dune_project_with_package 3.24 mypkg
+  $ mkdir producer
+
+  $ cat >producer/launcher.ml <<'EOF'
+  > let () = print_endline "hello from launcher"
+  > EOF
+
+  $ cat >producer/tool.cmd <<'EOF'
+  > @echo off
+  > echo hello from tool
+  > EOF
+
+  $ cat >producer/dune <<'EOF'
+  > (executable
+  >  (name launcher)
+  >  (public_name launcher)
+  >  (package mypkg))
+  > (install
+  >  (package mypkg)
+  >  (section bin)
+  >  (files tool.cmd))
+  > EOF
+
+  $ cat >dune <<'EOF'
+  > (rule
+  >  (deps %{bin:launcher} %{bin:tool.cmd})
+  >  (action
+  >   (progn
+  >    (with-stdout-to launcher.out (system "launcher"))
+  >    (with-stdout-to tool.out (system "tool.cmd")))))
+  > EOF
+
+On native Windows, both entries are callable by their lookup names:
+
+  $ dune build launcher.out tool.out
+  $ cat _build/default/launcher.out
+  hello from launcher
+  $ cat _build/default/tool.out
+  hello from tool
+
+The layout uses the installed filenames, including [.exe] only for the
+executable:
+
+  $ ls _build/install/default/.binaries/*
+  launcher.exe
+  tool.cmd
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/formatting/feature.t/fake-tools/refmt.ml
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/formatting/feature.t/fake-tools/refmt.ml
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/formatting/feature.t/fake-tools/refmt.ml
       2026-06-21 22:57:05.000000000 +0200
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/formatting/feature.t/fake-tools/refmt.ml
       2026-07-21 09:29:37.000000000 +0200
@@ -1,5 +1,8 @@
 let process args =
   Printf.printf "Sys.argv: %s\n" (String.concat " " (Array.to_list args));
+  (match Sys.getenv_opt "REFMT_PRINT_WIDTH" with
+   | None -> ()
+   | Some value -> Printf.printf "REFMT_PRINT_WIDTH=%s\n" value);
   Printf.printf "refmt output\n"
 
 let () =
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/formatting/feature.t/run.t 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/formatting/feature.t/run.t
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/formatting/feature.t/run.t 
    2026-06-21 22:57:05.000000000 +0200
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/formatting/feature.t/run.t 
    2026-07-21 09:29:37.000000000 +0200
@@ -228,6 +228,32 @@
   (library
    (name lib_reason))
 
+Formatting actions receive environment variables from the (env ...) stanza:
+
+  $ mkdir -p enabled/env-vars
+  $ cat >enabled/env-vars/dune <<EOF
+  > (env
+  >  (_
+  >   (env-vars
+  >    (REFMT_PRINT_WIDTH 120))))
+  > EOF
+  $ cat >enabled/env-vars/reason_file.re <<EOF
+  > let z = ();
+  > EOF
+  $ dune build @enabled/env-vars/fmt
+  File "enabled/env-vars/reason_file.re", line 1, characters 0-0:
+  --- enabled/env-vars/reason_file.re
+  +++ enabled/env-vars/reason_file.re.corrected
+  @@ -1 +1,3 @@
+  -let z = ();
+  +Sys.argv: ../install/default/bin/refmt enabled/env-vars/reason_file.re
+  +REFMT_PRINT_WIDTH=120
+  +refmt output
+  [1]
+  $ dune promote enabled/env-vars/reason_file.re
+  Promoting _build/default/enabled/env-vars/reason_file.re.corrected to
+    enabled/env-vars/reason_file.re.
+
 The fmt command automatically promotes the formatted files:
 
   $ touch fmt-cmd/.ocamlformat
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/bin/dune
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/bin/dune
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/bin/dune
     1970-01-01 01:00:00.000000000 +0100
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/bin/dune
     2026-07-21 09:29:37.000000000 +0200
@@ -0,0 +1,4 @@
+(executable
+ (name main)
+ (modes js)
+ (libraries foo))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/bin/main.ml
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/bin/main.ml
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/bin/main.ml
  1970-01-01 01:00:00.000000000 +0100
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/bin/main.ml
  2026-07-21 09:29:37.000000000 +0200
@@ -0,0 +1 @@
+let () = print_endline "hello"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/dune-project
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/dune-project
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/dune-project
 1970-01-01 01:00:00.000000000 +0100
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/dune-project
 2026-07-21 09:29:37.000000000 +0200
@@ -0,0 +1 @@
+(lang dune 3.0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/foo/dune
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/foo/dune
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/foo/dune
     1970-01-01 01:00:00.000000000 +0100
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/foo/dune
     2026-07-21 09:29:37.000000000 +0200
@@ -0,0 +1,7 @@
+(library
+ (name foo)
+ (enabled_if false))
+
+(library
+ (name foo)
+ (enabled_if true))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/run.t
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/run.t
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/run.t
        1970-01-01 01:00:00.000000000 +0100
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/archive-enabled-if.t/run.t
        2026-07-21 09:29:37.000000000 +0200
@@ -0,0 +1,8 @@
+Generating jsoo archive rules for a library that shares its name with
+another library in the same directory, the two being distinguished by
+mutually exclusive enabled_if clauses. The rules must be generated for
+the enabled stanza, not the first one by position.
+
+  $ dune build bin/main.bc.js --profile dev 2>&1 | head -12
+  $ node ./_build/default/bin/main.bc.js 2> /dev/null
+  hello
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/shared-runtime-build-runtime-flags.t
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/shared-runtime-build-runtime-flags.t
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/jsoo/shared-runtime-build-runtime-flags.t
      1970-01-01 01:00:00.000000000 +0100
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/jsoo/shared-runtime-build-runtime-flags.t
      2026-07-21 09:29:37.000000000 +0200
@@ -0,0 +1,46 @@
+Regression test for per-executable build_runtime_flags in separate
+compilation.
+
+Since the introduction of the shared standalone runtime, an executable
+with no javascript_files of its own was always given the shared runtime,
+which is built with the default flags: its build_runtime_flags were
+silently dropped. Here --file must embed data.txt into the
+pseudo-filesystem of main.bc.js.
+
+  $ make_dune_project 3.19
+
+  $ cat > dune <<EOF
+  > (executable
+  >  (name main)
+  >  (modes js)
+  >  (js_of_ocaml
+  >   (compilation_mode separate)
+  >   (build_runtime_flags (:standard --file %{dep:data.txt}))))
+  > EOF
+  $ cat > main.ml <<EOF
+  > let () = print_endline "hi"
+  > EOF
+  $ echo EMBEDDED_PAYLOAD > data.txt
+
+  $ dune build ./main.bc.js
+  $ grep -c EMBEDDED_PAYLOAD _build/default/main.bc.js
+  1
+
+An executable with default build_runtime_flags still uses the shared
+runtime:
+
+  $ mkdir other
+  $ cat > other/dune <<EOF
+  > (executable
+  >  (name other)
+  >  (modes js)
+  >  (js_of_ocaml
+  >   (compilation_mode separate)))
+  > EOF
+  $ cat > other/other.ml <<EOF
+  > let () = print_endline "hi"
+  > EOF
+
+  $ dune build ./other/other.bc.js
+  $ find _build/default/.js -name 'runtime.bc.runtime.js' | wc -l | xargs
+  1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/melange/sandbox-default.t 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/melange/sandbox-default.t
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/melange/sandbox-default.t  
    2026-06-21 22:57:05.000000000 +0200
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/melange/sandbox-default.t  
    2026-07-21 09:29:37.000000000 +0200
@@ -1,4 +1,4 @@
-Melange rules should be sandboxed by default
+Melange rules should honor explicit sandboxing
 
   $ cat > dune-project <<EOF
   > (lang dune 3.22)
@@ -26,11 +26,12 @@
   > let () = Js.log Lib.message
   > EOF
 
-Use default sandbox preference. The test suite sets `DUNE_SANDBOX`, so clear 
it.
+The test suite sets `DUNE_SANDBOX`, so clear it and use the command-line
+option explicitly.
 
   $ unset DUNE_SANDBOX
   $ rm -rf _build
-  $ dune build @mel --display quiet --trace-file trace.csexp
+  $ dune build @mel --sandbox=symlink --display quiet --trace-file trace.csexp
 
   $ cat > melc_dirs.jq <<EOF
   > select(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/melange/sandbox-preprocessed-reason-source.t
 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/melange/sandbox-preprocessed-reason-source.t
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/melange/sandbox-preprocessed-reason-source.t
   2026-06-21 22:57:05.000000000 +0200
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/melange/sandbox-preprocessed-reason-source.t
   2026-07-21 09:29:37.000000000 +0200
@@ -15,12 +15,27 @@
   >  (kind ppx_rewriter)
   >  (modules ppx_noop)
   >  (libraries ppxlib))
+  > 
+  > (library
+  >  (name ppx_read_input)
+  >  (kind ppx_rewriter)
+  >  (modules ppx_read_input)
+  >  (libraries ppxlib))
   > EOF
 
   $ cat > cases/ppx/ppx_noop.ml <<'EOF'
   > let () = Ppxlib.Driver.register_transformation "ppx_noop"
   > EOF
 
+  $ cat > cases/ppx/ppx_read_input.ml <<'EOF'
+  > let impl ast =
+  >   let ic = open_in !Ocaml_common.Location.input_name in
+  >   close_in ic;
+  >   ast
+  > ;;
+  > let () = Ppxlib.Driver.register_transformation "ppx_read_input" ~impl
+  > EOF
+
   $ cat > cases/src/dune <<'EOF'
   > (library
   >  (name reason_impl)
@@ -44,3 +59,23 @@
            int
   Leaving directory 'cases'
   [1]
+
+PPX rewriters may read the logical input filename passed with [-loc-filename].
+The original Reason source must be available in the PPX sandbox.
+
+  $ mkdir -p cases/read-loc/src
+
+  $ cat > cases/read-loc/src/dune <<'EOF'
+  > (library
+  >  (name read_loc_filename)
+  >  (modes melange)
+  >  (modules x)
+  >  (preprocess
+  >   (pps ppx_read_input)))
+  > EOF
+
+  $ cat > cases/read-loc/src/x.re <<'EOF'
+  > let x = "reason"
+  > EOF
+
+  $ dune build --root cases --sandbox=symlink @read-loc/src/all
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/pkg/relocatable-compiler.t 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/pkg/relocatable-compiler.t
--- 
old/ocaml-dune-3.24.0/test/blackbox-tests/test-cases/pkg/relocatable-compiler.t 
    2026-06-21 22:57:05.000000000 +0200
+++ 
new/ocaml-dune-3.24.1/test/blackbox-tests/test-cases/pkg/relocatable-compiler.t 
    2026-07-21 09:29:37.000000000 +0200
@@ -1,11 +1,26 @@
 Test that relocatable compilers bypass toolchain cache. A compiler is
-considered relocatable if the solution contains either:
-- The "relocatable-compiler" meta-package (from dra27's overlay repo)
-- The "relocatable" virtual package (from upstream opam-repository)
+considered relocatable if it's OCaml 5.5.0 or newer, or if the compiler
+package's dependency closure contains an older relocatable compiler marker.
 
   $ mkrepo
   $ mkdir -p relocatable-repo/packages
 
+  $ append_fake_compiler_commands() {
+  > local opam="$1"
+  > local contents="$2"
+  > cat >> "$opam" <<EOF
+  > build: [
+  >   [ "sh" "-c" "echo '${contents}' > ocamlc.opt" ]
+  >   [ "ln" "-s" "ocamlc.opt" "ocamlc" ]
+  > ]
+  > install: [
+  >   [ "mkdir" "-p" "%{bin}%" ]
+  >   [ "cp" "ocamlc.opt" "%{bin}%/" ]
+  >   [ "cp" "-P" "ocamlc" "%{bin}%/" ]
+  > ]
+  > EOF
+  > }
+
 Create the relocatable compiler packages in separate repo:
 
   $ mkdir -p relocatable-repo/packages/compiler-cloning/compiler-cloning.0.0.1
@@ -25,16 +40,10 @@
   $ cat > 
relocatable-repo/packages/ocaml-base-compiler/ocaml-base-compiler.5.4.0/opam << 
'EOF'
   > opam-version: "2.0"
   > depends: [ "relocatable-compiler" {= "5.4.0"} ]
-  > build: [
-  >   [ "sh" "-c" "echo 'ocamlc binary' > ocamlc.opt" ]
-  >   [ "ln" "-s" "ocamlc.opt" "ocamlc" ]
-  > ]
-  > install: [
-  >   [ "mkdir" "-p" "%{bin}%" ]
-  >   [ "cp" "ocamlc.opt" "%{bin}%/" ]
-  >   [ "cp" "-P" "ocamlc" "%{bin}%/" ]
-  > ]
   > EOF
+  $ append_fake_compiler_commands \
+  >   
relocatable-repo/packages/ocaml-base-compiler/ocaml-base-compiler.5.4.0/opam \
+  >   "ocamlc binary"
 
   $ mkdir -p relocatable-repo/packages/ocaml/ocaml.5.4.0
   $ cat > relocatable-repo/packages/ocaml/ocaml.5.4.0/opam << 'EOF'
@@ -99,49 +108,41 @@
   $ dune_cmd stat hardlinks $(get_build_pkg_dir 
ocaml-base-compiler)/target/bin/ocamlc.opt
   3
 
-Test the upstream opam-repository approach: the "relocatable" virtual package.
-Non-relocatable compilers conflict with it, so if it's in the solution the
-compiler must be relocatable. See 
https://github.com/ocaml/opam-repository/pull/29451
+With the shared cache disabled, building the compiler twice should reuse the
+workspace-local target from the first build.
+
+  $ rm -rf _build dune-cache
+  $ export DUNE_CACHE=disabled
+  $ build_pkg relocatable-compiler
+  $ build_pkg relocatable-compiler 2>&1 | grep "Building relocatable-compiler"
+  [1]
+  $ dune trace cat | jq -r '
+  >   select(.cat == "cache" and .name == "workspace_local_miss")
+  >   | select(.args.head | test("relocatable-compiler.*target$"))
+  >   | .args.reason
+  > '
+
+Test that OCaml 5.5 and newer compilers are treated as relocatable based on
+their version.
 
 We clean up the previous build state first:
 
   $ rm -rf _build dune.lock dune-cache mock-opam-repository
+  $ export DUNE_CACHE=enabled
   $ mkrepo
 
-  $ mkpkg relocatable packages << 'EOF'
-  > EOF
-
-The non-relocatable compiler in the mock repo conflicts with relocatable:
-
-  $ mkpkg ocaml-base-compiler 5.3.0 << 'EOF'
-  > conflicts: [ "relocatable" ]
-  > build: [
-  >   [ "sh" "-c" "echo 'ocamlc binary' > ocamlc.opt" ]
-  >   [ "ln" "-s" "ocamlc.opt" "ocamlc" ]
-  > ]
-  > install: [
-  >   [ "mkdir" "-p" "%{bin}%" ]
-  >   [ "cp" "ocamlc.opt" "%{bin}%/" ]
-  >   [ "cp" "-P" "ocamlc" "%{bin}%/" ]
-  > ]
+  $ mkpkg ocaml-compiler 5.5.0 << 'EOF'
   > EOF
+  $ append_fake_compiler_commands \
+  >   "$mock_packages/ocaml-compiler/ocaml-compiler.5.5.0/opam" \
+  >   "relocatable ocamlc"
 
-A relocatable compiler does not conflict with relocatable:
-
-  $ mkpkg ocaml-base-compiler 5.3.0+relocatable << 'EOF'
-  > build: [
-  >   [ "sh" "-c" "echo 'relocatable ocamlc' > ocamlc.opt" ]
-  >   [ "ln" "-s" "ocamlc.opt" "ocamlc" ]
-  > ]
-  > install: [
-  >   [ "mkdir" "-p" "%{bin}%" ]
-  >   [ "cp" "ocamlc.opt" "%{bin}%/" ]
-  >   [ "cp" "-P" "ocamlc" "%{bin}%/" ]
-  > ]
+  $ mkpkg ocaml-base-compiler 5.5.0 << 'EOF'
+  > depends: [ "ocaml-compiler" {= "5.5.0"} ]
   > EOF
 
-  $ mkpkg ocaml 5.3.0 << 'EOF'
-  > depends: [ "ocaml-base-compiler" {>= "5.3.0"} ]
+  $ mkpkg ocaml 5.5.0 << 'EOF'
+  > depends: [ "ocaml-base-compiler" {= "5.5.0"} ]
   > EOF
 
   $ cat > dune-project << 'EOF'
@@ -149,7 +150,7 @@
   > (package
   >  (name test)
   >  (allow_empty)
-  >  (depends ocaml relocatable))
+  >  (depends ocaml))
   > EOF
 
   $ cat > dune-workspace << EOF
@@ -161,15 +162,15 @@
   >  (url "file://$PWD/mock-opam-repository"))
   > EOF
 
-Requiring relocatable should exclude the non-relocatable compiler:
+Solving for OCaml 5.5 should pick the split compiler packages:
 
   $ dune_pkg_lock_normalized
   Solution for dune.lock:
-  - ocaml.5.3.0
-  - ocaml-base-compiler.5.3.0+relocatable
-  - relocatable.packages
+  - ocaml.5.5.0
+  - ocaml-base-compiler.5.5.0
+  - ocaml-compiler.5.5.0
 
-  $ build_pkg ocaml-base-compiler
+  $ build_pkg ocaml-compiler
 
 Toolchain cache should be empty:
 
@@ -179,6 +180,5 @@
 Check the installed files from the compiler are hardlinked (cached as regular
 package):
 
-  $ dune_cmd stat hardlinks $(get_build_pkg_dir 
ocaml-base-compiler)/target/bin/ocamlc.opt
+  $ dune_cmd stat hardlinks $(get_build_pkg_dir 
ocaml-compiler)/target/bin/ocamlc.opt
   3
-

Reply via email to