Sharing tools installed with opam across switches

There are tools available through opam which are useful as a developer but not tied to specific OCaml versions. For example, ocp-indent and ocamlformat.

By default, at least under opam 1.2.2, these tools need to be installed under each switch separately to keep them available in $PATH. A user can manually maintain symlinks but it would be really nice to avoid that if at all possible.

Is there a proper/accepted way to share these tools across switches?


A clean way would be for opam to install things system-wide.
I don’t think it can currently, or if this is well-supported in case it does.


I don’t think you really need to those tools in your path as they are more editor plugins that tools to call in the cli by hand.

So probably a good way is to replace calls to ocp-index by calls to opam config exec --sw=shared-switch ocp-index.

Another solution is to use direnv to add the bin directory of the shared switch to the path from a .envrc file.


I’d like something like this in general - maybe not system-wide, but maybe opam-wide. So an installation of ocamlformat could be available once the opam environment is setup, regardless of the switch in use.

This likely becomes more complicated with tools like ocp-index, merlin and refmt which may be more tightly coupled to internal data representations.

I use ocamlformat from the CLI at times to clean up an entire repo at once. That admittedly a more limited use-case though so it doesn’t need such special treatment.

direnv is on the list of tools I keep meaning to try but never get around to. I’ll give it a shot, thanks!

I have a really lightweight solution to this: when my shell starts up, I evaluate just the first command in opam-init/, which gives me a $OPAM_SWITCH_PREFIX for the default opam switch; then I manually add that "$OPAM_SWITCH_PREFIX/bin" to my $PATH:

This allows me to have the command-line invocations of, say, ocamlformat available system-wide, but still have them overridden by anything installed in a directory-local opam switch (which I use heavily). For instance, this also means the installation of ocamlmerlin in my ‘global’ opam switch ensures I have completion, type-interrogation, etc, even in a blank Vim buffer with no associated directory … but when I switch to a directory with a very specific, custom build of Merlin for BuckleScript, then my Vim instance automatically loads that plugin instead.