I am having some trouble setting up a dev shell for OCaml development with flakes. My issue is that OCaml doesnβt seem to recognize that a given library (OUnit
) is installed. I use direnv with use flake
to setup dev shells.
my flake.nix
{
description = "laziness";
inputs = {
nixpkgs.url = github:nixos/nixpkgs;
utils.url = github:numtide/flake-utils;
};
outputs = { nixpkgs, utils, ... }:
utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs { inherit system; };
ocmlpkgs = with pkgs.ocamlPackages; [
ounit
findlib
merlin
utop
];
in {
devShell = pkgs.mkShell {
buildInputs = with pkgs; [
ocaml
] ++ ocmlpkgs;
};
});
}
When I enter the environment (either with Emacsβ direnv integration, or simply by going in the directory of this project and letting direnv directly load everything), it complains when I do open OUnit
with Unbound module OUnit
.
How do you test that it does not work ? with your flake the module if found:
$ cat foo.ml
open OUnit;;
$ ocamlfind ocamlc -package oUnit foo.ml && echo success
success
I complains about it in my editor, and when I load it in the top level.
This works:
$ echo "open OUnit;;" > foo.ml
$ ocamlfind ocamlc -package oUnit foo.ml && echo success
success
$
But not
$ utop foo.ml
File "foo.ml", line 1, characters 5-10:
1 | open OUnit;;
^^^^^
Error: Unbound module OUnit
Hint: Did you mean Unit?
$
consider using dune top dune utop instead of utop (itβs the same thing, but dune adds all the required flags)
I am not familiar with dune. Does that require me to setup a dune workspace or something alike? I have tried following the instructions of the dune documentation by doing #use_output "dune ocaml top";;
in a utop
session, but that still doesnβt work. And, indeed, when trying to do something like dune ocaml top
in a shell, it prints nothing.
Maybe itβs my project file that is wrong? Dune refused to run dune ocaml top
without it.
dune-project
(lang dune 3.4)
(name laziness)
(generate_opam_files true)
(package
(name laziness)
(depends ocaml dune))
I simply copied the result of dune init project laziness
removing the parts that werenβt useful (summary, description, β¦). It also automatically generated an empty laziness.opam
(I donβt know what is its purpose). I also tried adding ounit
to the depends
instruction, but that didnβt change anything.
Sorry I should have said dune utop
, not dune top
.
To test in a nix-shell with dune_3, utop, findlib and ounit I did:
dune init proj bar
inside bar
, I modified lib/dune
as follows:
--- lib/dune.old 2022-08-10 20:47:52.511157426 +0200
+++ lib/dune 2022-08-10 20:46:47.185280863 +0200
@@ -1,3 +1,4 @@
(library
(name bar)
+ (libraries oUnit)
)
and then dune utop
:
ββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββ
β Welcome to utop version 2.9.1 (using OCaml version 4.13.1)! β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Type #utop_help for help about using utop.
β( 20:49:51 )β< command 0 >βββββββββββββββββββββββββββββββββββββββββββββββββββ{ counter: 0 }β
utop # open OUnit;;
β( 20:49:51 )β< command 1 >βββββββββββββββββββββββββββββββββββββββββββββββββββ{ counter: 0 }β
utop #
1 Like
Iβve been using this for quite a while and it works fine, but sometimes itβs a bit awkward because I donβt use dune as my building system, so I really end up setting up all the dune files and everything just to have a working utop
β¦ Do you know a way to achieve the same result without relying on a specific build system?
no idea sorry. nix-shell populates $OCAMLPATH, you need to teach your favourite toplevel implementation to look for dependencies there.