`Unix` module on macOS "not implemented" when `dune build` but working in `dune utop`

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