I’m working on packaging the wasm-micro-runtime for OCaml & OPAM; however, it has ~30 configuration parameters to pass to it’s CMake build process. I’d like to provide defaults for these but also allow users to configure it when they install the package with opam install
. Is there a recommended way to provide this level of configuration to packages you’d install from opam?
I don’t think so, see this issue. Though since we managed to do without it for so long I’m no longer sure it’s such a good idea.
The problem is that configurability tends to be a support and repository testing nightmare.
I don’t know what kind of things you get to configure but maybe you could design one or two sound profiles (say wasm-rt-blabla
, wasm-rt-blibli
) you deem important and have them not coninstallable and a proxy package wasm-rt
that installs one of them.
To do so you should put both wasm-rt-blabla
, wasm-rt-blibli
in the same conflict-class:
, say wasm-rt-class
, and then have a proxy package wasm-rt
which has the following depends:
depends: [ (wasm-rt-blabla | wasm-rt-blibli)]
The OCaml compiler itself achieves something of this sort by having a number of optional empty option packages whose presence (or the lack of it) affects the compiler itself: opam - ocaml-variants.4.14.0+options.
There’s a longer description of that here: Experimental new layout for the ocaml-variants packages in opam-repository.
Although I’m not sure how recommended this approach is for other packages, especially for 30 parameters. Also, this doesn’t work well if one parameter has many values (the compiler ones are essentially boolean).
Boiling it down to a handful of common configurations might still be reasonable. If someone wishes to fine-tune things more precisely, they might be better off checking out the source repository directly.
@dbuenzli If I’m following the trail of the linked issue, it seems that you can set values via opam commands. Would those then not be available to the build command?
I think you can set variables per switch but I’m not sure I would recommend it for configuring packages.
For example if you change a variable I doubt (to be confirmed though) your package will recompile, so it becomes unclear what the configuration of your package actually is.
Also I don’t know what the stance would be on this from opam’s repository maintainers. I don’t want to speak for them but I suspect they wouldn’t like it.
Here’s another idea (not fully formed tough).
You could have a wasm-rt-conf
package. That package simply writes a file in wasm-conf:etc
with the configuration. Your wasm-rt
package depends on wasm-rt-conf
and reads that file during the build to invoke cmake with the right options.
Now unless things have changed opam reads your current environment variables. So wasm-rt-conf
should read variables to set the configuration values, so
WASM_RT_OPTION1=v1 WASM_RT_OPTION2=v2 opam install wasm-rt-conf
would set option1 to v1 and option2 to v2 in the configuration. Not necessarily super convenient but does the job and provides us with something to read to understand the current configuration.
I like this! Would the wasm-rt-conf
package be more convenient then providing the env vars when installing wasm-rt
directly? What would be the benefits?
I don’t see any :–) Just make sure to write the actual conf somewhere so that we know what is really installed.
Also if you write this as a wasm-rt.config
file at the root of the build. You could then query the actual configuration via opam var wasm-rt:option1
There was a case recently, where a package with custom variable filters was merged into the repository, but that caused some issues, so those parts were removed again:
opam
does indeed reject attempts to set package variables at the moment, but I did have a branch for doing this (unpushed, for some reason - but I expect it’s terribly stale, wherever I left it!). That was for a precursor to the ocaml-option-
packages, which is the only reason I didn’t get around to upstreaming it. It did the “obvious” thing - if you change a package’s configuration, then it triggers a reinstall of it. I’d regarded my branch as a very “poor man’s” version of your package variables spec
FWIW, I think proper package parameters is a feature we’ve survived without, but not at all in a good way. Speaking as one of the co-designers of it, the ocaml-option-
packages are just a workaround, and in no way a good UI for configuring the compiler! The benefit of the approach is that it didn’t require a change to opam
to do it (so it works for 2.0, although they’re slightly less awkward to use with 2.1’s switch invariants). It’s definitely on the table to be looked at properly for opam 3.x.
Agreed - although where the testing nightmare is concerned, what we were doing before was putting a padlock on the scary wardrobe door by requiring any exotic combination to fork opam-repository (you want flambda and no-flat-flat-array, my friend, here be ) The support side is definitely an issue: being certain exactly which compiler configuration the stuck user is talking about. For the compiler, opam config report
is certainly supposed to include the option packages, as they’re part of the invariant/base. For other other packages, that’s a case for having a more formal package parameter arrangement, and with it a decent UI/UX for displaying what they’re set to (i.e. being able to see in opam list
or whatever that package parameters have been set).
Right now, I wouldn’t say the compiler occupies a “privileged” position where configuration packages are concerned, but I’d take these various “tricks”/“hacks” into account for what you’re trying to do, @phated:
- The main benefit of the
ocaml-option-
packages (apart from eliminating the combinatorial explosion of packages which had to be created on each compiler release) is that they can conflict each other (in particular, that’s used to implement theocaml-options-only-
packages, which are there so that you can have an “flambda, and don’t you dare change it!” switch). - @sim642’s point about using the packages for essentially booleans is correct, although note that you can use the
OPAMVAR_var
andOPAMVAR_package_var
“trick” to specify the variables in a variable at the command line - Speaking of
OPAMVAR_package_var
- that may be sufficient here for a lot of the string options? It’s somewhat clunky in theopam
file, but you can do something like"--with-foo=default" {my-config-package:foo = ""} "--with-foo=%{my-config-package:foo}%" {my-config-package:foo != ""}
and thenOPAMVAR_my-config-package_foo=baz opam install my-package
will communicate that option to theopam
file
Could you please clarify that or point to some docs ? I can’t figure out what is where here :–)