I’m the user @mjambon mentioned
and here’s what we found after some digging—I don’t think there’s a bug anywhere, I just had to learn more about how Cygwin works. Here’s what we now know—
If you build an OCaml binary in Cygwin and then copy the binary (plus cygwin1.dll and other DLLs required by the executable) to a fresh Windows install that doesn’t have Cygwin on it, you can, of course, run the executable.
If your code used Filename.temp_file
, the executable will likely try to access /tmp
, because, as @mjambon noted, when OCaml runs in Cygwin, it uses Unix conventions for the temp directory, which are:
let temp_dir_name =
try Sys.getenv "TMPDIR" with Not_found -> "/tmp"
We hypothesize that the environment at compile time gets frozen in the executable.
So if you put cygwin1.dll in c:\ocaml-stuff
, then /tmp
corresponds to c:\ocaml-stuff\..\tmp
, i.e., c:\tmp
. An easy way to understand this is: in Cygwin, cygwin1.dll expects to live in /bin
, so /tmp
corresponds to a sibling subdirectory. So one option is to create this tmp
directory: your OCaml executable will happily use that.
However, as the code snippet above indicates, you can override this by explicitly setting TMPDIR
environment variable. If I run set TMPDIR=.
before running my OCaml executable, it will use the current directory as the temp directory, not /tmp
.
(A nice bonus is, because Cygwin understands both Windows paths like C:\Users\User
and Unix paths like /cygdrive/c/User/Users
, you can use either with your OCaml binary.)
It might be nice if an OCaml executable could detect at runtime whether it was running in Windows or Cygwin and adjust Sysdeps
accordingly, but I do love the elegance of the current approach.