Help building OCaml LSP package `ocaml-lsp`

Summary:

  • Trying to build ocaml-lsp which isn’t part of nixpkgs
  • ocaml-lsp builds, but I don’t get a binary
  • If I run the make lsp-server command through a hook, the build fails and complains about missing dependencies
  • I’m unsure which deps go in buildInputs and which in propagatedBuildInputs and how the git submodules affect this whole process (for OCaml in general and ocaml-lsp in particular)

I want to play around with OCaml. I checked the setup instructions but decided to skip opam and see how far I can get with just Nix. Most packages are easy to build with buildDunePackage but I just can’t get ocaml-lsp to build. Part of the reason is probably my complete lack of understanding of Dune and OCaml in general.

Here’s what I currently have in shell.nix, with some (hopefully) irrelevant details ellided (the entire file can be found in this gist)

    ocaml-lsp = pkgs.ocaml-ng.ocamlPackages_4_09.buildDunePackage rec {
        pname = "lsp";
        version = "latest";

        ocaml = pkgs.ocaml-ng.ocamlPackages_4_09.ocaml;

        minimumOCamlVersion = "4.06.1";

        src = pkgs.fetchgit {
            url = "https://github.com/ocaml/ocaml-lsp";
            sha256 = "0jlh6zxrdcnfdbici2gwwk4j83hb2fvlnf285wpcbdwh08w14afa";
            fetchSubmodules = true;
        };

        useDune2 = true;

        buildInputs = [ 
        ];
        propagatedBuildInputs = [ 
            pkgs.ocaml-ng.ocamlPackages_4_09.yojson
            ppx_yojson_conv_lib 
            pkgs.ocaml-ng.ocamlPackages_4_09.stdlib-shims
            pkgs.ocaml-ng.ocamlPackages_4_09.menhir
            pkgs.ocaml-ng.ocamlPackages_4_09.cmdliner
            pkgs.ocaml-ng.ocamlPackages_4_09.merlin
            cinaps
        ];
        doCheck = false;

        preInstall = ''
            make lsp-server
        '';
    };

As you can see I’m installing a bunch of dependencies, which where reported as missing during the make lsp-server part (I tried various combinations of buildInputs and propagatedBuildInputs). The interesting thing is that it works if I omit the make lsp-server part, but then I don’t get the actual ocamllsp binary. The build instructions for ocaml-lsp mention these steps:

# clone repo with submodules
git clone --recursive git@github.com:ocaml/ocaml-lsp.git

# if you already cloned, pull submodules
git submodule update --init --recursive

# create local switch (or use global one)
opam switch create . ocaml-base-compiler.4.09.1

# install dependencies
opam install . --deps-only --with-test

# build
make build

# install ocamllsp
make lsp-server

Notice that they’re installing at least some dependencies as git submodules.

I looked at other OCaml packages in the Nix repository but I couldn’t find anything similar. I’m a bit lost and I’m unsure if I should ask in a more OCaml-specific place or here. Right now the error I’m getting is

File "ocaml-lsp-server/src/dune", line 8, characters 16-37:
8 |    merlin.utils merlin.query_commands result yojson ppx_yojson_conv_lib
                    ^^^^^^^^^^^^^^^^^^^^^
Error: Library "merlin.query_commands" not found.
Hint: try: dune external-lib-deps --missing @install

Here’s a gist with the entire shell.nix file.

Lastly, I can build and install the program successfully with opam if I follow their instructions. But relying on a 3rd party build tool which Nix has no control over whatsoever would be a last resort. I’m in no rush with this whole OCaml thing and my primary goal here is to understand what I’m doing wrong and if it’s the Nix part or the OCaml part.

Thank you for asking here, it enabled me to get something that for now at least produces the binary at the correct location such that it can be found!

I have not yet actually verified that the LS works as it should, I’m just starting with OCaml and wanted to have the LS sorted outr first.

Please see my current solution:

https://gitlab.com/NobbZ/nix-home-manager-dotfiles/-/blob/master/nix/myOverlay/ocaml-ls/default.nix