Non opam workflows

Very recently, I learnt that there is a significant chunk of users in the OCaml community that does not use opam to install packages. As a small initiative to contribute to tooling, I want to ensure what I build is compatible with these workflows - workflows I’m not familiar with myself.

I’d love to learn more - what does it look like? How do you setup your compiler, dune and merlin (and/or soon ocamllsp)? How do you configure your editor to find them and what would make it easier to do so?

I’m told of Duniverse as one tool that being used in these non-opam workflows. Are there any more popular ones out there?

Edit: Nix is another. I’m curious about OCaml-Nix workflows too

2 Likes

I am one of these people. I mostly rely on Nix, whose package repository nixpkgs provides package sets for all (relatively recent) versions of OCaml. These package sets are not generally as complete as what you can find on opam, so it sometimes happens that I open a PR on the nixpkgs repository to add a new package (and in the meantime I use my local updated copy of the nixpkgs repo).

You can see the list of available OCaml packages at: NixOS Search
(This is for the default OCaml version, currently 4.07 in nixpkgs-unstable. Other package sets are called ocaml-ng.ocamlPackages_4_0X but are not shown in this web search.)

Most OCaml packages are available at a single version in nixpkgs (even though you can choose your version of OCaml). To gain more flexibility on the exact version I use in one of my project, I am planning to test Duniverse. At that point, I would rely on Duniverse for library dependencies, but I would still rely on Nix to install OCaml, findlib, Dune, Duniverse (I’ll have to take care of packaging it), utop, merlin, or ocamlformat.

Nix is pretty straightforward to use. You generally provide a default.nix at the root of your repository, and it will list the dependencies that you use. When you want to go develop your project, you just enter a special shell (with the nix-shell command) and you are in an environment where the tools you need are in PATH and the libraries you need are in OCAMLPATH.

There’s just one tool that I needed special configuration for: ocamlformat (especially because some projects use it and some do not). When I use it, my default.nix contains:

shellHook = ''
  export OCAMLFORMAT_LOCATION=${ocamlformat}
'';

which will export an environment variable when I enter the shell.

And my .emacs contains:

(setq ocamlformat-location (getenv "OCAMLFORMAT_LOCATION"))
(when (> (length ocamlformat-location) 0)
 (add-to-list 'load-path (concat ocamlformat-location "/share/emacs/site-lisp"))
 (require 'ocamlformat)
 (add-hook 'tuareg-mode-hook
           (lambda () (add-hook 'before-save-hook 'ocamlformat-before-save))))

If you mean as a library author, then all you have to ensure is that you use Dune as the build system (makes the Duniverse workflow better, and makes it easier to package your library in nixpkgs, cf. buildDunePackage documented at Nixpkgs 23.11 manual | Nix & NixOS).

1 Like

You might want to check out the Fedora OCaml packages.

Unfortunately I don’t have a convenient way to link to the whole list, but if you look at all the OCaml packages here: https://koji.fedoraproject.org/koji/search?match=glob&type=package&terms=ocaml* and then if you substitute the ocaml-<packagename> in two places in this URL: https://src.fedoraproject.org/rpms/ocaml-re/blob/master/f/ocaml-re.spec (example showing ocaml-re package), you can see how we build and package them in the %prep, %build and %install sections.

And yes, please make sure your software doesn’t depend on opam. Building everything in your home directory is not suitable for enterprise software distribution.

1 Like