Is there a config/build tool similar to pythons poetry or elixirs mix or erlangs rebar3 that manages dependencies in a local “virtual environment” that sees only the dependencies specified? That also works with a lock file for full reproducability of the dev environment?
There’s esy although it’s not 1.0 yet.
opam also supports virtual environments with “local switches” and – as of Opam 2.1 – built-in support for lock file generation.
opam's lock files won’t get you truly reproducible builds since they don’t contain hashes of Opam packages (which can change by mutating either
opam-repository or the package deployment after release). That may not matter for your use-case.
(edit: did some more digging into
esy and it appears to hash the entire package on resolve. Neat!)
I’ve been using Esy for a few months now and it’s been solid. I especially like its Nix-style compilation cache–it avoids dependency recompiles even across projects.
I’m already using nix had some trouble using opam2nix the other day… Will try again!
opam2nix again, no dice…
https://gitlab.com/NobbZ/ocaml2nix-hello-example fails due to
OCAMLTOP_INCLUDE_PATH: unbound variable when building
nix-build directly in the
examples/simple dir of
opam2nix gives me
OCAMLPATH: unbound variable when building
The linked repository of mine, just tries to mimick what the mentioned example does anyway, differences I am aware of, is that I want to use a more recent version of OCaml and I have resolved at a later point in time, both might lead to a different
Can someone help me figuring this out? Or should I go and open a ticket at
opam2nix repo? Create a new thread here?
Thanks for the tip, though
esy is currently not packaged for nixOS, and from the PRs comment that tries to introduce it, it seems to be a rather complicated thing to add.
Can you tell me more with examples about how to use that?
I’m really interested in OCaml, though never really got my feets wet in it, as I never really was able to even get simplest examples working. Even hello worlds were unable to build, because some “package” wasn’t found, which I then had to install globally on my system, which again broke other stuff because of version missmatches… This was true on Ubuntu, Funtoo and Arch Linux, today on nixOS, it seems that I can’t even properly install a toolchain which would then complain about missing libraries…
Felt worse than
basically navigate to your project and type
opam switch create .
This will create a local switch using the system version of ocaml.
If you’re having trouble with it, I suggest installing a fresh version of ocaml in your switch :
opam switch list-available #list available compilers opam switch create . 4.10.0 #install lastest version of the compiler
Check that you’re in that switch by typing
opam switch (gives you the current switch and a list of available swiches) or switch into it by typing
opam switch .
Then install the libraries you want (like
opam install batteries) for example
If all you want is automatic resolution of dependencies within a local ocaml compiler context, then that is what opam is designed for. If so, read below; if not, you probably want to supplement it with something else.
The key for the use case I mentioned is not to use your distribution’s package system to set up ocaml dependencies for you. Instead, use opam. Pretty much any version of opam will do for automatically resolving dependencies, including the one supplied by your distribution, although preferably it should be at version 2.0 or greater. Really, the only ocaml package you need to have installed from your distribution is opam (although your distribution may unnecessarily insist on also installing in the /usr prefix its own version of the ocaml compiler).
Having installed your distribution’s opam package, proceed as mentioned at https://opam.ocaml.org/doc/Usage.html . After initializing opam and before installing any other ocaml software using it, it would probably be helpful for you to set up a new local compiler “switch”. For example you can install a switch for the latest stable compiler release with:
opam switch create 4.10.0
After opam has compiled and installed the ocaml compiler for you in that switch, you can then install opam packages in the switch. You can also uninstall the ocaml system compiler provided in the /usr prefix by your distribution (if it will let you do that while retaining opam).
Edit: by the way, you run opam as user, not as root.
Esy is distributed from npm, so you would need to install NodeJS, then
npm install --global esy. From there you would have the
esy binary installed in your path (and you wouldn’t need Node any more).
That doesn’t work on nixOS, as it just installs a pre-installed binary which points to a non-existing interpreter on my system.
And after that?
I added dependencies to my
opam file, how do I get them installed without having to
opam switch remove and
opam switch create . 4.10.0 afterwards? Even for my small project that takes close to 10 minutes…
You can pin the package:
opam pin add packagename ..
Once that is installed by opam you can reinstall with
opam update && opam reinstall packagename or build and run it directly from the project folder without the need to ask opam each time.
As I just want dependencies and build dependencies installed, but not the package I develop itself, what would be the workflow for that?
I’m basically searching for the equivalent of
poetry install (which indeed installs the package, but as “editable” and in the sandbox for the project only) or
mix do deps.get, deps.compile.
pin the package but don’t install it with:
opam pin add packagename . -n. Then
opam install packagename --deps-only.
There are local switches and support for lock files in opam if you prefer, but I rarely used them so I am not the best person to tell you what to do: https://khady.info/opam-sandbox.html
opam install aoc-ml --deps-only does nothing after I have added
"core" to the deps…
Did you re-pin the package or run
opam update before that?
$ opam install aoc-ml --deps-only <><> Synchronising pinned packages ><><><><><><><><><><><><><><><><><><><><><><> [NOTE] Ignoring uncommitted changes in /home/nmelzer/Projects/ocaml/aoc-ml (`--working-dir' not active). [aoc-ml.~dev] no changes from git+file:///home/nmelzer/Projects/ocaml/aoc-ml#master