Recommended way to provide config when installing OPAM packages?

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.

1 Like

@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.

1 Like

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.

1 Like

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.

1 Like

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

1 Like

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 :slightly_smiling_face:

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 :dragon:) :slightly_smiling_face: 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 the ocaml-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 and OPAMVAR_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 the opam 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 then OPAMVAR_my-config-package_foo=baz opam install my-package will communicate that option to the opam file
1 Like

Could you please clarify that or point to some docs ? I can’t figure out what is where here :–)