I’m confused about what’s happening and how to fix it. I’m on macOS and the
Unix module works in
utop but fails in
dune exec, and possibly other commands. It is ocaml-platform extension in vscode sees the module (shows the signature when I hover the symbol, and allows to jump to the
unix.mli file whose path is in my one and only switch).
I have reproduced the problem in a simple app named
hellocaml with the following
let () =
Printf.printf "Hello, %s" (Unix.getenv "HOME");
When I run
dune exec hellocaml I get the following error
File "_none_", line 1:
Error: No implementations provided for the following modules:
Unix referenced from bin/.main.eobjs/native/dune__exe__Main.cmx
But if I launch
dune utop the same code works.
Using other standard libraries, such as
Sys.getenv, shows no issues.
The project was created with
dune init project hellocaml. The
(lang dune 3.2)
(synopsis "A short synopsis")
(description "A longer description")
(depends ocaml dune))
dune files have not been touched.
The unix module is part of the
unix library which is a separate library that happens to be distributed along the compiler package. You need to tell dune that your executable depends on the unix library by adding
dune file (and you probably also want to add
unix in the
depends stanza of the package).
You don’t see the missing dependency in utop because
utop loads automatically the
unix library in the REPL.
Builds fine now.
For the developer-experience records, I saw
$OPAM_SWITCH_PREFIX/lib/ocaml/unix.mli and initially tried adding
ocaml to my
(libraries ...) (if it’s under
/lib/ocaml it maybe a part of
ocaml library, I though despite seemed strange to depend on
ocaml). Then saw it was alongside
string.mli, etc. and assumed they were all treated equally.
Now I guess
unix.mli is not loaded by default as it’s OS specific.
Any idea why the ocaml-platform extension does not show an error? Shouldn’t it also abide to dune’s specifications?
It is an issue with the way that the
unix library is packaged: the interface files for the library are located in the same folder that the interface files for the standard library. Thus, the language server can see the interfaces of the modules of the library even if you did not add it explicitly the library and the missing dependency only manifests itself during linking.
Those packaging issues should be gone in OCaml 5.0 .