The following are beyond the scope of the FAQ, but have been found useful for specific use-cases or for advanced users.
Simulate actions from the current switch state (for debugging)
opam upgrade --show-actions(stop at the action summary dialog)opam upgrade --dry-run(display only)- if you really want to try out the results:
opam switch export testing-state.exportopam switch create tmp-testing --emptyopam switch import testing-state.export --fake- try actions with
--fake(registers them in opam, but doesn't actually run the build/install commands) - revert to normal:
opam switch <previous>; opam switch remove tmp-testing
- Experiment with the solver:
opam <request> --cudf=cudf-file- or
opam config cudf-universe >cudf-file-1.cudf - run e.g. aspcud with
aspcud cudf-file-1.cudf /dev/stdout CRITERIA
Install in all switches
Not supported natively at the moment, but it's being considered. Quick hack:
for switch in $(opam switch list -s); do
opam install --switch $switch PACKAGE
doneYou may want to add --yes if you're confident.
Update opam environment within emacs
The best way is to use opam-user-setup (just run opam user-setup install),
and that will make the opam-update-env interactive function available in
emacs.
You could also define the function by hand:
(defun opam-env ()
(interactive nil)
(dolist (var (car (read-from-string (shell-command-to-string "opam config env --sexp"))))
(setenv (car var) (cadr var))))
You may want to run this at emacs startup if it doesn't inherit the proper shell
environment. Be also careful that tuareg-mode has its own bindings that
override the environment when using the compile command, so that may get in
the way (see Tuareg issue #94).
Provide a set of packages for a group of users to install
The easiest way is to create a package with your prerequisites as depends and
have them pin that. A quick way to host the file is to use a
Gist. Create one with minimal contents and listing
your packages as dependencies -- the file name has to be opam:
opam-version: "2.0"
name: "ocaml101"
version: "0.1"
maintainer: "Louis Gesbert <louis.gesbert@ocamlpro.com>"
depends: [ "menhir" { = "20140422" }
"merlin" { >= "2" }
"ocp-indent"
"ocp-index" ]
Save that and get the HTTPS clone URL. All that is needed then is to run:
$ opam pin <HTTPS clone URL>
Furthermore, opam update will then pick up any modification you made to the gist.
These other options may offer more control, with a little more work, depending on the scale you work at:
- distribute an "export" file, as generated by
opam switch export <file> - define and host your own repository, and use a specific
opamrcfile on the user's systems, to automatically select your repository and defaults onopam init.
Alternate implementations for a package
opam currently doesn't support a provides: field that would allow packages to
replace others. If you have two packages a and b providing foo, you need
to:
Define a (virtual) package
foo, withdepends: ["a" | "b"], for any version you want available: so if the versions ofa,bandfoomatch you would have e.g.foo.1withdepends: ["a" {= "1"} | "b" {= "1"}]. Or, better, using opam 2.0 variables:depends: ["a" {= _:version} | "b" {= _:version}], duplicated for any version desired.Make sure
aandbconflict with each other. The scalable solution for this is to use theconflict-class:field: add e.g.conflict-class: "foo-implementation"to all versions of bothaandb.
The need to define the virtual package explicitly also ensures that a third
package can't inject a new implementation without that being visible in foo:
it would otherwise be a security hole when we deploy end-to-end signing of
packages.
How to rename a package
Opam doesn't technically allow packages to be renamed, but you can create a
package with the new name, and a upgrade path between the two. Assuming you want
to rename foo to bar:
- Create a new version of
foo, e.g.foo.transition, depending onbar, and with a description mentioning it is a virtual package that can be safely removed. The package shouldn't have a source URL or build, install, etc. instructions. - Create
baras a new package. - Add
conflicts: "foo" {!= "transition"}. Remember to keep that field on any new version ofbar.
This ensures at the same time that users upgrading will get the new package
bar, and that the package can't be installed twice under the two names.
Display the current "opam switch" in the prompt ?
This can get quite handy if you have many switches you use in parallel.
You can use e.g. the command opam switch show --safe 2>/dev/null | sed
's|.*/|*|' to return a (shortened) switch name.
For bash, just include $(COMMAND) in your definition of PS1 (making sure the $ is escaped).
For zsh, use setopt prompt_subst, and include $(COMMAND) in the definition of prompt.
How to install a maximum number of packages ?
The following sequence of commands tries to install as much packages as possible in a local switch with OCaml $(VERSION).
opam update
opam switch create . ocaml-base-compiler.$(VERSION)
export OPAMSOLVERTIMEOUT=3600
export OPAMSOLVERTOLERANCE=1.0
opam list --available -s | xargs opam install --best-effort --yes
# Be patient


