-
Notifications
You must be signed in to change notification settings - Fork 390
Package variants: a trivial cross-compilation solution #2476
Description
So I know there's #1536, however, that issue has too much bikeshedding for my taste. I've implemented cross-compilation for two platforms already (https://github.com/whitequark/opam-cross-windows and https://github.com/whitequark/opam-cross-android) and I think we don't need all that complexity (cross-switch dependencies etc). I have a much simpler proposal.
Let's define a notion of variant packages. A variant package differs from a regular package by a suffix in its name, e.g. re-cross:windows-x86. The suffix is available via the variable %{variant}%. This variable, as a special case, is resolved in version constraints as well as %{version}% (#1993). Since it is a constant string that can include no evaluation of its own, I don't think that presents any practical problems, and a violation of abstraction levels in opam that it entails is more a reflection of an opam's design shortcoming than any true problem.
Given a package name re-cross:VARIANT, it is resolved to an opam file as follows. If a repository has a package with the verbatim name re-cross:VARIANT, then that package's opam file is used. If not, but it has a package re-cross whose opam file includes flags: [ variant ], that package's opam file is used. Otherwise the re-cross:VARIANT package is considered nonexistent.
I'm using re-cross here since the variant mechanism is fairly generic and it may be useful for more than cross-compilation; on top of that the opam files for cross-compiled packages often differ substantially and it is not immediately obvious whether merging them with the non-cross-compiled opam file is wise. Of course, we could decide that the only use for the variant mechanism should be cross-compilation and call it something like "platform".
This is essentially the only thing that is required to support cross-compilation as a first-class citizen. Concepts like a dependency on a build component are expressed elegantly. Similarly, dependency trees are rooted in packages such as ocaml:windows-x86, which do not include flags: [ variant ]; this prevents installation of nonsensical variants.