Why does dune insist on .exe extension?

I noticed that corebuild et al are now depreciated and that now the recommended way to compile programs is dune. So far so good.

What annoys me greatly, is the insistence of dune to add “.exe” to my executable. On Unix/Macos this string is meaningless and on Windows it is not required either. Why this insistence?

Thanks for any enlightment

P.S.: Just for kicks, I changed a recent snapshot of dune so that the “.exe” is not appended to the executable anymore, so this works (at least on a Mac, likely also on Unix) and was a 10 minute job. Of course, now I have issues with upgrading with opam :slight_smile:


I second this. I usually build with a Makefile having an additional line in the main rule, looking like the following :

    dune build main.exe
    mv _build/default/main.exe main

That’s not a huge issue in the end I reckon, but it is still worth mentioning.

On Windows, executable must has .exe extension so dune uses .exe for all 3 platforms mainly for consistency

The extension is not added to the public_name of the binary, though, if you are on a platform that doesn’t require the extension. For example,

 (names main)
 (public_names my_cool_tool))

You will end up building _build/default/main.exe and _build/install/default/my_cool_tool.

You can also run, e.g., dune exec my_cool_tool, which does not require the extension.


Ahh, that makes sense. So I just have to specify the name twice in the dune file, but then I get what I want.

Thank you!

Note that name has to be a valid OCaml module name, so public_name is often needed to change the binary to the actual filename you want, not necessarily just repeating the name field (see, for example, Dune’s own dune file where the public_name is simply different and opam’s tools dune file, where the public_name field is not a legal value for a name field) . See also the introduction to executable in the manual.

Dune uses the same system for names internally as ocamlbuild except that where ocamlbuild appends .native and .byte, Dune uses .exe and .bc. Further down it explains that the public_name field for executable is equivalent to adding an install stanza to name the program as you wish.

In general, if you are having to refer to things inside the build context (e.g. _build/default) then there’s probably something missing from your dune file (the install context - _build/install/default is a different matter)


On Windows the .exe is very much required, unless you’re willing to do strange tweaks to PATHEXT (for the command prompt) and the Registry (for Explorer).

Sorry I wasn’t clear; my comment about .exe not being necessary was referring to running the executable: “main” will run “main.exe” on Windows, but not on Unix. And yes, it also annoyed me about .native before – I think the POLA would be to use the convention of the OS, not some arbitrary “standard”.

The main reason for adding .exe to binaries in the build context (NB: not the install context) is that having the same extension for Unix and Windows makes it possible to write uniform dune rules that work on both systems. This is a huge win.