OCaml on Windows: the long paths issue

Not very long ago, I managed to solve the long paths issue for OCaml and I want to share how.

While building a large project, I ran into the path issues - Dune would fail with errors saying a certain file present in a long file was not found. Shortening libraries names helped. But what was really needed was manifesting OCaml tools so that they can perform I/O on long paths as described here on MSDN docs.

Guidelines there expect binary artifacts (dll or exe) have to be manifested with something like this

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
        <ws2:longPathAware>true</ws2:longPathAware>
    </windowsSettings>
</application>

Ideally, the application being built is also manifested so.

I use esy as my daily driver for Windows development. I have always found the workflow on Windows with esy reasonable and never stopped using it since I discovered. Over time, I have taken up maintenance of the project too.

OCaml on Windows is practical only with Cygwin. Not because the tools needs a Unix like environment - they have evolved significants over the years since I have been using OCaml on Windows. Cygwin is convenient because of the libraries in the ecosystem - for instance all the native libraries from GNU project. GNU projects are easily built inside Cygwin/MSYS/mingw but not so outside.

I was worried that I’d have to write some gory hack in the compiler to manifest every binary artifact - dune had to be manifested too. There are many ways to embed the manifest with tools windres etc. But fortunately, I found that Mingw already embeds all executables with a default one. It can be found here among the Cygwin projects

I decided to fork the repository and use the manifest MSDN docs recommended. You can find it here This helped me fix my project, but I wanted this for the rest of the community too.

Esy uses a utility called esy-bash which packages the Cygwin environment for the user. We find that users have mostly uniform setups this way. Helps with reproducibility. I decided to tweak esy-bash to package my fork of the windows-default-manifest along with other Cygwin packages. This way OCaml users dont have to worry about the long paths issue anymore.

This has been available since esy 0.7.0. If you’d like to try the latest esy, it is available on NPM and can be installed with npm i -g esy

I’d love to hear your thoughts on this approach. More than happy to contribute a solution like this for opam too.

9 Likes