Skip to content

fix(bin-pform): use installed filenames in Windows layouts - #15518

Merged
Alizter merged 1 commit into
ocaml:mainfrom
Alizter:bin-layout-installed-filenames
Jul 20, 2026
Merged

fix(bin-pform): use installed filenames in Windows layouts#15518
Alizter merged 1 commit into
ocaml:mainfrom
Alizter:bin-layout-installed-filenames

Conversation

@Alizter

@Alizter Alizter commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Description

Use installed filenames when materializing %{bin:...} PATH layouts for local package binaries.

Artifact lookup keys intentionally omit .exe on Windows, but those keys were also being used as physical layout filenames. Carry the lookup name together with the installed filename of the selected binary through the layout key instead. Native executables are therefore materialized as launcher.exe, while explicitly named entries such as tool.cmd remain unchanged.

This updates the Windows regression test added in #15517 from the documented failure to the corrected behavior.

Related Issue and Motivation

Fixes #15512.

Validation

  • ./dune.exe build @check @fmt
  • Focused cram test with the mingw-5.4 opam switch on native Windows 11

Checklist

@Alizter
Alizter force-pushed the bin-layout-installed-filenames branch from 1c64076 to 325c4e7 Compare July 17, 2026 20:01
]
;;

let compare x y =

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use Repr.Poly here so we don't have to write boilerplate.

@Alizter Alizter Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought so too, but Filename.repr is a Repr.view, which Repr.Poly rejects during runtime validation. On closer inspection, Filename.t is a validated path component backed by a string, and its comparison is exactly String.compare, so polymorphic comparison is sound here; ./foo is not a valid Filename.t. The remaining obstacle is the conservative validation of views. Changing Filename.repr to expose its structural string representation would allow us to use Repr.Poly; for now I’ll keep the explicit comparison and leave a CR for that cleanup.

Artifact lookup intentionally removes the .exe suffix from local binary keys
on Windows. Bin layouts reused those lookup keys as physical filenames, so an
action with %{bin:launcher} in its dependencies received a PATH directory
containing launcher rather than launcher.exe.

Keep the installed filename of the selected local package binary together with
the lookup name when constructing the layout. Key the layout by both names and
use the recorded lookup name when resolving the original artifact. This creates
launcher.exe for native executables while preserving declared names such as
tool.cmd.

Add a native Windows regression test covering both kinds of bin entry.

Signed-off-by: Ali Caglayan <alizter@gmail.com>
@Alizter
Alizter force-pushed the bin-layout-installed-filenames branch from 325c4e7 to 892d033 Compare July 20, 2026 07:55
@Alizter Alizter mentioned this pull request Jul 20, 2026
56 tasks
@Alizter
Alizter merged commit cb37311 into ocaml:main Jul 20, 2026
25 of 26 checks passed
@Alizter
Alizter deleted the bin-layout-installed-filenames branch July 20, 2026 08:08
Alizter added a commit that referenced this pull request Jul 20, 2026
Backport #15517 and #15518 onto 3.24.1-rc.

This includes the Windows regression test followed by its fix.
@Alizter Alizter added this to the 3.25.0 milestone Jul 21, 2026
avsm pushed a commit to ocaml/opam-repository that referenced this pull request Jul 23, 2026
CHANGES:

### 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` (ocaml/dune#14904, fixes ocaml/dune#14775, @vouillon)

- Fix passing environment variables to formatter actions  (ocaml/dune#15386, @anmonteiro)

- Fix missing source dependency in the sandbox when preprocessing Melange
  sources (ocaml/dune#15395, @anmonteiro)

- Treat OCaml compiler packages version 5.5 or newer as relocatable so their
  installations do not use the toolchain cache (ocaml/dune#15444, fixes ocaml/dune#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. (ocaml/dune#15455, @hhugo)

- Use installed filenames for local package binaries in `%{bin:...}` PATH
  layouts on Windows (ocaml/dune#15518, fixes ocaml/dune#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 (ocaml/dune#15418, @anmonteiro)
craff pushed a commit to craff/opam-repository that referenced this pull request Jul 25, 2026
CHANGES:

### 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` (ocaml/dune#14904, fixes ocaml/dune#14775, @vouillon)

- Fix passing environment variables to formatter actions  (ocaml/dune#15386, @anmonteiro)

- Fix missing source dependency in the sandbox when preprocessing Melange
  sources (ocaml/dune#15395, @anmonteiro)

- Treat OCaml compiler packages version 5.5 or newer as relocatable so their
  installations do not use the toolchain cache (ocaml/dune#15444, fixes ocaml/dune#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. (ocaml/dune#15455, @hhugo)

- Use installed filenames for local package binaries in `%{bin:...}` PATH
  layouts on Windows (ocaml/dune#15518, fixes ocaml/dune#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 (ocaml/dune#15418, @anmonteiro)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3.24 bin layout entries don't use .exe extensions on windows

2 participants