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 build
, 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 main.ml
:
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 dune-project
is
(lang dune 3.2)
(name hellocaml)
(generate_opam_files true)
(package
(name hellocaml)
(synopsis "A short synopsis")
(description "A longer description")
(depends ocaml dune))
The 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
(libraries unix)
to your 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.
1 Like
Builds fine now.
For the developer-experience records, I saw unix.mli
under $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 sys.mli
, 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 .
3 Likes