Quick upgrade guide from opam 1.2 to opam 2.0

This guide is not a complete list of changes, but it highlights changes that users of opam 1.2 should know about, as well as some important new features.


What you need to be aware of

Some commands have changed syntax:

  • opam switch: create must be specified to create a new switch. You should then specify either --empty or a base compiler package, e.g. use opam switch create 4.06 ocaml-base-compiler.4.06.0 to create a new switch named 4.06. Just opam switch create 4.06.0 also still works in most cases.

  • opam repository (or opam remote): repositories are still configured globally, but are now selected for each switch. So by default opam repository add will only affect the current switch. You can change the defaults with --set-defaults, and choose the repositories at switch creation time with opam switch create --repositories REPOS

  • opam list and opam show have been largely reworked to offer more options

  • options to build tests and documentation are now respectively --with-test and --with-doc. They only apply to packages listed on the command-line

The opam-admin tool, for repository operations, is now built into opam, use the opam admin command instead.

Opam now comes with a solver built-in, which means that installing aspcud alongside opam is no longer required.

Pinning to a version-controlled directory will now only use what is committed by default (opam 1.2 had a "mixed mode" where it would use the current versions of files, but only the version-controlled ones. This was good most of the time, but could become puzzling e.g. when opam didn't see an added source file). The option --working-dir can be used to temporarily make opam fetch uncommitted changes (see also --inplace-build). Upon pinning, opam 2.0 will also select the current branch by default if unspecified, so that later running git checkout BRANCH in the source tree doesn't affect the pinned package.

New features

  • new command aliases: opam var, opam exec, opam env can be used in place of the corresponding opam config subcommands

  • new command: opam clean to clear caches, logs, etc.

  • local switches: use e.g. opam switch create . to create a switch in the current directory. The switch contents will be in a _opam directory, which can be safely removed once done. The switch path can then be used as a handle to refer to the switch. Additionally, the above command will install any packages which definitions are found in the selected directory into the local switch.

  • automatic pinning: use e.g. opam install . to pin and install any packages found in the current directory. opam install . --deps-only can also be used to prepare a switch for working with a source tree. This extension also concerns the remove, upgrade, reinstall and show commands, and specifying the path to a specific opam file is also supported.

  • archive caching: opam now uses a much better caching mechanism, both locally and on the opam-repository. In particular, upstream repositories being down should no longer prevent package installation (even for older or removed packages). Git repositories are also cached.

  • better error mitigation, messages and recovery. opam install --restore can be used to retry after a failed operation.

  • a plugin, e.g. opam-depext, will now be available from all switches once installed in one.

  • opam install --destdir can be used to copy build artefacts of given packages to an external prefix

  • sandboxing: on Linux, all package commands will now be sandboxed by default. The bubblewrap tool is now required to this end.

File formats

What you need to be aware of

Repositories and migration

Repositories for 1.2 and 2.0 have a different format, but everything should be transparent unless you publish packages:

Everything from 1.2 is converted to 2.0 when needed (on the fly by opam, automatically on the git repository, or manually using opam admin upgrade). >

When publishing packages, remember that:

  • packages in 1.2 format must be published to master, and they will be available to everyone
  • packages in 2.0 format must be published to the 2.0.0 branch — e.g. using the new opam-publish.2.0. They will only be available to opam 2.0 users.
  • compiler definition files: these no longer exist, as compilers have been replaced by normal package definitions (that should have flags: compiler)

  • the base syntax of opam files didn't change, but:

    • compilers now being packages, e.g. the field available: [ ocaml-version >= "4.00.1" ] is now encoded as a dependency towards the ocaml package with depends: [ "ocaml" {>= "4.00.1"} ]. The ocaml-version variable is no longer defined.

    • extra dependencies needed for test and documentation must now be flagged with resp. with-test and with-doc. Fields build-test: and build-doc: are deprecated in favour of filters on build: instructions, and there is a new run-test: field

    • the format of the depexts: field is changed

    • the host system is now polled through the arch, os, os-distribution and os-version variables. os may now take the value macos instead of darwin.

    • depopts: [ "foo" >= "v0" ] now means that the optional dependency is only active for the corresponding versions, there is no implicit conflict with "foo" < "v0"

  • URLs must now be non-ambiguous in files, e.g. you must use git+https://github.com/owner/pkg.git rather than https://github.com/owner/pkg.git. The latter will still be understood as git and rewritten to the former if used from the command-line.

  • Any specified patches: must now apply with patch -p1 and use unified, rather than context, diffs.

  • opam switch export/import format has been changed (but files in the 1.2 format can still be read)

  • the conversion from the 1.2 format is done internally and automatic, both for repositories and when pinning. Be careful, however, not to submit 2.0 format files if they are to be used by opam 1.2, or published to the main repository before it makes the transition.

New features

opam files have been extended in a lot of ways:

For more details on the new opam, see: