Compatibility packages & conditional dependencies in opam

I notice several packages are “Compatibility packages” for supporting various versions of ocaml, for instance uchar or seq.

If I’m using OCaml 4.10, In principle I need neither of them, but if I ask opam to install uutf it will install uchar, and if I want lwt it will install seq.

Isn’t there a way to tell opam “install foo only if ocaml version < xx.xx”?

The problem (as I understand it) is that these packages (uutf, lwt, etc) mention the compatibility packages in their build system dependencies, so one cannot just not install them. I agree this is a major pain point with these compatibility packages. Fixing would need some collaboration from the build system.

Interestingly, dune does what is needed when building code without ocamlfind installed: it “synthetizes” these compatibility packages when the underlying OCaml version provides them. Perhaps this logic could be extended as well to the case when ocamlfind/opam are installed…

cc @jeremiedimino

Best wishes,
Nicolás

2 Likes

Yes. Conditional dependencies can be stated like this:

  ("ocaml" {>= "4.03.0"} | "result")

Lwt does this for ocaml-syntax-shims.


Note that Dune’s library dependencies can also be made conditional using the OCaml escape hatch for dune files. Lwt already does this to conditionally add future_syntax preprocessing.

As far as I know, there’s no hard blocker in the way of conditionally depending on compatibility packages. I created an Lwt issue last week about doing this for result and seq. (I also have a prototype implementation, but it needs some work.)

2 Likes

@nojb AFAICT, this is what Dune already does. The lookup procedure is as follow:

  • first look in the current project
  • then look in all the public libraries in the workspace
  • then look in installed libaries
  • then look in hardcoded builtins

and this doesn’t depend on whether ocamlfind is installed or not.

FTR, I’d prefer if we didn’t have any hardcoded builtins in Dune and instead the compiler shipped META files for the libraries it distributes.

1 Like

This is what dune does already: with OCaml < 4.08, (preprocess future_syntax) is the same as (preprocess no_preprocessing): https://dune.readthedocs.io/en/stable/concepts.html?highlight=future_syntax#future-syntax

1 Like

Thanks for the clarification @jeremiedimino, I misremembered. In that case, it is enough to make the dependencies conditional in the opam file, indeed.

Cheers,
Nicolás

Thanks, that’s great; is there a way to include this in dune-project together with ((generate_opam_files true) ?

1 Like

From a look at the documentation of the grammar of package specifications[^1] it looks like it’s not supported:

op := '=' | '<' | '>' | '<>' | '>=' | '<='

stage := :with-test | :build | :dev

constr := (<op> <version>)

logop := or | and

dep := (name <stage>)
     | (name <constr>)
     | (name (<logop> (<stage> | <constr>)*))

dep-specification = dep+

Each dep needs a single name, and logops can apply only to version constraints.

(I suspect the Dune team would be happy to support this, if you feel like raising an issue / making a PR about it.)


[^1]: … which is incidentally quite hard to find. Perhaps the section on generating opam files should link to it?

1 Like