OCaml Changelog

RSS

Read the latest releases and updates from the OCaml ecosystem.

opam 2.3.0

Feedback on this post is welcomed on Discuss!

As mentioned in our talk at the OCaml Workshop 2024, we decided to switch to a time-based release cycle (every 6 months), starting with opam 2.3.

As promised, we are very pleased to announce the release of opam 2.3.0, and encourage all users to upgrade. Please read on for installation and upgrade instructions.

Try it!

In case you plan a possible rollback, you may want to first backup your ~/.opam or $env:LOCALAPPDATA\opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

For Unix systems

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh)"

or from PowerShell for Windows systems

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) }"

or download manually from the Github "Releases" page to your PATH.

  1. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Major breaking change: extra-files

When loading a repository, opam now ignores files in packages' files/ directories which aren't listed in the extra-files field of the opam file. This was done to simplify the opam specification where we hope the opam file to be the only thing that you have to look at when reading a package specification. It being optional to list all files in the extra-files: field went against that principle. This change also reduces the surface area for potential file corruption as all extra-files must have checksums.

This is a breaking change and means that if you are using the files/ directory without listing them in the extra-files: field, you need to make sure that all files in that directory are included in the extra-files field. The resulting opam file remains compatible with all previous opam 2.x releases.

If you have an opam repository, you should make sure all files are listed so every packages continues to work without any issue, which can be done automatically using the opam admin update-extrafiles command.

Major changes

  • Packages requiring an unsupported version of opam are now marked unavailable, instead of causing a repository error. This means an opam repository can now allow smoother upgrade in the future where some packages can require a newer version of opam without having to fork the repository to upgrade every package to that version as was done for the upgrade from opam 1.2 to 2.0

  • Add a new opam list --latests-only option to list only the latest versions of packages. Note that this option respects the order options were given on the command line. For example: --available --latests-only will first list all the available packages, then choose only the latest packages in that set; while --latests-only --available will first list all the latest packages, then only show the ones that are available in that set

  • Fix and improve opam install --check, which now checks if the whole dependency tree of the package is installed instead of only the root dependencies

  • Add a new --verbose-on option to enable verbose output for specified package names. Thanks to @desumn for this contribution

  • Add a new opam switch import --deps-only option to install only the dependencies of the root packages listed in the opam switch export file

  • opam switch list-available no longer displays compilers flagged with avoid-version/deprecated unless --all is given, meaning that pre-release or unreleased OCaml packages no longer appear to be the latest version

  • opam switch create --repositories now correctly infers --kind=git for URLs ending with .git rather than requiring the git+https:// protocol. This is consistant with other commands such as opam repository add. Thanks to @Keryan-dev for this contribution

  • opam switch set-invariant now displays the switch invariant using the same syntax as the --formula flag

  • The builtin-0install solver was improved and should now be capable of being your default solver instead of builtin-mccs+glpk. It was previously mostly only suited for automated tasks such as Continuous Integration. If you wish to give it a try, simply calling opam option solver=builtin-0install (call opam option solver= restores the default)

  • Most of the unhelpful conflict messages were fixed. (#4373)

  • Fix an opam 2.1 regression where the initial pin of a local VCS directory would store untracked and ignored files. Those files would usually be cleaned before building the package, however git submodules would not be cleaned and would cause issues when paired with the new behaviour added in 2.3.0~alpha1 which makes opam error when git submodules fail to update (it was previously a warning). (#5809)

  • Fix the value of the arch variable when the current OS is 32bit on a 64bit machine (e.g. Raspberry Pi OS). (#5949)

  • opam now fails when git submodules fail to update instead of ignoring the error and just showing a warning

  • opam's libraries now compile with OCaml >= 5.0 on Windows

  • Fix the installed packages internal cache, which was storing the wrong version of the opam file after a build failure. This could be triggered easily for users with custom repositories with non-populated extra-files. (#6213)

  • Several improvements to the pre-built release binaries were made:

    • The Linux binaries are now built on Alpine 3.20
    • The FreeBSD binary is now built on FreeBSD 14.1
    • The OpenBSD binary is now built on OpenBSD 7.6 and loses support for OpenBSD 7.5 and earlier
    • Linux/riscv64 and NetBSD/x86_64 binaries are now available

And many other general, performance and UI improvements were made and bugs were fixed. You can take a look to previous blog posts. API changes and a more detailed description of the changes are listed in:

This release also includes PRs improving the documentation and improving and extending the tests.

Please report any issues to the bug-tracker.

We hope you will enjoy the new features of opam 2.3!

Feedback on this post is welcomed on Discuss!

We're happy to announce the first and hopefully only release candidate of opam 2.3.0.

This version does not have any significant change compared to the previous 2.3.0~beta2 release and we hope the final release to also have no significant change. Regardless, we invite users to test this version to make sure there isn't any regressions.

Unless a regression is spotted or another problem arises, we hope to have the final release of 2.3.0 out on the 12th of November.

Try it!

The upgrade instructions are unchanged:

  1. Either from binaries: run

For Unix systems

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.3.0~rc1"

or from PowerShell for Windows systems

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.3.0~rc1"

or download manually from the Github "Releases" page to your PATH.

  1. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Happy hacking!

Feedback on this post is welcomed on Discuss!

We're happy to announce the second beta release of opam 2.3.0.

As this version is a beta, we invite users to test it to spot previously unnoticed bugs as we head towards the stable release.

Changes

Compared to the previous 2.3.0~beta1 release, the main change is:

  • Fix a regression in the detection of the current terminal size that leads to opam output that tries to fit itself into 80 columns regardless of the current terminal size (#6243).

  • A NetBSD/x86_64 pre-built release binary is now available

You can view the full list of changes, including API changes, in the release note.

Try it!

The upgrade instructions are unchanged:

  1. Either from binaries: run

For Unix systems

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.3.0~beta2"

or from PowerShell for Windows systems

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.3.0~beta2"

or download manually from the Github "Releases" page to your PATH.

  1. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Happy hacking!

Feedback on this post is welcome on Discuss!

We're happy to announce the first beta release of opam 2.3.0. Compared to the previous 2.3.0~alpha1 release, you can view the full list of changes in the release note.

This version is a beta, so we invite users to test it to spot previously unnoticed bugs as we head towards the stable release.

Changes

  • Fix an opam 2.1 regression where the initial pin of a local VCS directory would store untracked and ignored files. Those files would usually be cleaned before building the package; however, Git submodules would not be cleaned and would cause issues when paired with the new behaviour added in 2.3.0~alpha1, which makes an opam error when Git submodules fail to update (it was previously a warning). (#5809)

  • Fix a regression which would make opam crash on platforms where getconf LONG_BIT is not available (e.g., OpenBSD). (#6215)

  • Fix the installed packages internal cache, which was storing the wrong version of the opam file after a build failure. This could be triggered easily for users with custom repositories with non-populated extra-files. (#6213)

  • Fix a regression in lint W59 with local URLs that are not archives. (#6218)

  • Fix the compilation of opam on Windows with OCaml >= 5.0 (again)

  • Several improvements to the prebuilt release binaries were made:

    • The Linux binaries are now built on Alpine 3.20
    • The FreeBSD binary is now built on FreeBSD 14.1
    • The OpenBSD binary is now built on OpenBSD 7.6 and loses support for OpenBSD 7.5 and older
    • A Linux/riscv64 binary is now available

API changes are denoted in the release note linked above. This release also includes a couple of PRs improving and extending the tests.

Try It!

The upgrade instructions are unchanged:

  1. Either from binaries: run

For Unix systems

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.3.0~beta1"

or from PowerShell for Windows systems

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.3.0~beta1"

or download manually from the GitHub "Releases" page to your PATH.

  1. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Happy hacking!

Feedback on this post is welcomed on Discuss!

As mentioned in our talk at the OCaml Workshop 2024, we decided to switch to a time-based release cycle (every 6 months), starting with opam 2.3.

As promised, we are happy to announce the first alpha release of opam 2.3.0. You can view the full list of changes in the release note.

This version is an alpha, we invite users to test it to spot previously unnoticed bugs as we head towards the stable release.

Major breaking change

When loading a repository, opam now ignores files in packages' files/ directories which aren't listed in the extra-files field of the opam file. This was done to simplify the opam specification where we hope the opam file to be the only thing that you have to look at when reading a package specification. The optionality of the extra-files: field goes against that principle. This change also reduces the surface area for potential file corruption as it ensures that extra-files are checked against their checksums.

This is a breaking change and means that if you are using the files/ directory without the extra-files: field, you need to make sure that all files in that directory are listed in the extra-files field. Once done, the resulting opam file is backward-compatible and you don't need to worry about anything else.

If you have an opam repository, you should make sure all files are listed so every packages continues to work without any issue, which can be done automatically using the opam admin update-extrafiles command.

Major changes

  • Packages requiring an unsupported version of opam are now marked unavailable, instead of causing a repository error. This means an opam repository can now allow smoother upgrade in the future where some packages can require a newer version of opam without having to fork the repository to upgrade every package to that version as was done for the upgrade from opam 1.2 to 2.0

  • Add a new opam list --latests-only option to list only the latest versions of packages. Note that this option is respects the order options were given on the command line. For example: --available --latests-only will first list all the available packages, then choose only the latest packages in that set; while --latests-only --available will first list all the latest packages, then only show the ones that are available in that set

  • Fix and improve opam install --check, which now checks if the whole dependency tree of the package is installed instead of only the root dependencies

  • Add a new --verbose-on option to enable verbose output for specified package names. Thanks to @desumn for this contribution

  • Add a new opam switch import --deps-only option to install only the dependencies of the root packages listed in the opam switch export file

  • opam switch list-available will now not display compilers flagged with avoid-version/deprecated unless --all is given, meaning that the "trunk" build of OCaml no longer appears to be the latest version

  • opam switch create --repos now accepts git URLs suffixed with .git instead of requiring the git+https:// protocol prefix. This is consistant with other commands such as opam repository add. Thanks to @Keryan-dev for this contribution

  • opam switch set-invariant now displays the switch invariant using the same syntax as the --invariant flag

  • The builtin-0install solver was improved and should now be capable of being your default solver instead of builtin-mccs+glpk. It was previously mostly only suited for automated tasks such as Continuous Integration. If you wish to give it a try, simply call opam option solver=builtin-0install

  • Most of the unhelpful conflict messages were fixed

  • Fix the value of the arch variable when the current OS is 32bit on a 64bit machine (e.g. Raspberry Pi OS)

  • opam now fails when git submodules fail to update instead of ignoring the error and just showing a warning

  • opam's libraries now compile with OCaml >= 5.0 on Windows

Various performance and other improvements were made and bugs were fixed. API changes are denoted in the release note linked above. This release also includes a handful of PRs improving the documentation and more two dozen PRs improving and extending the tests.

Try it!

The upgrade instructions are unchanged:

  1. Either from binaries: run

For Unix systems

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.3.0~alpha1"

or from PowerShell for Windows systems

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) } -Version 2.3.0~alpha1"

or download manually from the Github "Releases" page to your PATH.

  1. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Happy hacking!

opam 2.2.1

Feedback on this post is welcomed on Discuss!

We are pleased to announce the release of opam 2.2.1.

We've fixed a couple of regressions and would like to encourage users of opam 2.2 to upgrade.

Changes

The three main changes are:

  • Fixe a regression in opam install --deps-only where the direct dependencies were not set as root packages (spotted in the wild by @rjbou and also reported on Discuss)
  • Fix a regression when fetching Git packages where the resulting Git repository could lead to unexpected outputs of Git commands, by disabling shallow clone by default except when fetching opam repositories (#6145)
  • Mitigate curl/curl#13845 by falling back from --write-out to --fail if exit code 43 is returned by Curl. In particular, this fixes opam init when run from cmd/PowerShell on Windows 11 23H2 (#6120)

A couple more improvements and additions to the testsuite were made. You can view the full list of changes in the release note.

Try it!

The upgrade instructions are unchanged:

  1. Either from binaries: run

For Unix systems

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.1"

or from PowerShell for Windows systems

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) }"

(or via winget upgrade OCaml.opam) or download manually from the Github "Releases" page to your PATH.

  1. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Happy hacking!

opam 2.2.0

Feedback on this post is welcomed on Discuss!

We are very pleased to announce the release of opam 2.2.0, and encourage all users to upgrade. Please read on for installation and upgrade instructions.

Try it!

In case you plan a possible rollback, you may want to first backup your ~/.opam or $env:LOCALAPPDATA\opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

For Unix systems

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.0"

or from PowerShell for Windows systems

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) }"

or download manually from the Github "Releases" page to your PATH.

  1. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Changes

Major change: Windows support

After 8 years' effort, opam and opam-repository now have official native Windows support! A big thank you is due to Andreas Hauptmann (@fdopen), whose WODI and OCaml for Windows projects were for many years the principal downstream way to obtain OCaml on Windows, Jun Furuse (@camlspotter) whose initial experimentation with OPAM from Cygwin formed the basis of opam-repository-mingw, and, most recently, Jonah Beckford (@jonahbeckford) whose DkML distribution kept - and keeps - a full development experience for OCaml available on Windows.

OCaml when used on native Windows requires certain tools from the Unix world which are provided by either Cygwin or MSYS2. We have engineered opam init so that it is possible for a user not to need to worry about this, with opam managing the Unix world, and the user being able to use OCaml from either the Command Prompt or PowerShell. However, for the Unix user coming over to Windows to test their software, it is also possible to have your own Cygwin/MSYS2 installation and use native Windows opam from that. Please see the previous blog post for more information.

There are two "ports" of OCaml on native Windows, referred to by the name of provider of the C compiler. The mingw-w64 port is GCC-based. opam's external dependency (depext) system works for this port (including providing GCC itself), and many packages are already well-supported in opam-repository, thanks to the previous efforts in opam-repository-mingw. The MSVC port is Visual Studio-based. At present, there is less support in this ecosystem for external dependencies, though this is something we expect to work on both in opam-repository and in subsequent opam releases. In particular, it is necessary to install Visual Studio or Visual Studio BuildTools separately, but opam will then automatically find and use the C compiler from Visual Studio.

Major change: opam tree / opam why

opam tree is a new command showing packages and their dependencies with a tree view. It is very helpful to determine which packages bring which dependencies in your installed switch.

$ opam tree cppo
cppo.1.6.9
├── base-unix.base
├── dune.3.8.2 (>= 1.10)
│   ├── base-threads.base
│   ├── base-unix.base [*]
│   └── ocaml.4.14.1 (>= 4.08)
│       ├── ocaml-base-compiler.4.14.1 (>= 4.14.1~ & < 4.14.2~)
│       └── ocaml-config.2 (>= 2)
│           └── ocaml-base-compiler.4.14.1 (>= 4.12.0~) [*]
└── ocaml.4.14.1 (>= 4.02.3) [*]

Reverse-dependencies can also be displayed using the new opam why command. This is useful to examine how dependency versions get constrained.

$ opam why cmdliner
cmdliner.1.2.0
├── (>= 1.1.0) b0.0.0.5
│   └── (= 0.0.5) odig.0.0.9
├── (>= 1.1.0) ocp-browser.1.3.4
├── (>= 1.0.0) ocp-indent.1.8.1
│   └── (>= 1.4.2) ocp-index.1.3.4
│       └── (= version) ocp-browser.1.3.4 [*]
├── (>= 1.1.0) ocp-index.1.3.4 [*]
├── (>= 1.1.0) odig.0.0.9 [*]
├── (>= 1.0.0) odoc.2.2.0
│   └── (>= 2.0.0) odig.0.0.9 [*]
├── (>= 1.1.0) opam-client.2.2.0~alpha
│   ├── (= version) opam.2.2.0~alpha
│   └── (= version) opam-devel.2.2.0~alpha
├── (>= 1.1.0) opam-devel.2.2.0~alpha [*]
├── (>= 0.9.8) opam-installer.2.2.0~alpha
└── user-setup.0.7

Special thanks to @cannorin for contributing this feature.

Major change: with-dev-setup

There is now a way for a project maintainer to share their project development tools: the with-dev-setup dependency flag. It is used in the same way as with-doc and with-test: by adding a {with-dev-setup} filter after a dependency. It will be ignored when installing normally, but it's pulled in when the package is explicitly installed with the --with-dev-setup flag specified on the command line.

For example

opam-version: "2.0"
depends: [
  "ocaml"
  "ocp-indent" {with-dev-setup}
]
build: [make]
install: [make "install"]
post-messages:
[ "Thanks for installing the package"
  "as well as its development setup. It will help with your future contributions" {with-dev-setup} ]

Major change: opam pin --recursive

When pinning a package using opam pin, opam looks for opam files in the root directory only. With recursive pinning, you can now instruct opam to look for .opam files in subdirectories as well, while maintaining the correct relationship between the .opam files and the package root for versioning and build purposes.

Recursive pinning is enabled by the following options to opam pin and opam install:

  • With --recursive, opam will look for .opam files recursively in all subdirectories.
  • With --subpath <path>, opam will only look for .opam files in the subdirectory <path>.

The two options can be combined: for instance, if your opam packages are stored as a deep hierarchy in the mylib subdirectory of your project you can try opam pin . --recursive --subpath mylib.

These options are useful when dealing with a large monorepo-type repository with many opam libraries spread about.

New Options

  • opam switch -, inspired by git switch -, makes opam switch back to the previously selected global switch.

  • opam pin --current fixes a package to its current state (disabling pending reinstallations or removals from the repository). The installed package will be pinned to its current installed state, i.e. the pinned opam file is the one installed.

  • opam pin remove --all removes all the pinned packages from a switch.

  • opam exec --no-switch removes the opam environment when running a command. It is useful when you want to launch a command without opam environment changes.

  • opam clean --untracked removes untracked files interactively remaining from previous packages removal.

  • opam admin add-constraint <cst> --packages pkg1,pkg2,pkg3 applies the given constraint to a given set of packages

  • opam list --base has been renamed into --invariant, reflecting the fact that since opam 2.1 the "base" packages of a switch are instead expressed using a switch invariant.

  • opam install --formula <formula> installs a formula instead of a list of packages. This can be useful if you would like to install one package or another one. For example opam install --formula '"extlib" |"extlib-compat"' will install either extlib or extlib-compat depending on what's best for the current switch.

Miscellaneous changes

  • The UI now displays a status when extracting an archive or reloading a repository
  • Overhauled the implementation of opam env, fixing many corner cases for environment updates and making the reverting of package environment variables precise. As a result, using setenv in an opam file no longer triggers a lint warning.
  • Fix parsing pre-opam 2.1.4 switch import files containing extra-files
  • Add a new sys-ocaml-system default global eval variable
  • Hijack the "%{var?string-if-true:string-if-false-or-undefined}%" syntax to support extending the variables of packages with + in their name (conf-c++ and conf-g++ already exist) using "%{?pgkname:var:}%"
  • Fix issues when using fish as shell
  • Sandbox: Mark the user temporary directory (as returned by getconf DARWIN_USER_TEMP_DIR) as writable when TMPDIR is not defined on macOS
  • Add Warning 69: Warn for new syntax when package name in variable in string interpolation contains several '+' (this is related to the "hijack" item above)
  • Add support for Wolfi OS, treating it like Alpine family as it also uses apk
  • Sandbox: /tmp is now writable again, restoring POSIX compliance
  • Add a new opam admin: new add-extrafiles command to add/check/update the extra-files: field according to the files present in the files/ directory
  • Add a new opam lint -W @1..9 syntax to allow marking a set of warnings as errors
  • Fix bugs in the handling of the OPAMCURL, OPAMFETCH and OPAMVERBOSE environment variables
  • Fix bugs in the handling of the --assume-built argument
  • Software Heritage fallbacks is now supported, but is disabled-by-default for now. For more information you can read one of our previous blog post

And many other general and performance improvements were made and bugs were fixed. You can take a look to previous blog posts. API changes and a more detailed description of the changes are listed in:

This release also includes PRs improving the documentation and improving and extending the tests.

Please report any issues to the bug-tracker.

We hope you will enjoy the new features of opam 2.2! 📯

Feedback on this post is welcomed on Discuss!

We are very excited to announce the first (and hopefully only) release candidate for opam 2.2.0.

We've squashed a few more bugs and we consider this to be ready for the final release. You can view the full list of changes in the release note.

We invite users to test it one final time just in case there are any previously unnoticed bugs!

Changes

  • Fix opam upgrade wanting to keep rebuilding the compiler (as now it contains an x-env-path-rewrite field)
  • Provide defaults so opam init -y no longer asks questions on Windows
  • Fix OpamConsole.menu when there are more than 9 options (can happen on Windows)

A couple more improvements were made and bugs were fixed. The single API change is also denoted in the release note. This release also includes PRs extending the tests.

Try it!

In case you plan a possible rollback, you may want to first backup your ~/.opam or $env:LOCALAPPDATA\opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

For Unix systems

bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.0~rc1"

or from PowerShell for Windows systems

Invoke-Expression "& { $(Invoke-RestMethod https://opam.ocaml.org/install.ps1) }"

or download manually from the Github "Releases" page to your PATH.

  1. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Thanks for trying this new release out, and we hope you will enjoy the new features of opam 2.2!

Feedback on this post is welcomed on Discuss!

We are very pleased to announce the third and final beta release of opam 2.2.0.

We've done our best to polish everything and squash as many bugs as possible in order to be ready for the final release. You can view the full list of changes in the release note.

This version is a beta, we invite users to test it to spot previously unnoticed bugs as we near the stable release.

Changes

  • Greatly enhance the opam init user experience on Windows, and the number of recognised configurations
  • New option opam init --cygwin-extra-packages=CYGWIN_PKGS --cygwin-internal-install, to specify additional packages for the internal Cygwin installation
  • Redirect the opam root to C:\opamroot\opam-xxx when the opam root contains spaces on Windows
  • Out-of-the-box UTF-8 paged --help on Windows
  • Fix a performance regression when calling opam install --deps-only on an already installed package
  • Fix several edge cases related to environment reverting
  • Fixed some issues that could appear when upgrading from previous versions of opam
  • Fix various issues with opam tree --with-test
  • Fix parsing opam 2.1 switch import files containing extra-files
  • Fix download URLs containing invalid characters on Windows
  • Fix some failure cases when extracting tarballs which contain symlinks on Windows

Various other general and performance improvements were made and bugs were fixed. API changes are denoted in the release note. This release also includes PRs improving the documentation and improving and extending the tests.

Try it on Windows!

BEWARE: the command shown below is experimental, use caution and please do report any issues that you are experiencing. If you prefer to not use our experimental script, feel free to get the Windows binary directly from the Release Page and put it in your directory of choice instead.

Now that the Windows support was merged in opam-repository, testing is as simple as calling the following command from a PowerShell terminal:

Invoke-Expression "& { $(Invoke-RestMethod https://raw.githubusercontent.com/kit-ty-kate/opam/windows-installer/shell/install.ps1) }"

opening a new terminal, and a simple opam init will work out-of-the-box.

Try it on other platforms!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.0~beta3"
    

    or download manually from the Github "Releases" page to your PATH.

  2. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Thanks for trying this new release out, and we hope you will enjoy the new features!

opam 2.1.5

Feedback on this post is welcomed on Discuss!

We are pleased to announce the patch release of opam 2.1.6.

This opam release consists of backported bug fixes and improvements:

  • Changes necessary for opam-repository (see ocaml/opam-repository#23789)
    • Warn if GNU patch is not detected when a patch is applied (#5893)
    • Use gpatch by default instead of patch on NetBSD and DragonFlyBSD (#5893)
    • Use gpatch if it exists and is detected as GNU patch when patch is not GNU patch (#5893)
  • Better recognize depexts on Gentoo, NetBSD, OpenBSD (#5065)
  • Upgrade the vendored dune to 3.14.0 (#5869)
  • Fix debug logs showing up regardless of verbosity on macOS 12.7.1 / 13.6.3 / 14.2 and FreeBSD (#5769)

Opam installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.6"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

See full changelog
  • Changes necessary for opam repository
  • Warn if GNU patch is not detected when a patch is applied [#5893 @kit-ty-kate]
  • Use gpatch by default instead of patch on NetBSD and DragonFlyBSD [#5893 @kit-ty-kate]
  • Use gpatch if it exists and is detected as GNU patch when patch is not GNU patch [#5893 @kit-ty-kate]
  • Better recognize depexts on Gentoo, NetBSD, OpenBSD [#5065 @mndrix]
  • Upgrade the vendored dune to 3.14.0 [#5869 @kit-ty-kate]
  • Vendor mccs.1.1+17 [#5769 @kit-ty-kate]
  • Require mccs >= 1.1+17: Fix debug logs showing up regardless of verbosity on macOS 12.7.1 / 13.6.3 / 14.2 and FreeBSD [#5769 @kit-ty-kate]
  • API Changes:
  • OpamSystem.patch now displays a warning when GNU patch is not detected and looks for both patch and gpatch as a backup option depending on the OS [#5893 @kit-ty-kate]

Feedback on this post is welcomed on Discuss!

We are indescribably thrilled to announce the second beta release of opam 2.2.0.

It contains everything required to be able to make opam-repository compatible with Windows, as well as a whole bunch of fixes. You can view the full list of changes in the release note.

We'll post another blog post very soon with more directions on how to test opam on Windows with this release.

This version is a beta, we invite users to test it to spot previously unnoticed bugs as we head towards the stable release.

Changes

Windows support

This beta introduces a handful of changes necessary to be able to make the default opam-repository support Windows out of the box:

  • Add a new sys-ocaml-system init default global eval variable
  • Hijack the "%{var?string-if-true:string-if-false-or-undefined}%" syntax to support extending the variables of packages with + in their name (conf-c++ and conf-g++ already exist) using "%{?pgkname:var:}%"
  • Add winsymlinks:native to the CYGWIN environment variable when installing a package on Windows. In particular, this provides a workaround when extracting ocamlbuild's sources.
  • Internal Cygwin installation's bin directory is placed as far down PATH as is necessary not to shadow bash, tar, sort or git
  • Disable ACL in Cygwin internal install to avoid permission mismatch errors

We expect to be able to show the proposed changed to opam-repository very soon to take advantage of all these changes.

opam-repository scalability

The current draft resolution resulting from the discussion in ocaml/opam-repository#23789 about the scalability of opam-repository includes the removal of some packages. However currently, opam uses the patch system command to apply changes from a repository. The behaviour of that command is thus very important and it is a known behaviour for the macOS and BSDs patch command to not be able to delete files which leads to failures and inconsistencies for opam. Package managers on those platforms installing opam already make opam depend on GNU patch, however a certain number of people do not install opam via a system package manager (e.g. our own install script!) and end up using their system version of patch. This is in particular a problem on macOS as the name of the GNU patch command is not gpatch like on BSDs but simply patch when installed via Homebrew.

This issue is surprisingly tricky to fix, and after many trials and errors, we've decided to:

  • Warn if GNU patch is not detected when a patch is applied
  • Use gpatch by default instead of patch on NetBSD and DragonFlyBSD
  • Use gpatch if it exists and is detected as GNU patch when patch is not GNU patch

These changes will make their way to the upcoming opam 2.1.6, in a few weeks.

Other noteworthy changes

  • Recommend enabling Developer Mode on Windows. This allows the creation of symlinks without requiring elevation. Longer-term, the aim is that we should never require Developer Mode, but at the moment more things work with it than without it!
  • Mark the internal Cygwin installation as recommended. Please don't try to maintain your own Cygwin install for use with opam unless you really know what you're doing!
  • Fix MSYS2 support. For 2.2.0, the focus has been on Cygwin, so configuring opam to use MSYS2 is quite manual. Please note that even if opam can use a MSYS2 installation, it is not yet officially supported and opam repository is not yet MSYS2 compatible. Use opam with MSYS2 only if you really really know what you're doing!
  • Fix issues when using fish
  • Improve the internal Cygwin installation during init on Windows
  • Unixify Windows paths in init shells scripts
  • Disable Software Heritage fallback by default as there currently no CI job in opam-repository to check validity of proposed swhid regarding release archive (neither publication tools support) and some concerns were raised regarding the degree of trust of the hashing method used by Software Heritage (sha1).
  • Make sure opam source --dev with git sources, clones the whole repository instead of using --depth=1
  • Sandbox: Mark the user temporary directory (as returned by getconf DARWIN_USER_TEMP_DIR) as writable when TMPDIR is not defined on macOS
  • Add Warning 69: Warn for new syntax when package name in variable in string interpolation contains several '+' (this is related to the "hijack" item above)
  • Add support for Wolfi OS, treat it like Alpine family as it also uses apk
  • Upgrade the vendored dune package to 3.14.2 to allow to compile opam when the environment contains unicode characters on Windows (in particular, this means opam now works if your username contains accented characters)
  • Upgrade other vendored packages (cmdliner 1.2.0, re 1.11.0, ocamlgraph 2.1.0, opam-file-format 2.1.6)

Various other general and performance improvements were made and bugs were fixed. API changes are denoted in the release note. This release also includes PRs improving the documentation and improving and extending the tests.

Windows Support

As we've said above we're writing a separate blog post to present how to test this new release of opam on Windows.

Stay tuned!

Try it!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.0~beta2"
    

    or download manually from the Github "Releases" page to your PATH.

  2. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Thanks for trying this new release out, and we hope you will enjoy the new features!

Feedback on this post is welcomed on Discuss!

We are happy to announce the first beta release of opam 2.2.0. It contains some fixes and a new feature for Windows. You can view the full list in the release note.

This version is a beta, we invite users to test it to spot previously unnoticed bugs as we head towards the stable release.

Major change: Check and advertise to use Git for Windows

Opam 2.2 is based on a Cygwin installation (previously installed, or managed internally by opam). Cygwin's Git has three known usability issues when used outside a Cygwin environment: it uses a different set of trusted certificate authorities, has its own Credential Manager and potentially uses a separate Git configuration. We therefore recommend using Git for Windows either installed manually or via winget.

At opam init, opam checks for available Git(s), and asks the user to choose one of the available, or to rerun opam init after installing another Git.

Other noteworthy changes

  • When compiling opam on Windows with MinGW, the resulting opam binary now contains libstdc++ instead of requiring the DLL to be distributed alongside it or present in the environment
  • Fix opam env containing carriage return on Cygwin - eval $(opam env) now works from a Cygwin bash terminal

Miscellaneous changes

  • Remove stray comments from pwsh and cmd opam env output
  • Add ./configure --enable-static to compile the opam binary statically on Linux
  • Fix debug logs showing up regardless of verbosity on macOS 12.7.1 / 13.6.3 / 14.2 and FreeBSD
  • Upgrade to, and require mccs >= 1.1+17
  • Fix opam tree options --dev and --no-switch

Various other improvements were made and bugs were fixed. API changes are denoted in the release note linked above. This release also includes PRs improving the documentation and improving and extending the tests.

Windows Support

The main opam-repository Windows compliance is still a work in progress, we recommend to use existing compatible repository (originally from @fdopen) and 32/64 bit mingw-w64 packages (by @dra27).

How to Test opam on Windows

If you're feeling adventurous, you can use the experimental pre-built binary for Windows available here.

Otherwise you can compile opam yourself using the following steps:

This beta requires a preexisting Cygwin installation for compiling opam.

  1. Check that you have all dependencies installed:
  • autoconf, make, patch, curl
  • MinGW compilers: mingw64-x86_64-gcc-g++, mingw64-i686-gcc-g++
  • Or if you want to use the MSVC port of OCaml, you'll need to install Visual Studio or Visual Studio Build Tools
  1. Download & extract the opam archive
  2. In the directory, launch make cold
  3. A coffee later, you now have an opam executable!
  4. Start your preferred Windows terminal (cmd or PowerShell), and initialise opam with the Windows sunset repository:
  • opam init git+https://github.com/ocaml-opam/opam-repository-mingw

From here, you can try to install the sunset repository packages. If you find any bugs, please submit an issue. It will help opam-repository maintainers to add Windows repository packages into the main repository.

Try it!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.0~beta1"
    

    or download manually from the Github "Releases" page to your PATH.

  2. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Thanks for trying this new release out, and we hope you will enjoy the new features!

Feedback on this post is welcomed on Discuss!

We are happy to announce the third alpha release of opam 2.2.0. It contains some fixes and a new feature for Windows. You can view the full list in the release note.

This version is an alpha, we invite users to test it to spot previously unnoticed bugs as we head towards the stable release.

Major change: Environment variables handling on Windows

opam files now support a new x-env-path-rewrite field which specifies rewriting rules for the environment variable updates defined in the setenv and build-env fields. This field allows greater control over the separator character used for PATH-like fields (i.e. ; vs :), conversion of slashes to backslashes, and even conversion from Windows native path format (C:\cygwin64\home\dra\.opam) to Cygwin format (/home/dra/.opam).

The rewriting rules allow opam directory-like variables (e.g. the %{lib}% directory of a switch) to be used in setenv and build-env fields in a portable way.

For example, given:

setenv: [
  [PKG_CONFIG_PATH += "%{lib}%/pkgconfig"]
  [PATH += "%{share}%/bin"]
]
x-env-path-rewrite: [
  [ PKG_CONFIG_PATH ":" "host" ]
  [ PATH (":" {os != "win32"} | ";" {os = "win32"}) ("target" {os != "win32"} | "target-quoted" {os = "win32"}) ]
]

the environment variable changes given by opam env on Windows would be:

PKG_CONFIG_PATH='/cygdrive/c/Users/DRA/AppData/Local/opam/default/lib/pkgconfig[:<rest-of-PKG_CONFIG_PATH, if given>]'
PATH='C:\Users\DRA\AppData\Local\opam\default\share\bin;C:\Users\DRA\AppData\Local\opam\default\bin;<rest-of-PATH>'

with the following interesting parts for Windows users:

  • PKG_CONFIG_PATH, which is consumed by a Cygwin-tool, has the directory given in Unix-like syntax, and opam's share variable was automatically converted
  • The correct separator is used for each (: for PKG_CONFIG_PATH, ; for PATH is used when adding entries)
  • In the PATH update, /bin was converted to \bin

Note that the specification for PATH is opam's default behaviour, so it's not actually necessary to have this formula for PATH in the x-env-path-rewrite field.

The full syntax is described in full in the manual.

Opam files carrying this new field are still compatible with the opam 2.0 syntax as it is an extension field, however its effect is only available with opam 2.2.0~alpha3 and above. If you want to make sure users of the package containing it have a compatible opam, you can use the available field to that end:

available: opam-version >= "2.2.0~alpha3"

or, if the change is Windows-specific:

available: opam-version >= "2.2.0~alpha3" | os != "win32"

Other noteworthy changes

  • Sandbox: /tmp is now writable again, restoring POSIX compliance
  • opam tree: opam tree package.version is now supported, displaying the dependency tree of a specific version of a package
  • opam tree: --recurse and --subpath are supported for directory arguments
  • opam admin: new add-extrafiles command to add/check/update the extra-files: field according to the files present in the files/ directory
  • opam lint: new syntax allow marking a set of warnings as errors e.g. -W @1..9
  • Releases: Pre-built binaries now include ppc64le and s390x

Miscellaneous changes

  • A handful of issues related to the compilation of opam on Windows were fixed
  • Bugs in the handling of the OPAMCURL, OPAMFETCH and OPAMVERBOSE environment variables were fixed
  • Bugs in the handling of the --assume-built argument were fixed
  • Sporadic crashes and segfaults during shell detection on Windows were fixed

Various other improvements were made and bugs were fixed. API changes are denoted in the release note linked above. This release also includes a handful of PRs improving the documentation and more than a dozen PRs improving and extending the tests.

Windows Support

The main opam-repository Windows compliance is still a work in progress, we recommend to use existing compatible repository (originally from @fdopen) and 32/64 bit mingw-w64 packages (by @dra27).

How to Test opam on Windows

If you're feeling adventurous, you can use the experimental pre-built binary for Windows available here. It should work but since it's our first public pre-built binary for Windows please use at your own risk.

Otherwise you can compile opam yourself using the following steps:

This alpha requires a preexisting Cygwin installation for compiling opam.

  1. Check that you have all dependencies installed:
  • autoconf, make, patch, curl
  • MinGW compilers: mingw64-x86_64-gcc-g++, mingw64-i686-gcc-g++
  • Or if you want to use the MSVC port of OCaml, you'll need to install Visual Studio or Visual Studio Build Tools
  1. Download & extract the opam archive
  2. In the directory:
  • if you are using MSVC: launch make cold
  • if you are using MinGW: make sure the path to the libc dlls are in your PATH and launch make cold. For instance: export PATH='C:\cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\bin':$PATH && make cold. Don’t forget to update PATH accordingly or place the opam binary in the same directory as the libc dlls if you want to move the resulting opam binary.
  • alternatively, if you're using MinGW: make cold CONFIGURE_ARGS=--with-private-runtime. If you change the location of the resulting opam binary, don't forget to copy Opam.Runtime.amd64 directory (or Opam.Runtime.i386) in the same directory.
  1. A coffee later, you now have an opam executable!
  2. Start your preferred Windows terminal (cmd or PowerShell), and initialise opam with the Windows sunset repository:
  • opam init git+https://github.com/ocaml-opam/opam-repository-mingw

From here, you can try to install the sunset repository packages. If you find any bugs, please submit an issue. It will help opam-repository maintainers to add Windows repository packages into the main repository.

Try it!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.0~alpha3"
    

    or download manually from the Github "Releases" page to your PATH.

  2. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Thanks for trying this new release out, and we hope you will enjoy the new features!

Feedback on this post is welcomed on Discuss!

We are happy to announce the second alpha release of opam 2.2.0. It contains some fixes and a new feature for Windows. You can view the full list in the release note.

This version is an alpha. so we invite users to test it for previously unnoticed bugs to head towards the stable release.

Windows Support

The first alpha came with native Windows compatibility. This second alpha comes with a simpler initialisation for Windows: we no longer rely on an already present Cygwin UNIX-like environment for Windows as a compatibility layer. During initialisation, opam now proposes to embed its own fully managed Cygwin install.

The main opam-repository Windows compliance is still a work in progress. We recommend using an existing, compatible repository (originally from @fdopen) and 32/64 bit mingw-w64 packages (by @dra27).

How to Test opam on Windows

This alpha requires a preexisting Cygwin installation for compiling opam.

  1. Check that you have all dependencies installed:
  • autoconf, make, patch, curl
  • MinGW compilers: mingw64-x86_64-gcc-g++, mingw64-i686-gcc-g++
  • If you want to use the MSVC port of OCaml, you'll need to install Visual Studio or Visual Studio Build Tools
  1. Download & extract the opam archive
  2. In the directory launch make cold
  3. A coffee later, you now have an opam executable!
  4. Start your preferred Windows terminal (cmd or PowerShell), and initialise opam with the Windows sunset repository:
  • opam init https://github.com/ocaml-opam/opam-repository-mingw

From here, you can try to install the sunset repository packages. If you find any bugs, please submit an issue. It will help opam-repository maintainers to add Windows repository packages into the main repository.

Hint: if you use the MinGW compiler, don't forget to add to your PATH the path to libc dlls (usually C:\cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\bin). You can also compile opam with make cold CONFIGURE_ARGS=--with-private-runtime, and if you change opam's location, don't forget to copy Opam.Runtime.amd64 (or Opam.Runtime.i386) with it.

Updates & Fixes

  • opam var now has a more informative error message in case of package variable
  • opam lint: update Error 29 on package variables on filters to check also conflicts: field
  • opam admin lint cleans output when called not from a terminal
  • configure throws an error if no complementary compiler is found on Windows

Try It!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries, run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.0~alpha2"
    

    or download manually from the Github "Releases" page to your PATH.

  2. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Feedback on this post is welcomed on Discuss!

We are happy to announce the alpha release of opam 2.2.0. It contains numerous fixes, enhancements, and updates; including much-improved Windows support, addressing one of the most important pain points identified by the OCaml community. You can view the full list of changes in the release note.

This alpha release is a significant milestone, brought together by Raja Boujbel after years of work from the opam dev team (Raja Boujbel, David Allsopp, Kate Deplaix, Louis Gesbert, in a united OCamlPro/Tarides collaboration) with the help of many community contributors. We also thank Jane Street for their continued sponsorship.

This version is an alpha, so we invite users to test it to spot previously unnoticed bugs and work towards a stable release.

Windows Support

Opam 2.2 comes with native Windows compatibility. You can now use opam from your preferred Windows terminal! We rely on the Cygwin UNIX-like environment for Windows as a compatibility layer, but it is possible for a package to generate native executables.

The main opam repository is not Windows compatible at the moment, but existing work on a compatible repository (originally from @fdopen) and 32/64 bit mingw-w64 packages (by @dra27) is in the process of being merged. Before the final release, we expect it to be possible to run opam init and use the main opam-repository for Windows.

How to Test opam on Windows

This alpha requires a preexisting Cygwin installation. Support for full management of a local Cygwin environment inside of opam (so that it's as transparent as possible) is queued already and should be available in 2.2.0~alpha2 as the default option.

  1. Check that you have all dependencies installed:
  • autoconf, make, patch, curl
  • MinGW compilers: mingw64-x86_64-gcc-g++, mingw64-i686-gcc-g++
  • Or if you want to use the MSVC port of OCaml, you'll need to install Visual Studio or Visual Studio Build Tools
  1. Download & extract the opam archive
  2. In the directory launch make cold
  3. A coffee later, you now have an opam executable!
  4. Start your preferred Windows terminal (cmd or PowerShell), and initialise opam with the Windows sunset repository:
  • opam init https://github.com/ocaml-opam/opam-repository-mingw

From here, you can try to install sunset repository packages. If any bug is found, please submit an issue. It will help opam repository maintainers to add Windows repository packages into the main repository.

Hint: if you use the MinGW compiler, don't forget to add to your PATH the path to libc dlls (usually C:\cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\bin). Or compile opam with make cold CONFIGURE_ARGS=--with-private-runtime, and if you change opam location, don't forget to copy Opam.Runtime.amd64 (or Opam.Runtime.i386) with it.

Recursive Pin

When installing or pinning a package using opam install or opam pin, opam normally only looks for opam files at the root of the installed package. With recursive pinning, you can now instruct opam to also look for .opam files in subdirectories, while maintaining the correct relationship between the .opam files and the package root for versioning and build purposes.

Recursive pinning is used with the following options to opam pin and opam install:

  • With --recursive, opam will look for .opam files recursively in all subdirectories.
  • With --subpath <path>, opam will only look for .opam files in the subdirectory <path>.

The two options can be combined: for instance, if your opam packages are stored as a deep hierarchy in the mylib subdirectory of your project, give opam pin . --recursive --subpath mylib a try!

You can use these options with opam pin, opam install, and opam remove.

$ tree .
.
├── ba
│   └── z
│       └── z.opam
├── bar
│   └── bar.opam
└── foo.opam

$ opam pin . --subpath ba/z --no-action
Package z does not exist, create as a NEW package? [y/n] y
z is now subpath-pinned to directory /ba/z in git+file:///tmp/recpin#master (version 0.1)

$ opam pin --recursive . --no-action
This will pin the following packages: foo, z, bar. Continue? [y/n] y
foo is now pinned to git+file:///tmp/recpin#master (version 0.1)
Package z does not exist, create as a NEW package? [y/n] y
z is now subpath-pinned to directory /ba/z in git+file:///tmp/recpin#master (version 0.1)
Package bar does not exist, create as a NEW package? [y/n] y
bar is now subpath-pinned to directory /bar in file:///tmp/recpin (version 0.1)

$ opam pin
bar.0.1  (uninstalled)  rsync  directory /bar in file:///tmp/recpin
foo.0.1  (uninstalled)  git    git+file:///tmp/recpin#master
z.0.1    (uninstalled)  git    directory /ba/z in git+file:///tmp/recpin#master

$ opam pin . --recursive --subpath ba/ --no-action
Package z does not exist, create as a NEW package? [y/n] y
z is now subpath-pinned to directory /ba/z in git+file:///tmp/recpin#master (version 0.1)

Tree View

opam tree shows packages and their dependencies with a tree view. It is very helpful to determine which packages bring which dependencies in your installed switch.

$ opam tree cppo
cppo.1.6.9
├── base-unix.base
├── dune.3.8.2 (>= 1.10)
│   ├── base-threads.base
│   ├── base-unix.base [*]
│   └── ocaml.4.14.1 (>= 4.08)
│       ├── ocaml-base-compiler.4.14.1 (>= 4.14.1~ & < 4.14.2~)
│       └── ocaml-config.2 (>= 2)
│           └── ocaml-base-compiler.4.14.1 (>= 4.12.0~) [*]
└── ocaml.4.14.1 (>= 4.02.3) [*]

It can also display a reverse-dependency tree (through opam why, which is an alias to opam tree --rev-deps). This is useful to examine how dependency versions get constrained.

$ opam why cmdliner
cmdliner.1.2.0
├── (>= 1.1.0) b0.0.0.5
│   └── (= 0.0.5) odig.0.0.9
├── (>= 1.1.0) ocp-browser.1.3.4
├── (>= 1.0.0) ocp-indent.1.8.1
│   └── (>= 1.4.2) ocp-index.1.3.4
│       └── (= version) ocp-browser.1.3.4 [*]
├── (>= 1.1.0) ocp-index.1.3.4 [*]
├── (>= 1.1.0) odig.0.0.9 [*]
├── (>= 1.0.0) odoc.2.2.0
│   └── (>= 2.0.0) odig.0.0.9 [*]
├── (>= 1.1.0) opam-client.2.2.0~alpha
│   ├── (= version) opam.2.2.0~alpha
│   └── (= version) opam-devel.2.2.0~alpha
├── (>= 1.1.0) opam-devel.2.2.0~alpha [*]
├── (>= 0.9.8) opam-installer.2.2.0~alpha
└── user-setup.0.7

Special thanks to @cannorin for contributing this feature.

Recommended Development Tools

There is now a way for a project maintainer to share their project development tools: the with-dev-setup dependency flag. It is used in the same way as with-doc and with-test: by adding a {with-dev-setup} filter after a dependency. It will be ignored when installing normally, but it's pulled in when the package is explicitely installed with the --with-dev-setup flag specified on the command line. The variable is also resolved in the post-messages: field to allow maintainers to share more informations about that setup.

This is typically useful for tools that are required for bootstrapping or regenerating artifacts.

For example

opam-version: "2.0"
depends: [
  "ocaml"
  "dune"
  "ocp-indent" {with-dev-setup}
]
build: [make]
install: [make "install"]
post-messages:
[ "Thanks for installing the package"
  "and its tool dependencies too, it will help for your futur PRs" {with-dev-setup} ]

Software Heritage Binding

Software Heritage is a project that aims to archive all software source code in existence. This is done by collecting source code with a loader that uploads software source code to the Software Heritage distributed infrastructure. From there, any project/version is available via the search webpage and via a unique identifier called the SWHID. Some OCaml source code is already archived, and the main opam and Coq repository packages are continuously uploaded.

Opam now integrates a fallback to Software Heritage archive retrieval, based on SWHID. If an SWHID URL is present in an opam file, the fallback can be activated.

To keep backwards compatibility of opam files, we added a specific Software Heritage URL syntax to the url.mirrors: field, which is used to specify mirrors of the main URL. Opam 2.2.+ understands this specific syntax as a Software Heritage fallback URL: https://swhid.opam.ocaml.org/<SWHID>.

url {
  src: "https://faili.ng/url.tar.gz"
  checksum: "sha512=e2146c1d7f53679fd22df66c9061b5ae4f8505b749513eedc67f3c304f297d92e54f5028f40fb5412d32c7d7db92592eacb183128d2b6b81d10ea716b7496eba"
  mirrors: [
    "https//failli.ng/mirror.tar.gz"
    "https://swhid.opam.ocaml.org/swh:1:dir:9f2be900491e1dabfc027848204ae01aa88fc71d"
  ]
}

To add a Software Heritage fallback URL to your package, use the swhid library. Specifically the Compute.directory_identifier_deep function:

  1. Download opam package archive
  2. Extract the archive
  3. Compute SWHID with Compute.directory_identifier_deep. You can use this oneliner in the directory:
ocaml -e '#use "topfind";; #require "digestif.ocaml";; #require "swhid";; Swhid_core.Object.pp Format.std_formatter (Result.get_ok (Swhid.Compute.directory_identifier_deep "."))'

Special thanks to @zapashcanon for collaborating on this feature.

Formula (Experimental)

It is now possible to leverage the full expressivity of package dependency formulas from the command line during switch creation and package operations.

It is possible to create a switch using a formula. For example, with ocaml-variant or ocaml-system, excluding ocaml-base-compiler:

opam switch create ocaml --formula '"ocaml-variants" {>= "4.14.1"} | "ocaml-system"'

This syntax is brought to install commands. For example, while installing a package, let's say genet, you can specify that you want to install either conf-mariadb & mariadb or conf-postgresql:

opam install genet --formula '["mysql" ("conf-mariadb" & "mariadb" | "conf-postgresql")]'

New Options

Here are several of new options (possibly scripts breaking changes are marked with ✘):

  • opam pin --current to fix a package to its current state (disabling pending reinstallations or removals from the repository). The installed package will be pinned with the opam file that is stored in opam internal state, the one that is currently installed.

  • opam pin remove --all to remove all the pinned packages from a switch.

  • opam pin remove pkg.version now removes the pins on pinned pkg.version.

  • opam exec --no-switch to remove opam environment from launched command.

$ export FOOVAR=env
$ opam show foo --field setenv
FOOVAR = "package"
$ opam exec  -- env | grep "OPAM_SWITCH\|FOO"
FOOVAR=package
OPAM_SWITCH_PREFIX=~/.opam/env
$ opam exec --no-switch -- env | grep "OPAM_SWITCH\|FOO"
FOOVAR=env
  • opam source --no-switch to allow downloading package sources without having an installed switch (instead of failing).

  • opam clean --untracked to remove untracked files interactively remaining from previous packages removal.

  • opam switch -, inspired from git switch -, that goes back to the previously selected global switch.

  • opam admin add-constraint <cst> --packages pkg1,pkg2,pkg3 to select a subset of packages to apply constraints.

  • ✘ Change --base into --invariant. opam switch compiler column now contains installed packages that verifies invariant formula, and empty synopsis shows switch invariant.

$ opam switch create inv --formula '["ocaml" {>= "4.14.1"} "dune"]'
$ opam switch invariant
["ocaml" {>= "4.14.1"} "dune"]
$ opam list --invariant
# Packages matching: invariant
# Name # Installed # Synopsis
dune   3.8.2       Fast, portable, and opinionated build system
ocaml  5.0.0       The OCaml compiler (virtual package)
$ opam switch list
#  switch   compiler                                            description
→  inv      ocaml-base-compiler.5.0.0,ocaml-options-vanilla.1   ocaml >= 4.14.1 & dune

Try It!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. From binaries: run
bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.2.0~alpha"

Or download manually from the Github "Releases" page to your PATH.

  1. From source, manually: see the instructions in the README.

Then run:

opam init --reinit -ni

Please report any issues to the bug-tracker.

Thanks for trying this new release out, and we're hoping you will enjoy the new features!

opam 2.1.5

Feedback on this post is welcomed on Discuss!

We are pleased to announce the patch release of opam 2.1.5.

This opam release consists of backported bug & security fixes:

  • Security issue: fix opam installing packages without checking their checksum when the local cache is corrupted in some case (#5538), you can find more information there.
  • Variables are now expanded in build-env (as for setenv) (#5352)
  • Correctly handle empty environment variable additions (#5350)
  • Skip empty environment variable additions (#5350)
  • Fix passing archive-mirrors field from init config file to config (#5315)
  • git, hg: Use the full SHA1 revision instead of just the 8 first characters (#5342)

Opam installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.5"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

See full changelog
  • [BUG] Variables are now expanded in build-env (as for setenv) [#5352 @dra27]
  • Correctly handle empty environment variable additions [#5350 @dra27]
  • Skip empty environment variable additions [#5350 @dra27]
  • [BUG] Fix passing archive-mirrors field from init config file to config [#5315 @hannesm]
  • git, hg: Use the full SHA1 revision instead of just the 8 first characters [#5342 @reynir]
  • [BUG] Fix opam installing packages without checking their checksum when the local cache is corrupted in some case [#5538 @kit-ty-kate]

opam 2.1.4

Feedback on this post is welcomed on Discuss!

We are pleased to announce the minor release of opam 2.1.4.

This opam release consists of backported fixes:

  • Make opam able to fully build with OCaml 5.0. dose3 >= 6.1 and base64 >= 3.1.0 are now required (#5357)
  • Fix a bug where opam would not output any explanation when a conflict arises when attempting to install a package (#5378)

Opam installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.4"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

See full changelog
  • Add support for OCaml 5.0. Dose3 >= 6.1 and base64 >= 3.1.0 are now required [#5357 @kit-ty-kate @dra27 - fix #5354]
  • [BUG] Fix all empty conflict explanation messages [#5378 @kit-ty-kate - partial fix #4373]

opam 2.1.3

Feedback on this post is welcomed on Discuss!

We are pleased to announce the minor release of opam 2.1.3.

This opam release consists of backported fixes:

  • Fix opam init and opam init --reinit when the jobs variable has been set in the opamrc or the current config. (#5056)
  • opam var no longer fails if no switch is set (#5025)
  • Setting a variable with option --switch <sw> fails instead of writing an invalid switch-config file (#5027)
  • Handle external dependencies when updating switch state pin status (all pins), instead as a post pin action (only when called with opam pin (#5046)
  • Remove windows double printing on commands and their output (#4940)
  • Stop Zypper from upgrading packages on updates on OpenSUSE (#4978)
  • Clearer error message if a command doesn't exist (#4112)
  • Actually allow multiple state caches to co-exist (#4554)
  • Fix some empty conflict explanations (#4373)
  • Fix an internal error on admin repository upgrade from OPAM 1.2 (#4965)

and improvements:

  • When inferring a 2.1+ switch invariant from 2.0 base packages, don't filter out pinned packages as that causes very wide invariants for pinned compiler packages (#4501)
  • Some optimisations to opam list --installable queries combined with other filters (#4311)
  • Improve performance of some opam list combinations (e.g. --available, --installable) (#4999)
  • Improve performance of opam list --conflicts-with when combined with other filters (#4999)
  • Improve performance of opam show by as much as 300% when the package to show is given explicitly or is unique (#4997)(#4172)
  • When a field is defined in switch and global scope, try to determine the scope also by checking switch selection (#5027)

You can also find API changes in the release note.


Opam installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.3"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

See full changelog
  • [BUG] Fix opam init and opam init --reinit when the jobs variable has been set in the opamrc or the current config. [#5056 @rjbou]
  • When inferring a 2.1+ switch invariant from 2.0 base packages, don't filter out pinned packages as that causes very wide invariants for pinned compiler packages [#5176 @dra27 - fix #4501]
  • [BUG] Fix an internal error on repository upgrade from OPAM 1.2 [#4965 @AltGr]
  • Some optimisations to opam list --installable queries combined with other filters [#4882 @AltGr - fix #4311]
  • Improve performance of some opam list combinations (e.g. --available, --installable) [#4999 @kit-ty-kate]
  • Improve performance of opam list --conflicts-with when combined with other filters [#4999 @kit-ty-kate]
  • Improve performance of opam show by as much as 300% when the package to show is given explicitly or is unique [#4998 @kit-ty-kate - fix #4997 and partially #4172]
  • [BUG] opam var no longer fails if no switch is set [#5027 @rjbou - fix #5025]
  • [BUG] Setting a variable with option --switch <sw> fails instead of writing an invalid switch-config file [#5027 @rjbou]
  • When a field is defined in switch and global scope, try to determine the scope also by checking switch selection [#5027 @rjbou]
  • [BUG] Handle external dependencies when updating switch state pin status (all pins), instead as a post pin action (only when called with opam pin [#5047 @rjbou - fix #5046]
  • [BUG] When reinstalling a package that has a dirty source, if uncommitted changes are the same than the ones stored in opam's cache, opam consider that it is up to date and nothing is updated [4879 @rjbou]
  • Stop Zypper from upgrading packages on updates on OpenSUSE [#4978 @kit-ty-kate]
  • Clearer error message if a command doesn't exist [#4971 @kit-ty-kat - fix #4112]
  • [BUG] Remove windows double printing on commands and their output [#4940 @rjbou]
  • Actually allow multiple state caches to co-exist [#4934 @dra27 - actually fixes #4554]
  • Update cold compiler to 4.13 to avoid issues with glibc 2.34 on Unix [#5017 @dra27]
  • Bump opam-file-format to 2.1.4 [#5117 @kit-ty-kate - fix #5116]
  • Fix some empty conflict explanations [#4982 @kit-ty-kate - partially fix #4373]
  • Port some tests from master [#4841 #4974 #4861 #4915 #4979 #5004 #5006 #5015 #5024 #5025 #5031 #5131 #5176 @AltGr @dra27 @kit-ty-kate]
  • Update test engine to allow for additional tests [#4913 #4966 #4979 #5004 #5009 #5024 #5097 @AltGr @kit-ty-kate @rjbou]
  • Update for git protocol deprecation on GitHub [#5097 @rjbou]
  • When building opam, do not fail if curl/wget is missing [#5223 #5233 @kit-ty-kate]

opam 2.1.2

We are pleased to announce the minor release of opam 2.1.2.

This opam release consists of backported fixes, including:

  • Fallback on dnf if yum does not exist on RHEL-based systems (#4825)
  • Use --no-depexts in CLI 2.0 mode. This further improves the use of opam 2.1 as a drop-in replacement for opam 2.0 in CI, for example with setup-ocaml in GitHub Actions. (#4908)

Opam installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.2"
    

    or download manually from the GitHub "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

See full changelog
  • Fallback on dnf if yum does not exist on RHEL-based systems [#4825 @kit-ty-kate]
  • Use --no-depexts in CLI 2.0 mode [#4908 @dra27]
  • bootstrap: update ocaml version (fixes the compilation of opam with mingw) [#4927 @kit-ty-kate]

opam 2.1.1

Feedback on this post is welcomed on Discuss!

We are pleased to announce the release of opam 2.1.1.

With opam 2.1.1, if you export OPAMCLI=2.0 into your environment then workflows expecting opam 2.0 should now behave even more equivalently.

opam 2.1.1 includes both the fixes in opam 2.0.10.

General fixes:

  • Restore support for switch creation with "positional" package arguments and --packages option for CLI version 2.0, e.g. OPAMCLI=2.0 opam switch create . 4.12.0+options --packages=ocaml-option-flambda. In opam 2.1 and later, this syntax remains an error (#4843)
  • Fix opam switch set-invariant: default repositories were loaded instead of the switch's repositories selection (#4869)
  • Run the sandbox check in a temporary directory (#4783)

Integrated depext support has a few updates:

  • Homebrew now has support for casks and full-names (#4800)
  • Archlinux now handles virtual package detection (#4833, partially addressing #4759)
  • Disable the detection of available packages on RHEL-based distributions. This fixes an issue on RHEL-based distributions where yum list used to detect available and installed packages would wait for user input without showing any output and/or fail in some cases (#4791)

And finally two regressions have been dealt with:

  • Regression: avoid calling Unix.environment on load (as a toplevel expression). This regression affected opam's libraries, rather than the binary itself (#4789)
  • Regression: handle empty environment variable updates (#4840)

A few issues with the compilation of opam from sources have been fixed as well (e.g. mingw-w64 with g++ 11.2 now works)


Opam installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.1"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

See full changelog
  • Fix typo in error message for opam var [#4786 @kit-ty-kate - fix #4785]
  • Run the sandbox check in the temporary directory [#4787 @dra27 - fix #4783]
  • OpamSystem: avoid calling Unix.environment at top level [#4789 @hannesm]
  • Homebrew: Add support for casks and full-names [#4801 @kit-ty-kate]
  • Fix the cold target in presence of an older OCaml compiler version on macOS [#4802 @kit-ty-kate - fix #4801]
  • Archlinux: handle virtual package detection [#4833 @rjbou - partial fix #4759]
  • Disable the detection of available packages on RHEL-based distributions. This fixes an issue on RHEL-based distributions where yum list used to detect available and installed packages would wait for user input without showing any output and/or fail in some cases [#4791 @kit-ty-kate - fixes #4790]
  • Handle empty environment variable updates - missed cherry-pick from 2.0 [#4840 @dra27]
  • Fix vendored build on mingw-w64 with g++ 11.2 [#4835 @dra27]
  • Put back support for switch creation with packages argument and --packages option with cli 2.0, and a specific error message for cli 2.1 [#4853 @rjbou - fix #4843]
  • Fix reverting environment additions to PATH-like variables when several dirs added at once [#4861 @dra27]
  • Fix dose3 download url since gforge is gone [#4870 @avsm]
  • Ensure setenv can use package variables defined during the build [#4841 @dra27]
  • Fix `set-invariant: default repos were loaded instead of switch repos [#4866 @rjbou]

opam 2.0.10

Feedback on this post is welcomed on Discuss!

We are pleased to announce the release of opam 2.0.10.

Two subtle fixes are included in opam 2.0.10. These actually affect the ocaml package. Both of these are Heisenbugs - investigating what's going wrong on your system may well have fixed them, they were both found on Windows!

$(opam env --revert) is the reverse of the more familiar $(opam env) but it's effectively called by opam whenever you change switch. It has been wrong since 2.0.0 for the case where several values are added to an environment variable in one setenv update. For example, if a package included a setenv field of the form [PATH += "dir1:dir2"], then this would not be reverted, but [[PATH += "dir1"] [PATH += "dir2"]] would be reverted. As it happens, this bug affects the ocaml package, but it was masked by another setenv update in the same package.

The other fix is also to do with setenv. It can be seen immediately after creating a switch but before any additional packages are installed, as this Dockerfile shows:

FROM ocaml/opam@sha256:244b948376767fe91e2cd5caca3b422b2f8d332f105ef2c8e14fcc9a20b66e25
RUN sudo apt-get install -y ocaml-nox
RUN opam --version
RUN opam switch create show-issue ocaml-system
RUN eval $(opam env) ; echo $CAML_LD_LIBRARY_PATH
RUN opam install conf-which
RUN eval $(opam env) ; echo $CAML_LD_LIBRARY_PATH

Immediately after switch creation, $CAML_LD_LIBRARY_PATH was set to /home/opam/.opam/show-issue/lib/stublibs:, rather than /home/opam/.opam/show-issue/lib/stublibs:/usr/local/lib/ocaml/4.08.1/stublibs:/usr/lib/ocaml/stublibs


Opam installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.0.10"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

See full changelog
  • Fix reverting environment additions to PATH-like variables when several dirs added at once [#4861 @dra27]
  • Ensure setenv can use package variables defined during the build [#4841 @dra27]

Feedback on this post is welcomed on Discuss!

We are happy to announce the release of opam 2.1.0.

Many new features made it in (see the pre-release changelogs or release notes for the details), but here are a few highlights.

What's New in opam 2.1?

  • Integration of system dependencies (formerly the opam-depext plugin), increasing their reliability as it integrates the solving step
  • Creation of lock files for reproducible installations (formerly the opam-lock plugin)
  • Switch invariants, replacing the "base packages" in opam 2.0 and allowing for easier compiler upgrades
  • Improved options configuration (see the new option and expanded var subcommands)
  • CLI versioning, allowing cleaner deprecations for opam now and also improvements to semantics in future without breaking backwards-compatibility
  • opam root readability by newer and older versions, even if the format changed
  • Performance improvements to opam-update, conflict messages, and many other areas

Seamless Integration of System Dependencies Handling (a.k.a. "depexts")

Opam has long included the ability to install system dependencies automatically via the depext plugin. This plugin has been promoted to a native feature of opam 2.1.0 onwards, giving the following benefits:

  • You no longer have to remember to run opam depext, as opam always checks depexts (there are options to disable this or automate it for CI use). Installation of an opam package in a CI system is now as easy as opam install ., without having to do the dance of opam pin add -n/depext/install. Just one command now for the common case!
  • The solver is only called once, which both saves time and also stabilises the behaviour of opam in cases where the solver result is not stable. It was possible to get one package solution for the opam depext stage and a different solution for the opam install stage, resulting in some depexts missing.
  • Opam now has full knowledge of depexts, which means that packages can be automatically selected based on whether a system package is already installed. For example, if you have neither MariaDB nor MySQL dev libraries installed, opam install mysql will offer to install conf-mysql and mysql, but if you have the MariaDB dev libraries installed, opam will offer to install conf-mariadb and mysql.

Hint: You can set OPAMCONFIRMLEVEL=unsafe-yes or --confirm-level=unsafe-yes to launch non interactive system package commands.

opam Lock Files and Reproducibility

When opam was first released, it had the mission of gathering together scattered OCaml source code to build a community repository. As time marches on, the size of the opam repository has grown tremendously to over 3000 unique packages with over 19500 unique versions. Opam looks at all these packages and is designed to solve for the best constraints for a given package, so your project can keep up with releases of your dependencies.

While this works well for libraries, we need a different strategy for projects that need to test and ship using a fixed set of dependencies. To satisfy this use case, opam 2.0.0 shipped with support for using project.opam.locked files. These are normal opam files but with exact versions of dependencies. The lock file can be used as simply as opam install . --locked to have a reproducible package installation.

With opam 2.1.0, the creation of lock files is also now integrated into the client:

  • opam lock will create a .locked file for your current switch and project, that you can check into the repository.
  • opam switch create . --locked can be used by users to reproduce your dependencies in a fresh switch.

This lets a project simultaneously keep up with the latest dependencies (without lock files) while providing a stricter set for projects that need it (with lock files).

Hint: You can export the full configuration of a switch with opam switch export new options, --full to have all packages metadata included, and --freeze to freeze all VCS to their current commit.

Switch Invariants

In opam 2.0, when a switch is created the packages selected are put into the “base” of the switch. These packages are not normally considered for upgrade, in order to ease pressure on opam's solver. This was a much bigger concern early on in opam 2.0's development, but it is less of a problem with the default mccs solver.

However, it's a problem for system compilers. opam would detect that your system compiler version had changed, but it's unable to upgrade the ocaml-system package, unless you went through a slightly convoluted process with --unlock-base.

In opam 2.1, base packages have been replaced by switch invariants. The switch invariant is a package formula which must be satisfied on every upgrade and install. All existing switches' base packages could just be expressed as package1 & package2 & package3, etc., but opam 2.1 recognises many existing patterns and simplifies them. Therefore, in most cases, the invariant will be "ocaml-base-compiler" {= "4.11.1"}, etc. This means that opam switch create my_switch ocaml-system now creates a switch invariant of "ocaml-system" rather than a specific version of the ocaml-system package. If your system OCaml package is updated, opam upgrade will seamlessly switch to the new package.

This also allows you to have switches which automatically install new point releases of OCaml. For example:

opam switch create ocaml-4.11 --formula='"ocaml-base-compiler" {>= "4.11.0" & < "4.12.0~"}' --repos=old=git+https://github.com/ocaml/opam-repository#a11299d81591
opam install utop

Creates a switch with OCaml 4.11.0 (the --repos= was just to select a version of opam-repository from before 4.11.1 was released). Now issue:

opam repo set-url old git+https://github.com/ocaml/opam-repository
opam upgrade

Opam 2.1 will automatically offer to upgrade OCaml 4.11.1 along with a rebuild of the switch. There's not yet a clean CLI for specifying the formula, but we intend to iterate further on this with future opam releases so that there is an easier way of saying “install OCaml 4.11.x."

Hint: You can set up a default invariant that will apply for all new switches, via a specific opamrc. The default one is ocaml >= 4.05.0

Configuring opam From the Command Line

Configuring opam is not a simple task: you need to use an opamrc at init stage, hack global/switch config file, or use opam config var for additional variables. To ease that step, and permit a more consistent opam config tweaking, a new command was added : opam option.

For example:

  • opam option download-jobs gives the global download-jobs value (as it exists only in global configuration)
  • opam option jobs=6 --global will set the number of parallel build jobs opam is allowed to run (along with the associated jobs variable)
  • opam option depext-run-commands=false disables the use of sudo for handling system dependencies. It will be replaced by a prompt to run the installation commands
  • opam option depext-bypass=m4 --global bypasses m4 system package check globally, while opam option depext-bypass=m4 --switch myswitch will only bypass it in the selected switch.

The command opam var is extended with the same format, acting on switch and global variables.

Hint: to revert your changes use opam option <field>=, it will take its default value.

CLI Versioning

A new --cli switch was added to the first beta release, but it's only now that it's being widely used. Opam is a complex enough system that sometimes bug fixes need to change the semantics of some commands. For example:

  • opam show --file needed to change behaviour
  • The addition of new controls for setting global variables means that the opam config was becoming cluttered and some things want to move to opam var
  • opam switch install 4.11.1 still works in opam 2.0, but it's really an opam 1.2.2 syntax.

Changing the CLI is exceptionally painful since it can break scripts and tools which themselves need to drive opam. CLI versioning is our attempt to solve this. The feature is inspired by the (lang dune ...) stanza in dune-project files, which has allowed the Dune project to rename variables and alter semantics without requiring every single package using Dune to upgrade their dune files on each release.

Now you can specify which version of opam you expected the command to be run against. In day-to-day use of opam at the terminal, you wouldn't specify it, so you'll get the latest version of the CLI. For example: opam var --global is the same as opam var --cli=2.1 --global. However, if you issue opam var --cli=2.0 --global, you will have told it that --global was added in 2.1, so it's not available to you. You can see similar things with the renaming of opam upgrade --unlock-base to opam upgrade --update-invariant.

The intention is that --cli should be used in scripts, user guides (e.g., blog posts), and in software which calls opam. The only decision you have to take is the oldest version of opam which you need to support. If your script is using a new opam 2.1 feature (for example, opam switch create --formula=) then you simply don't support opam 2.0. If you need to support opam 2.0, then you can't use --formula and should use --packages instead. Opam 2.0 does not have the --cli option, so for opam 2.0 instead of --cli=2.0 you should set the environment variable OPAMCLI to 2.0. As with all opam command line switches, OPAMCLI is simply the equivalent of --cli, which opam 2.1 will pick-up but opam 2.0 will quietly ignore (and, as with other options, the command line takes precedence over the environment).

Note that opam 2.1 sets OPAMCLI=2.0 when building packages, so on the rare instances where you need to use the opam command in a package build: command (or in your build system), you must specify --cli=2.1 if you're using new features.

Since 2.1.0~rc2, CLI versioning applies to opam environment variables. The previous behaviour was to ignore unknown or wrongly set environment variables. Now you will have a warning to let you know that the environment variable won't be handled by this version of opam.

To ensure not breaking compatibility of some widely used deprecated options, a default CLI is introduced: when no CLI is specified, those deprecated options are accepted. It concerns opam exec and opam var subcommands.

There's even more detail on this feature in our wiki. We're hoping that this feature will make it much easier in future releases for opam to make required changes and improvements to the CLI without breaking existing setups and tools.

Note: For opam libraries users, since 2.1 environment variable are no more loaded by the libraries, only by opam client. You need to load them explicitly.

opam root Portability

opam root format changes during opam's life cycle. New fields are added or removed, and new files are added. An older opam version sometimes can no longer read an upgraded or newly created opam root. opam root format has been updated to allow new versions of opam to indicate that the root may still be read by older versions of the opam libraries. A plugin compiled against the 2.0.9 opam libraries will therefore be able to read information about an opam 2.1 root (plugins and tools compiled against 2.0.8 are unable to load opam 2.1.0 roots). It is a read-only best effort access, any attempt to modify the opam root fails.

Hint: for opam libraries users, you can safely load states with OpamStateConfig load functions.

Tremendous thanks to all involved people, who've developed, tested & retested, helped with issue reports, comments, feedback, etc...

Try It!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.0"
    

    or download manually from the GitHub "Releases" page to your PATH.

  2. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni
See full changelog
  • Set DEBIAN_FRONTEND=noninteractive for unsafe-yes confirmation level [#4735 @dra27 - partially fix #4731]
  • Fix 2.1~alpha2 to 2.1 format upgrade with reinit [#4750 #4756 @rjbou - fix #4748]
  • Fix bypass-check handling on reinit [#4750 @rjbou]
  • fish: fix deprecated redirection syntax ^ [#4736 @vzaliva]
  • Bump src_exts and fix build compat with Dune 2.9.0 [#4754 @dra27]
  • Fix depext alpine tagged repositories handling [#4758 @rjbou]

Feedback on this post is welcomed on Discuss!

We are pleased to announce the minor release of opam 2.0.9.

This new version contains some back-ported fixes.

New features

  • Back-ported ability to load upgraded roots read-only; allows applications compiled with opam-state 2.0.9 to load a root which has been upgraded to opam 2.1 [#4636]
  • macOS sandbox now supports OPAM_USER_PATH_RO for adding a custom read-only directory to the sandbox [#4589, #4609]
  • OPAMROOT and OPAMSWITCH now reflect the --root and --switch parameters in the package build [#4668]
  • When built with opam-file-format 2.1.3+, opam-format 2.0.x displays better errors for newer opam files [#4394]

Bug fixes

  • Linux sandbox now mounts host $TMPDIR read-only, then sets the sandbox $TMPDIR to a new separate tmpfs. Hardcoded /tmp access no longer works if TMPDIR points to another directory [#4589]
  • Stop clobbering DUNE_CACHE in the sandbox script [#4535, fixing ocaml/dune#4166]
  • Ctrl-C now correctly terminates builds with bubblewrap; sandbox now requires bubblewrap 0.1.8 or later [#4400]
  • Linux sandbox script no longer makes PWD read-write on remove actions [#4589]
  • Lint W59 and E60 no longer trigger for packages flagged conf [#4549]
  • Reduce the length of temporary file names for pin caching to ease pressure on Windows [#4590]
  • Security: correct quoting of arguments when removing switches [#4707]
  • Stop advertising the removed option --compiler when creating local switches [#4718]
  • Pinning no longer fails if the archive's opam file is malformed [#4580]
  • Fish: stop using deprecated ^ syntax to fix support for Fish 3.3.0+ [#4736]

Installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.0.9"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

Feedback on this post is welcomed on Discuss!

The opam team has great pleasure in announcing opam 2.1.0~rc2!

The focus since beta4 has been preparing for a world with more than one released version of opam (i.e. 2.0.x and 2.1.x). The release candidate extends CLI versioning further and, under the hood, includes a big change to the opam root format which allows new versions of opam to indicate that the root may still be read by older versions of the opam libraries. A plugin compiled against the 2.0.9 opam libraries will therefore be able to read information about an opam 2.1 root (plugins and tools compiled against 2.0.8 are unable to load opam 2.1.0 roots).

Please do take this release candidate for a spin! It is available in the Docker images at ocaml/opam on Docker Hub as the opam-2.1 command (or you can sudo ln -f /usr/bin/opam-2.1 /usr/bin/opam in your Dockerfile to switch to it permanently). The release candidate can also be tested via our installation script (see the wiki for more information).

Thank you to anyone who noticed the unannounced first release candidate and tried it out. Between tagging and what would have been announcing it, we discovered an issue with upgrading local switches from earlier alpha/beta releases, and so fixed that for this second release candidate.

Assuming no showstoppers, we plan to release opam 2.1.0 next week. The improvements made in 2.1.0 will allow for a much faster release cycle, and we look forward to posting about the 2.2.0 plans soon!

Try it!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.0~rc2"
    

    or download manually from the Github "Releases" page to your PATH.

  2. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

We hope there won't be any, but please report any issues to the bug-tracker. Thanks for trying it out, and hoping you enjoy!

See full changelog
  • Remove OPAMZ3DEBUG evironment variable [#4720 @rjbou - fix #4717]
  • Fix format upgrade when there is missing local switches in the config file [#4715 @rjbou - fix #4713]
  • Fix not recorded local switch handling, with format upgrade [#4715 @rjbou]
  • Set opam root version to 2.1 [#4715 @rjbou]
  • Improved and extended tests [#4715 @rjbou]
See full changelog
  • (*) Environment variables initialised only at opam client launch, no more via libraries [#4606 #4703 @rjbou]
  • (*) Deprecated build-doc, build-test, make flags [#4581 @rjbou]
  • (+) Add --confirm-level and OPAMCONFIRMLEVEL for automatic answering [#4582 @rjbou - fix #4168; #4683 @dra27 - fix #4682; #4691 @rjbou - fix #4682]
  • (+) Add --no [#4582 @rjbou]
  • (+) Add a --with-0install-solver option to the configure script to enable the 'builtin-0install' solver [#4646 @kit-ty-kate]
  • Add default CLI mechanism: deprecated options are accepted (in the major version) if no CLI is specified [#4575 @rjbou]
  • Add opam config deprecated subcommands in the default CLI [#4575 @rjbou - fix #4503]
  • Add CLI versioning for opam environment variables [#4606 @rjbou]
  • Add CLI versioning for enums of flags with predefined enums [#4606 @rjbou]
  • Clearer messages about using --cli and OPAMCLI [#4655 @dra27]
  • The options --root and --switch are now reflected in environment variables when building packages so that calls to opam during build access the correct root and switch [#4668 @LasseBlaauwbroek]
  • Add CLI versioning for enums of flags with predefined enums [#4626 @rjbou]
  • Preprocess --confirm-level for plugins calls/install [#4694 @rjbou]
  • Ensure the symlink for a plugin is maintained on each invocation [#4621 @dra27 - partially fixes #4619]
  • Initialise environment variables for plugins call/install [#4582 @rjbou]
  • Expect plugins to end in .exe on Windows [#4709 @dra27]
  • Introduce a default-invariant config field, restore the 2.0 semantics for default-compiler [#4607 @AltGr]
  • Fix default invariant with no system compiler [#4644 @AltGr - fix #4640]
  • Perform an hard upgrade on intermediate roots, i.e., root from 2.1~alpha/beta, and keep a light upgrade from 2.0 [#4638 @rjbou]
  • Send the 'opam root layout update' message to stderr [#4692 @AltGr]
  • If opam root is different from the binary, allow reading it and try to read in best effort mode [#4638 @rjbou - fix #4636]
  • Don't check opam system dependencies on reinit after a format upgrade [#4638 @rjbou]
  • Fix sys-ocaml-cc, sys-ocaml-arch, and sys-ocaml-libc when no system compiler installed [#4706 @dra27]
  • Fix Not_found (config file) in config report [#4570 @rjbou]
  • Config report: Print variables of installed compilers and their (installed) dependencies [#4570 @rjbou]
  • Don't patch twice file [#4529 @rjbou]
  • With --deps-only, set dependencies as root packages [#4964 @rjbou - fix #4502]
  • Keep global lock only if root format upgrade is performed [#4612 @rjbou - fix #4597]
  • Improve installation times by only tracking files listed in .install instead of the whole switch prefix when there are no install: instructions (and no preinstall commands) [#4494 @kit-ty-kate @rjbou; #4667 @dra27 - fix #4422]
  • Scrub opam* environment variables added since 2.0 from package builds to prevent warnings when a package calls opam [#4663 @dra27 - fix #4660]
  • Correct the message when more than one depext is missing [#4678 @dra27]
  • Only display one conflict message when they are all owing to identical missing depexts [#4678 @dra27]
  • Don't exclude base packages from rebuilds (made some sense in opam 2.0 with base packages but doesn't make sense with 2.1 switch invariants) [#4569 @dra27]
  • Don't refer to base packages in messages any more [#4623 @dra27 - fixes #4572]
  • Give the correct command when demonstrating switch creation [#4675 @dra27 - fixes #4673]
  • On switch loading, if invariant is inferred and a write lock required, write the file [#4638 @rjbou]
  • Don't look for lock files for pin depends [#4511 @rjbou - fix #4505]
  • Fetch sources when pinning an already-pinned package with a different URL when using working directory [#4542 @rjbou - fix #4484]
  • Don't ask for confirmation for pinning base packages (similarly makes no sense with 2.1 switch invariants) [#4571 @dra27]
  • Fix version pin source retrieving: mustn't error if archive opam file is malformed [#4580 @rjbou]
  • opam list --silent renamed to --check [#4595 @dra27 - fix #4323]
  • Include doc field in opam-show [#4567 @dra27 - partially fix #4565]
  • Fix switch global variable resolving [#4685 @rjbou - fix #4684]
  • Fix hash package variable resolving [#4687 @rjbou]
  • Lint: Fix W59 & E60 for conf packages (no URL required) [#4550 @rjbou - fix #4549]
  • Lint: Fix W59 & E60 with VCS URLs, don't check upstream if URL has VCS backend [#4635 @rjbou]
  • Lint: Add E67 checksum specified with non archive URL [#4635 @rjbou]
  • Lint: Disable subpath warning E63,W64 [#4638 @rjbou]
  • Lint: Fix manpage listing [#4708 @rjbou]
  • Don't write lock file with --read-only, --safe, and --dryrun [#4562 @rjbou - fix #4320]
  • Make opam lock consistent with opam install. On local pin, always take last opam file even if uncommitted [#4562 @rjbou - fix #4320]
  • Opam file: Fix features parser [#4507 @rjbou]
  • Opam file: Rename hidden-version to avoid-version [#4527 @dra27]
  • Opam file: Fix rewriting with preserved format empty field error [#4634 @rjbou - fix #4628]
  • Opam file: Switch config: Defined invariant field as an option to differentiate when it is not defined [#4638 @rjbou]
  • Opam file: Differentiate bad format from bad (opam) version with Bad_version exception, raised from OpamFormat.check_opam_version [#4638 @rjbou]
  • Opam file: Always print the opam-version field on files [#4638 @rjbou]
  • Opam file: Config: add opam-root-version field as a marker for the whole opam root [#4638 @rjbou - fix #4636]
  • Opam file: Add BestEffort modules with reading functions that don't show errors, given the opam_file_format internal field [#4638 @rjbou - fix #4636]
  • Depext: Handle macport variants [#4509 @rjbou - fix #4297]
  • Depext: Always upgrade all the installed packages when installing a new package on Archlinux [#4556 @kit-ty-kate]
  • Depext: Handle some additional environment variables (OPAMASSUMEDEPEXTS, OPAMNODEPEXTS) [#4587 @AltGr]
  • Depext: Improve messages to hint that answering no doesn't abort installation [#4591 @AltGr]
  • Depext: Add support for non-interactive mode in MacPorts [#4676 @kit-ty-kate]
  • Depext: Handling of packages of tagged repositories for Alpine [#4700 @rjbou - fix #4670]
  • Depext: Clarify some assume-depexts related messages [#4671 @AltGr - partial fix #4662]
  • Depext: Warn the user if epel-release is missing and unavailable, depexts are detected [#4679 @dra27 fix #4669]
  • Depext: Ignore config yes automatic answering when asking confirmation to run install commands [#4698 @rjbou - fix #4680]
  • Sandbox: Fix the conflict with the environment variable name used by Dune [#4535 @smorimoto - fix ocaml/dune#4166]
  • Sandbox: Kill builds on Ctrl-C with bubblewrap [#4530 @kit-ty-kate - fix #4400]
  • Sandbox: Linux: mount existing TMPDIR read-only, re-bind $TMPDIR to a separate TMPFs [#4589 @AltGr]
  • Sandbox: Fix the sandbox check [#4589 @AltGr]
  • Sandbox: Fix sandbox script shell mistake that made PWD read-write on remove actions [#4589 @AltGr]
  • Sandbox: Port bwrap improvements to sandbox_exec [#4589 @AltGr]
  • Sandbox: Fix realpath use for macOS, partial revert of #4589 [#4609 @AltGr]
  • Add missing shell quoting to support space and special shell characters in switch directory path [#4707 @kit-ty-kate]
  • Rename state.cache to include the OpamVersion.magic() string. All .cache files are deleted if any cache file is written to, allowing multiple versions of the library to coexist without constantly regenerating it [#4642 @dra27 - fix #4554]
  • Fix cuDF preprocessing [#4534 #4627 @AltGr - fix #4624]
  • Allow to upgrade to a hidden-version package if a hidden-version package is already installed [#4525 @kit-ty-kate]
  • Add support for a few select criteria useful to CI to the 0install solver: +count[version-lag,solution] to always choose the oldest version available, +removed to not try to keep installed packages [#4631 @kit-ty-kate]
  • Fix opam-devel's tests on platforms without OpenSSL, GNU-diff, and a system-wide OCaml [#4500 @kit-ty-kate]
  • Use Dune to run reftests [#4376 @emillon]
  • Restrict extlib and dose version [#4517 @kit-ty-kate]
  • Restrict to opam-file-format.2.1.2 [#4495 @rjbou]
  • Require opam-file-format.2.1.3+ in order to enforce opam-version: "2.1" as first non-comment line [#4639 @dra27 - fix #4394]
  • Switch to newer version of MCCS (based on newer GLPK) for src_ext [#4559 @AltGr]
  • Bump Dune version to 2.8.2 [#4592 @AltGr]
  • Bump the minimal Dune requirement to Dune 1.11 [#4437 @dra27 @kit-ty-kate]
  • 4.12 compatibility [#4437 @dra27 @kit-ty-kate]
  • Cold compiler updated to 4.12 [#4616 @dra27]
  • Fix build from source when a dune-project file is presented in the parent directory [#4545 @kit-ty-kate]
  • Fix build from source when a dune-project file is presented in the parent directory [#4545 @kit-ty-kate - fix #4537]
  • Fix opam-devel.install not to install two files called opam [#4664 @dra27]
  • Build release tags as non-dev versions, as for release tarballs [#4665 @dra27 - fix #4656]
  • Disable dev version for tests (needed for format upgrade test) [#4638 @rjbou]
  • Add a hint for missing openssl in make cold [#4702 @rjbou]
  • Remove test field from opam-devel, they need the network [#4702 @rjbou]
  • Update src_ext for Dune and MCCS [#4704 @dra27]
  • Release scripts: switch to OCaml 4.10.2 by default, add macOS/ARM64 builds by default [#4559 @AltGr]
  • Release scripts: add default CLI version check on full archive build [#4575 @rjbou]
  • Arg: Generalise mk_tristate_opt to mk_state_opt [#4575 @rjbou]
  • Arg: Fix mk_state_opt and rename to mk_enum_opt [#4626 @rjbou]
  • Arg: Add mk_enum_opt_all for state flags that appears more than once [#4582 @rjbou]
  • Fix opam exec on native Windows when calling Cygwin executables [#4588 @AltGr]
  • Fix temporary file with a too long name causing errors on Windows [#4590 @AltGr]
  • CLI: Add flag deprecation and replacement helper [#4595 @rjbou]
  • Win32 Console: fix VT100 support [#3897 #4710 @dra27]
  • Tidied the opam files [#4620 @dra27]
  • Externalise CLI versioning tools from OpamArg into OpamArgTools [#4606 @rjbou]
  • Each library defines its own environment variables that fills the config record [#4606 @rjbou]
  • Harden cygpath wrapper [#4625 @dra27]
  • Reset the plugin symlinks when the root is upgraded [#4641 @dra27 - partial fix for #4619]
  • Formalise opam dev version detection with OpamVersion.is_dev_version [#4665 @dra27]
  • Add OpamStd.String.is_prefix_of [#4694 @rjbou @dra27]
  • Fix OpamStd.Format.pretty_list: last argument dropped if list contains more than 2 elements [#4694 @rjbou]
  • Run the shell hooks with closed stdin (bash, zsh) [#4692 @AltGr]
  • Improved and extended tests [#4376 #4504 #4545 #4612 #4668 #4612 #4634 #4672 #4638 #4702 #4697 #4697 @AltGr @dra27 @emillon @rjbou]
  • Improve GitHub Actions [#4593 #4575 #4610 #4610 #4618 #4606 #4695 #4695 @AltGr @dra27 @rjbou]
  • Improve documentation [#4496 #4506 #4513 #4637 #4681 #4702 @dannywillems @eth-arm @kit-ty-kate @rjbou @UnixJunkie]

Feedback on this post is welcomed on Discuss!

On behalf of the opam team, it gives me great pleasure to announce the third beta release of opam 2.1. Don’t worry, you didn’t miss beta3 - we had an issue with a configure script that caused beta2 to report as beta3 in some instances, so we skipped to beta4 to avoid any further confusion!

We encourage you to try out this new beta release: there are instructions for doing so in our wiki. The instructions include taking a backup of your ~/.opam root as part of the process, which can be restored in order to wind back. Please note that local switches which are written to by opam 2.1 are upgraded and will need to be rebuilt if you go back to opam 2.0. This can either be done by removing _opam and repeating whatever you use in your build process to create the switch, or you can use opam switch export switch.export to backup the switch to a file before installing new packages. Note that opam 2.1 shouldn’t upgrade a local switch unless you upgrade the base packages (i.e. the compiler).

What’s new in opam 2.1?

  • Switch invariants
  • Improved options configuration (see the new option and expanded var sub-commands)
  • Integration of system dependencies (formerly the opam-depext plugin), increasing their reliability as it integrates the solving step
  • Creation of lock files for reproducible installations (formerly the opam-lock plugin)
  • CLI versioning, allowing cleaner deprecations for opam now and also improvements to semantics in future without breaking backwards-compatibility
  • Performance improvements to opam-update, conflict messages, and many other areas
  • New plugins: opam-compiler and opam-monorepo

Switch invariants

In opam 2.0, when a switch is created the packages selected are put into the “base” of the switch. These packages are not normally considered for upgrade, in order to ease pressure on opam’s solver. This was a much bigger concern early on in opam 2.0’s development, but is less of a problem with the default mccs solver.

However, it’s a problem for system compilers. opam would detect that your system compiler version had changed, but be unable to upgrade the ocaml-system package unless you went through a slightly convoluted process with --unlock-base.

In opam 2.1, base packages have been replaced by switch invariants. The switch invariant is a package formula which must be satisfied on every upgrade and install. All existing switches’ base packages could just be expressed as package1 & package2 & package3 etc. but opam 2.1 recognises many existing patterns and simplifies them, so in most cases the invariant will be "ocaml-base-compiler" {= 4.11.1}, etc. This means that opam switch create my_switch ocaml-system now creates a switch invariant of "ocaml-system" rather than a specific version of the ocaml-system package. If your system OCaml package is updated, opam upgrade will seamlessly switch to the new package.

This also allows you to have switches which automatically install new point releases of OCaml. For example:

opam switch create ocaml-4.11 --formula='"ocaml-base-compiler" {>= "4.11.0" & < "4.12.0~"}' --repos=old=git+https://github.com/ocaml/opam-repository#a11299d81591
opam install utop

Creates a switch with OCaml 4.11.0 (the --repos= was just to select a version of opam-repository from before 4.11.1 was released). Now issue:

opam repo set-url old git+https://github.com/ocaml/opam-repository
opam upgrade

and opam 2.1 will automatically offer to upgrade OCaml 4.11.1 along with a rebuild of the switch. There’s not yet a clean CLI for specifying the formula, but we intend to iterate further on this with future opam releases so that there is an easier way of saying “install OCaml 4.11.x”.

opam depext integration

opam has long included the ability to install system dependencies automatically via the depext plugin. This plugin has been promoted to a native feature of opam 2.1.0 onwards, giving the following benefits:

  • You no longer have to remember to run opam depext, opam always checks depexts (there are options to disable this or automate it for CI use). Installation of an opam package in a CI system is now as easy as opam install ., without having to do the dance of opam pin add -n/depext/install. Just one command now for the common case!
  • The solver is only called once, which both saves time and also stabilises the behaviour of opam in cases where the solver result is not stable. It was possible to get one package solution for the opam depext stage and a different solution for the opam install stage, resulting in some depexts missing.
  • opam now has full knowledge of depexts, which means that packages can be automatically selected based on whether a system package is already installed. For example, if you have neither MariaDB nor MySQL dev libraries installed, opam install mysql will offer to install conf-mysql and mysql, but if you have the MariaDB dev libraries installed, opam will offer to install conf-mariadb and mysql.

opam lock files and reproducibility

When opam was first released, it had the mission of gathering together scattered OCaml source code to build a community repository. As time marches on, the size of the opam repository has grown tremendously, to over 3000 unique packages with over 18000 unique versions. opam looks at all these packages and is designed to solve for the best constraints for a given package, so that your project can keep up with releases of your dependencies.

While this works well for libraries, we need a different strategy for projects that need to test and ship using a fixed set of dependencies. To satisfy this use-case, opam 2.0.0 shipped with support for using project.opam.locked files. These are normal opam files but with exact versions of dependencies. The lock file can be used as simply as opam install . --locked to have a reproducible package installation.

With opam 2.1.0, the creation of lock files is also now integrated into the client:

  • opam lock will create a .locked file for your current switch and project, that you can check into the repository.
  • opam switch create . --locked can be used by users to reproduce your dependencies in a fresh switch.

This lets a project simultaneously keep up with the latest dependencies (without lock files) while providing a stricter set for projects that need it (with lock files).

CLI Versioning

A new --cli switch was added to the first beta release, but it’s only now that it’s being widely used. opam is a complex enough system that sometimes bug fixes need to change the semantics of some commands. For example:

  • opam show --file needed to change behaviour
  • The addition of new controls for setting global variables means that the opam config was becoming cluttered and some things want to move to opam var
  • opam switch install 4.11.1 still works in opam 2.0, but it’s really an OPAM 1.2.2 syntax.

Changing the CLI is exceptionally painful since it can break scripts and tools which themselves need to drive opam. CLI versioning is our attempt to solve this. The feature is inspired by the (lang dune ...) stanza in dune-project files which has allowed the Dune project to rename variables and alter semantics without requiring every single package using Dune to upgrade their dune files on each release.

Now you can specify which version of opam you expected the command to be run against. In day-to-day use of opam at the terminal, you wouldn’t specify it, and you’ll get the latest version of the CLI. For example: opam var --global is the same as opam var --cli=2.1 --global. However, if you issue opam var --cli=2.0 --global, you will told that --global was added in 2.1 and so is not available to you. You can see similar things with the renaming of opam upgrade --unlock-base to opam upgrade --update-invariant.

The intention is that --cli should be used in scripts, user guides (e.g. blog posts), and in software which calls opam. The only decision you have to take is the oldest version of opam which you need to support. If your script is using a new opam 2.1 feature (for example opam switch create --formula=) then you simply don’t support opam 2.0. If you need to support opam 2.0, then you can’t use --formula and should use --packages instead. opam 2.0 does not have the --cli option, so for opam 2.0 instead of --cli=2.0 you should set the environment variable OPAMCLI to 2.0. As with all opam command line switches, OPAMCLI is simply the equivalent of --cli which opam 2.1 will pick-up but opam 2.0 will quietly ignore (and, as with other options, the command line takes precedence over the environment).

Note that opam 2.1 sets OPAMCLI=2.0 when building packages, so on the rare instances where you need to use the opam command in a package build: command (or in your build system), you must specify --cli=2.1 if you’re using new features.

There’s even more detail on this feature in our wiki. We’re still finalising some details on exactly how opam behaves when --cli is not given, but we’re hoping that this feature will make it much easier in future releases for opam to make required changes and improvements to the CLI without breaking existing set-ups and tools.

What’s new since the last beta?

  • opam now uses CLI versioning (#4385)
  • opam now exits with code 31 if all failures were during fetch operations (#4214)
  • opam install now has a --download-only flag (#4036), allowing opam’s caches to be primed
  • opam init now advises the correct shell-specific command for eval $(opam env) (#4427)
  • post-install hooks are now allowed to modify or remove installed files (#4388)
  • New package variable opamfile-loc with the location of the installed package opam file (#4402)
  • opam update now has --depexts flag (#4355), allowing the system package manager to update too
  • depext support NetBSD and DragonFlyBSD added (#4396)
  • The format-preserving opam file printer has been overhauled (#3993, #4298 and #4302)
  • pins are now fetched in parallel (#4315)
  • os-family=ubuntu is now treated as os-family=debian (#4441)
  • opam lint now checks that strings in filtered package formulae are booleans or variables (#4439)

and many other bug fixes as listed on the release page.

New Plugins

Several features that were formerly plugins have been integrated into opam 2.1.0. We have also developed some new plugins that satisfy emerging workflows from the community and the core OCaml team. They are available for use with the opam 2.1 beta as well, and feedback on them should be directed to the respective GitHub trackers for those plugins.

opam compiler

The opam compiler plugin can be used to create switches from various sources such as the main opam repository, the ocaml-multicore fork, or a local development directory. It can use Git tag names, branch names, or PR numbers to specify what to install.

Once installed, these are normal opam switches, and one can install packages in them. To iterate on a compiler feature and try opam packages at the same time, it supports two ways to reinstall the compiler: either a safe and slow technique that will reinstall all packages, or a quick way that will just overwrite the compiler in place.

opam monorepo

The opam monorepo plugin lets you assemble standalone dune workspaces with your projects and all of their opam dependencies, letting you build it all from scratch using only Dune and OCaml. This satisfies the “monorepo” workflow which is commonly requested by large projects that need all of their dependencies in one place. It is also being used by projects that need global cross-compilation for all aspects of a codebase (including C stubs in packages), such as the MirageOS unikernel framework.

Next Steps

This is anticipated to be the final beta in the 2.1 series, and we will be moving to release candidate status after this. We could really use your help with testing this release in your infrastructure and projects and let us know if you run into any blockers. If you have feature requests, please also report them on our issue tracker -- we will be planning the next release cycle once we ship opam 2.1.0 shortly.

See full changelog
  • (*) Implemented CLI version compatibility layer [#4385 @rjbou]
  • (*) Return code 31 (Sync_error) instead of code 40 (Package_operation_error) when all failures happend during fetching [#4416 @rjbou - fix #4214]
  • (+) Add --download-only flag [#4071 @Armael @rjbou - fix #4036]
  • (+) Provide opam update --depexts to request an update of the system package manager databases [#4379 @AltGr - fix #4355]
  • Set OPAMCLI=2.0 during package action commands [#4492 @kit-ty-kate]
  • Fix sandbox check on first opam init [#4370 @rjbou - fix #4368]
  • Print shell-appropriate eval command on opam init [#4427 @freevoid]
  • Fix init script check in csh [#4482 @gahr]
  • The stdout of pre- and post-session hooks is now propagated to the user [#4382 @AltGr - fix #4359]
  • post-install hooks are now allowed to modify or remove installed files [#4388 @lefessan]
  • Add support for switch-specific pre/post sessions hooks [#4476 @rjbou - fix #4472]
  • Ensure we don't advertise upgrades to hidden versions [#4477 @AltGr - fix #4432]
  • Fix opam remove --autoremove <PKG> to not autoremove unrelated packages [#4369 @AltGr - fix #4250 #4332]
  • Fix cases where opam remove -a could trigger conflicts in the presence of orphan packages [#4369 @AltGr - fix #4250 #4332]
  • Fix --update-invariant when removing or changing package name [#4360 @AltGr - fix #4353]
  • Fix updates of the invariant with --update-invariant [#4431 @AltGr]
  • Fix cleanup of build dirs for version pinned packages [#4436 @rjbou - fix #4255]
  • Fix opamfile format upgrade on pinning [#4366 @rjbou - fix #4365]
  • Fix pin --show actually pinning [#4367 @rjbou - fix #4348]
  • When several pins are needed, do their fetching in parallel [#4399 @rjbou - fix #4315]
  • Don't cleanup VCS pin source directories [#4399 @rjbou]
  • Fix --working-dir with local switches [#4433 @rjbou]
  • Add package variable opamfile-loc, containing the location of installed package opam file [#4402 @rjbou]
  • Fix arch detection when using 32bit mode on ARM64 [#4462 @kit-ty-kate]
  • Fix arch detection of i486 [#4462 @kit-ty-kate]
  • Skip loading the switch state for variable lookup when possible [#4428 @rjbou]
  • Fix package variables display when no config file is found [#4428 @rjbou]
  • Fix opam option depext-bypass-=["XXX"] [#4428 @rjbou]
  • Lint: add a check that strings in filtered package formula are Booleans or variables [#443 @rjbou - fix #4439]
  • Fix handling of filename-encoded pkgname in opam files [#4401 @AltGr - fix ocaml-opam/opam-publish#107]
  • Don't recompile when modifying the package flags [#4477 @AltGr]
  • Add depext support for NetBSD and DragonFlyBSD [#4396 @kit-ty-kate]
  • Fix depexts on OpenBSD, FreeBSD, and Gentoo: Allow short names and full name paths for ports-based systems [#4396 @kit-ty-kate]
  • Handle the case where os-family=ubuntu as os-family=debian [#4441 @alan-j-hu]
  • Update opam's opam files to 2.0 [#4371 @AltGr]
  • Makefile: Add rule custom-libinstall for opam-custom-install use [#4401 @AltGr]
  • Use the archive caches when running opam admin cache [#4384 @AltGr - fix #4352]
  • Fix explosion of opam admin check --cycles on repositories with huge cliques [#4392 @AltGr]
  • Much improved format-preserving printer [#4298 #4302 @rjbou - fix #3993]
  • Fix missing conflict message when trying to remove required packages [#4362 @AltGr]
  • Fix the Z3 backend for upgrades [#4393 @AltGr]
  • Fix cases where opam would wrongly complain about action cycles [#4358 @AltGr - fix #4357]
  • Fix permission denied fallback for openssl [#4449 @Blaisorblade - fix #4448]
  • Add debug & verbose log for patch & subst applications [#4464 @rjbou - fix #4453]
  • Be more robust w.r.t. new caches updates when --read-only is not used [#4467 @AltGr - fix #4354]
  • Improved and extended tests [#4375 #4395 #4428 #4385 #4467 #4475 #4483 @emillon @rjbou @AltGr @freevoid @dra27]
  • Switched to GitHub actions [#4463 @rjbou]

We are pleased to announce the minor release of opam 2.0.8.

This new version contains some backported fixes:

  • Critical for fish users! Don't add . to PATH. [#4078]
  • Fix sandbox script for newer ccache versions. [#4079 and #4087]
  • Fix sandbox crash when ~/.cache is a symlink. [#4068]
  • User modifications to the sandbox script are no longer overwritten by opam init. [#4020 & #4092]
  • macOS sandbox script always mounts /tmp read-write, regardless of TMPDIR [#3742, addressing ocaml/opam-repository#13339]
  • pre- and post-session hooks can now print to the console [#4359]
  • Switch-specific pre/post sessions hooks are now actually run [#4472]
  • Standalone opam-installer now correctly builds from sources [#4173]
  • Fix arch variable detection when using 32bit mode on ARM64 and i486 [#4462]

A more complete release note is available.


Installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.0.8"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com, and published in discuss.ocaml.org. Please head to the latter for the comments!

See full changelog
  • Reduced startup times, in particular for opam exec [#4341 @altgr]
  • Fixed the sandboxing check on fresh inits [#4342 @altgr]
  • Fixed cases where --with-version was not respected by opam pin [#4346 @altgr]
  • Upgraded the bootstrap OCaml compiler from 4.09.1 to 4.11.1 [#4242 @avsm @dra27 @MisterDA @rjbou]

We are happy to announce a alpha for opam 2.1.0, one year and a half in the making after the release of 2.0.0.

Many new features made it in (see the complete changelog or release note for the details), but here are a few highlights of this release.

Release highlights

The two following features have been around for a while as plugins and are now completely integrated in the core of opam. No extra installs needed anymore, and a more smooth experience.

Seamless integration of System dependencies handling (a.k.a. "depexts")

A number of opam packages depend on tools or libraries installed on the system, which are out of the scope of opam itself. Previous versions of opam added a specification format, and opam 2.0 already handled checking the OS and extracting the required system package names.

However, the workflow generally involved letting opam fail once, then installing the dependencies and retrying, or explicitely using the opam-depext plugin, which was invaluable for CI but still incurred extra steps.

With opam 2.1.0, depexts are seamlessly integrated, and you basically won't have to worry about them ahead of time:

  • Before applying its course of actions, opam 2.1.0 checks that external dependencies are present, and will prompt you to install them. You are free to let it do it using sudo, or just run the provided commands yourself.
  • It is resilient to depexts getting removed or out of sync.
  • Opam 2.1.0 detects packages that depend on stuff that is not available on your OS version, and automatically avoids them.

This is all fully configurable, and can be bypassed without tricky commands when you need it (e.g. when you compiled a dependency yourself).

Dependency locking

To share a project for development, it is often necessary to be able to reproduce the exact same environment and dependencies setting — as opposed to allowing a range of versions as opam encourages you to do for releases.

For some reason, most other package managers call this feature "lock files". Opam can handle those in the form of [foo.]opam.locked files, and the --locked option.

With 2.1.0, you no longer need a plugin to generate these files: just running opam lock will create them for existing opam files, enforcing the exact version of all dependencies (including locally pinned packages).

If you check-in these files, new users would just have run opam switch create . --locked on a fresh clone to get a local switch ready to build the project.

Pinning sub-directories

This one is completely new: fans of the Monorepo rejoice, opam is now able to handle projects in subtrees of a repository.

  • Using opam pin PROJECT_ROOT --subpath SUB_PROJECT, opam will look for PROJECT_ROOT/SUB_PROJECT/foo.opam. This will behave as a pinning to PROJECT_ROOT/SUB_PROJECT, except that the version-control handling is done in PROJECT_ROOT.
  • Use opam pin PROJECT_ROOT --recursive to automatically lookup all sub-trees with opam files and pin them.

Opam switches are now defined by invariants

Previous versions of opam defined switches based on base packages, which typically included a compiler, and were immutable. Opam 2.1.0 instead defines them in terms of an invariant, which is a generic dependency formula.

This removes a lot of the rigidity opam switch commands had, with little changes on the existing commands. For example, opam upgrade ocaml commands are now possible; you could also define the invariant as ocaml-system and have its version change along with the version of the OCaml compiler installed system-wide.

Configuring opam from the command-line

The new opam option command allows to configure several options, without requiring manual edition of the configuration files.

For example:

  • opam option jobs=6 --global will set the number of parallel build jobs opam is allowed to run (along with the associated jobs variable)
  • opam option depext-run-commands=false disables the use of sudo for handling system dependencies; it will be replaced by a prompt to run the installation commands.

The command opam var is extended with the same format, acting on switch and global variables.

Try it!

In case you plan a possible rollback, you may want to first backup your ~/.opam directory.

The upgrade instructions are unchanged:

  1. Either from binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.1.0~alpha"
    

    or download manually from the Github "Releases" page to your PATH.

  2. Or from source, manually: see the instructions in the README.

You should then run:

opam init --reinit -ni

This is still a alpha, so a few glitches or regressions are to be expected. Please report them to the bug-tracker. Thanks for trying it out, and hoping you enjoy!

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce the minor release of opam 2.0.7.

This new version contains backported small fixes:


Installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.0.7"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce the minor release of opam 2.0.6.

As sandbox scripts have been updated, don't forget to run opam init --reinit -ni to update yours.

Note: To homogenise macOS name on system detection, we decided to keep macos, and convert darwin to macos in opam. For the moment, to not break jobs & CIs, we keep uploading darwin & macos binaries, but from the 2.1.0 release, only macos ones will be kept.


Installation instructions (unchanged):

  1. From binaries: run

    bash -c "sh <(curl -fsSL https://opam.ocaml.org/install.sh) --version 2.0.6"
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce the minor release of opam 2.0.5.

This new version contains build update and small fixes:

Note: To homogenise macOS name on system detection, we decided to keep macos, and convert darwin to macos in opam. For the moment, to not break jobs & CIs, we keep uploading darwin & macos binaries, but from the 2.1.0 release, only macos ones will be kept.


Installation instructions (unchanged):

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce the release of opam 2.0.4.

This new version contains some backported fixes:

Note: To homogenise macOS name on system detection, we decided to keep macos, and convert darwin to macos in opam. For the moment, to not break jobs & CIs, we keep uploading darwin & macos binaries, but from the 2.1.0 release, only macos ones will be kept.


Installation instructions (unchanged):

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce the release of opam 2.0.3.

This new version contains some backported fixes:

  • Fix manpage remaining $ (OPAMBESTEFFORT)
  • Fix OPAMROOTISOK handling
  • Regenerate missing environment file

Installation instructions (unchanged):

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new major version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce the release of opam 2.0.2.

As sandbox scripts have been updated, don't forget to run opam init --reinit -ni to update yours.

This new version contains mainly backported fixes:

  • Doc:
    • update man page
    • add message for deprecated options
    • reinsert removed ones to print a deprecated message instead of fail (e.g. --alias-of)
    • deprecate no-aspcud
  • Pin:
    • on pinning, rebuild updated pin-depends packages reliably
    • include descr & url files on pinning 1.2 opam files
  • Sandbox:
    • handle symlinks in bubblewrap for system directories such as /bin or /lib (#3661). Fixes sandboxing on some distributions such as CentOS 7 and Arch Linux.
    • allow use of unix domain sockets on macOS (#3659)
    • change one-line conditional to if statement which was incompatible with set -e
    • make /var readonly instead of empty and rw
  • Path: resolve default opam root path
  • System: suffix .out for read_command_output stdout files
  • Locked: check consistency with opam file when reading lock file to suggest regeneration message
  • Show: remove pin depends messages
  • Cudf: Fix closure computation in the presence of cycles to have a complete graph if a cycle is present in the graph (typically ocaml-base-compilerocaml)
  • List: Fix some cases of listing coinstallable packages
  • Format upgrade: extract archived source files of version-pinned packages
  • Core: add is_archive in OpamSystem and OpamFilename
  • Init: don't fail if empty compiler given
  • Lint: fix light_uninstall flag for error 52
  • Build: partial port to dune
  • Update cold compiler to 4.07.1

Installation instructions (unchanged):

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update your sandbox script.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed or to update you sandbox script)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new minor version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce the release of opam 2.0.1.

This new version contains mainly backported fixes, some platform-specific:

  • Cold boot for MacOS/CentOS/Alpine
  • Install checksum validation on MacOS
  • Archive extraction for OpenBSD now defaults to using gtar
  • Fix compilation of mccs on MacOS and Nix platforms
  • Do not use GNU-sed specific features in the release Makefile, to fix build on OpenBSD/FreeBSD
  • Cleaning to enable reproducible builds
  • Update configure scripts

And some opam specific:

  • git: fix git fetch by sha1 for git < 2.14
  • linting: add test variable warning and empty description error
  • upgrade: convert pinned but not installed opam files
  • error reporting: more comprehensible error message for tar extraction, and upgrade of git-url compilers
  • opam show: upgrade given local files
  • list: as opam 2.0.0 list doesn't return non-zero code if list is empty, add --silent option for a silent output and returns 1 if list is empty

Installation instructions (unchanged):

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new major version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are happy to announce the final release of opam 2.0.0.

A few weeks ago, we released a last release candidate to be later promoted to 2.0.0, synchronised with the opam package repository upgrade.

You are encouraged to update as soon as you see fit, to continue to get package updates: opam 2.0.0 supports the older formats, and 1.2.2 will no longer get regular updates. See the Upgrade Guide for details about the new features and changes.

The website opam.ocaml.org has been updated, with the full 2.0.0 documentation pages. You can still find the documentation for the previous versions in the corresponding menu.

Package maintainers should be aware of the following:

  • the master branch of the opam package repository is now in the 2.0.0 format
  • package submissions must accordingly be made in the 2.0.0 format, or using the new version of opam-publish (2.0.0)
  • anything that was merged into the repository in 1.2 format has been automatically updated to the 2.0.0 format
  • the 1.2 format repository has been forked to its own branch, and will only be updated for critical fixes

For custom repositories, the advice remains the same.


Installation instructions (unchanged):

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new major version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are happy to announce the opam 2.0.0 final release candidate! 🍾

This release features a few bugfixes over Release Candidate 3. It will be promoted to 2.0.0 proper within a few weeks, when the official repository format switches from 1.2.0 to 2.0.0. After that date, updates to the 1.2.0 repository may become limited, as new features are getting used in packages.

It is safe to update as soon as you see fit, since opam 2.0.0 supports the older formats. See the Upgrade Guide for details about the new features and changes. If you are a package maintainer, you should keep publishing as before for now: the roadmap for the repository upgrade will be detailed shortly.

The opam.ocaml.org pages have also been refreshed a bit, and the new version showing the 2.0.0 branch of the repository is already online. Report any issues here.


Installation instructions:

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed)

  3. From source, manually: see the instructions in the README.

We hope you enjoy this new version, and remain open to bug reports and suggestions.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce the release of a third release candidate for opam 2.0.0. This one is expected to be the last before 2.0.0 comes out.

Changes since the 2.0.0~rc2 are, as expected, mostly fixes. We deemed it useful, however, to bring in the following:

  • a new command opam switch link that allows to select a switch to be used in a given directory (particularly convenient if you use the shell hook for automatic opam environment update)
  • a new option opam install --assume-built, that allows to install a package using its normal opam procedure, but for a source repository that has been built by hand. This fills a gap that remained in the local development workflows.

The preview of the opam 2 webpages can be browsed at https://opam.ocaml.org/2.0-preview/ (please report issues here).

Installation instructions (unchanged):

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed)

  3. From source, manually: see the instructions in the README.

Thanks a lot for testing out this new RC and reporting any issues you may find.

We are pleased to announce the release of a second release candidate for opam 2.0.0.

This new version brings us very close to a final 2.0.0 release, and in addition to many fixes, features big performance enhancements over the RC1.

Among the new features, we have squeezed in full sandboxing of package commands for both Linux and macOS, to protect our users from any misbehaving scripts.

NOTE: if upgrading manually from 2.0.0~rc, you need to run opam init --reinit -ni to enable sandboxing.

The new release candidate also offers the possibility to setup a hook in your shell, so that you won't need to run eval $(opam env) anymore. This is specially useful in combination with local switches, because with it enabled, you are guaranteed that running make from a project directory containing a local switch will use it.

The documentation has also been updated, and a preview of the opam 2 webpages can be browsed at https://opam.ocaml.org/2.0-preview/ (please report issues here). This provides the list of packages available for opam 2 (the 2.0 branch of opam-repository), including the compiler packages.

Installation instructions:

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH. In this case, don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained, and don't forget to run opam init --reinit -ni to enable sandboxing if you had version 2.0.0~rc manually installed)

  3. From source, manually: see the instructions in the README.

Thanks a lot for testing out this new RC and reporting any issues you may find.

NOTE: this article is cross-posted on opam.ocaml.org and ocamlpro.com. Please head to the latter for the comments!

We are pleased to announce a first release candidate for the long-awaited opam 2.0.0.

A lot of polishing has been done since the last beta, including tweaks to the built-in solver, allowing in-source package definitions to be gathered in an opam/ directory, and much more.

With all of the 2.0.0 features getting pretty solid, we are now focusing on bringing all the guides up-to-date¹, updating the tools and infrastructure, making sure there are no usability issues with the new workflows, and being future-proof so that further updates break as little as possible.

You are invited to read the beta5 announcement for details on the 2.0.0 features. Installation instructions haven't changed:

  1. From binaries: run

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    or download manually from the Github "Releases" page to your PATH.

  2. From source, using opam:

    opam update; opam install opam-devel
    

    (then copy the opam binary to your PATH as explained)

  3. From source, manually: see the instructions in the README.

Thanks a lot for testing out the RC and reporting any issues you may find. See what we need tested for more detail.


¹ You can at the moment rely on the manpages, the Manual, and of course the API, but other pages might be outdated.

After a few more months brewing, we are pleased to announce a new beta release of opam. With this new milestone, opam is reaching feature-freeze, with an expected 2.0.0 by the beginning of next year.

This version brings many new features, stability fixes, and big improvements to the local development workflows.

What's new

The features presented in past announcements: local switches, in-source package definition handling, extended dependencies are of course all present. But now, all the glue to make them interact nicely together is here to provide new smooth workflows. For example, the following command, if run from the source tree of a given project, creates a local switch where it will restore a precise installation, including explicit versions of all packages and pinnings:

opam switch create ./ --locked

this leverages the presence of opam.locked or <name>.opam.locked files, which are valid package definitions that contain additional details of the build environment, and can be generated with the opam-lock plugin (the lock command may be merged into opam once finalised).

But this new beta also provides a large amount of quality of life improvements, and other features. A big one, for example, is the integration of a built-in solver (derived from mccs and glpk). This means that the opam binary works out-of-the box, without requiring the external aspcud solver, and on all platforms. It is also faster.

Another big change is that detection of architecture and OS details is now done in opam, and can be used to select the external dependencies with the new format of the depexts: field, but also to affect dependencies or build flags.

There is much more to it. Please see the changelog, and the updated manual.

How to try it out

Our warm thanks for trying the new beta and reporting any issues you may hit.

  1. The easiest is to use our pre-compiled binaries. This script will also make backups if you migrate from 1.x, and has an option to revert back:

    sh <(curl -sL https://opam.ocaml.org/install.sh)
    

    This uses the binaries from https://github.com/ocaml/opam/releases/tag/2.0.0-beta5

  2. Another option is to compile from source, using an existing opam installation. Simply run:

    opam update; opam install opam-devel
    

    and follow the instructions (you will need to copy the compiled binary to your PATH).

  3. Compiling by hand from the inclusive source archive, or from the git repo. Use ./configure && make lib-ext && make if you have OCaml >= 4.02.3 already available; make cold otherwise.

    If the build fails after updating a git repo from a previous version, try git clean -fdx src/ to remove any stale artefacts.

Note that the repository format is different from that of opam 1.2. Opam 2 will be automatically redirected from the opam-repository to an automatically rewritten 2.0 mirror, and is otherwise able to do the conversion on the fly (both for package definitions when pinning, and for whole repositories). You may not yet contribute packages in 2.0 format to opam-repository, though.

What we need tested

We are interested in all opinions and reports, but here are a few areas where your feedback would be specially useful to us:

  • Use 2.0 day-to-day, in particular check any packages you may be maintaining. We would like to ensure there are no regressions due to the rewrite from 1.2 to 2.0.
  • Check the quality of the solutions provided by the solver (or conflicts, when applicable).
  • Test the different pinning mechanisms (rsync, git, hg, darcs) with your project version control systems. See the --working-dir option.
  • Experiment with local switches for your project (and/or opam install DIR). Give us feedback on the workflow. Use opam lock and share development environments.
  • If you have any custom repositories, please try the conversion to 2.0 format with opam admin upgrade --mirror on them, and use the generated mirror.
  • Start porting your CI systems for larger projects to use opam 2, and give us feedback on any improvements you need for automated scripting (e.g. the --json output).

UPDATE (2017-02-14): A beta2 is online, which fixes issues and performance of the opam build command. Get the new binaries, or recompile the opam-devel package and replace the previous binary.

We are pleased to announce that the beta release of opam 2.0 is now live! You can try it already, bootstrapping from a working 1.2 opam installation, with:

opam update; opam install opam-devel

With about a thousand patches since the last stable release, we took the time to gather feedback after our last announcement and implemented a couple of additional, most-wanted features:

  • An opam build command that, from the root of a source tree containing one or more package definitions, can automatically handle initialisation and building of the sources in a local switch.
  • Support for repository signing through the external Conex tool, being developed in parallel.

There are many more features, like the new opam clean and opam admin commands, a new archive caching system, etc., but we'll let you check the full changelog.

We also improved still on the already announced features, including compilers as packages, local switches, per-switch repository configuration, package file tracking, etc.

The updated documentation is at https://opam.ocaml.org/doc/2.0/. If you are developing in opam-related tools, you may also want to browse the new APIs.

Try it out

Please try out the beta, and report any issues or missing features. You can:

  • Build it from source in opam, as shown above (opam install opam-devel)
  • Use the pre-built binaries.
  • Building from the source tarball: download here and build using ./configure && make lib-ext && make if you have OCaml >= 4.01 already available; make cold otherwise
  • Or directly from the git tree, following the instructions included in the README. Some files have been moved around, so if your build fails after you updated an existing git clone, try to clean it up (git clean -dx).

Some users have been using the alpha for the past months without problems, but you may want to keep your opam 1.2 installation intact until the release is out. An easy way to do this is with an alias:

alias opam2="OPAMROOT=~/.opam2 path/to/opam-2-binary"

Changes to be aware of

Command-line interface

  • opam switch create is now needed to create new switches, and opam switch is now much more expressive
  • opam list is also much more expressive, but be aware that the output may have changed if you used it in scripts
  • new commands:
    • opam build: setup and build a local source tree
    • opam clean: various cleanup operations (wiping caches, etc.)
    • opam admin: manage software repositories, including upgrading them to opam 2.0 format (replaces the opam-admin tool)
    • opam env, opam exec, opam var: shortcuts for the opam config subcommands
  • opam repository add will now setup the new repository for the current switch only, unless you specify --all
  • Some flags, like --test, now apply to the packages listed on the command-line only. For example, opam install lwt --test will build and install lwt and all its dependencies, but only build/run the tests of the lwt package. Test-dependencies of its dependencies are also ignored
  • The new opam install --soft-request is useful for batch runs, it will maximise the installed packages among the requested ones, but won't fail if all can't be installed

As before, opam is self-documenting, so be sure to check opam COMMAND --help first when in doubt. The bash completion scripts have also been thoroughly improved, and may help navigating the new options.

Metadata

There are both a few changes (extensions, mostly) to the package description format, and more drastic changes to the repository format, mainly related to translating the old compiler definitions into packages.

  • opam will automatically update, internally, definitions of pinned packages as well as repositories in the 1.2 format
  • however, it is faster to use repositories in the 2.0 format directly. To that end, please use the opam admin upgrade command on your repositories. The --mirror option will create a 2.0 mirror and put in place proper redirections, allowing your original repository to retain the old format

The official opam repository at https://opam.ocaml.org remains in 1.2 format for now, but has a live-updated 2.0 mirror to which you should be automatically redirected. It cannot yet accept package definitions in 2.0 format.

Package format

  • Any available: constraints based on the OCaml compiler version should be rewritten into dependencies to the ocaml package
  • Separate build: and install: instructions are now required
  • It is now preferred to include the old url and descr files (containing the archive URL and package description) in the opam file itself: (see the new synopsis: and description: fields, and the url {} file section)
  • Building tests and documentation should now be part of the main build: instructions, using the {test} and {doc} filters. The build-test: and build-doc: fields are still supported.
  • It is now possible to use opam variables within dependencies, for example depends: [ "foo" {= version} ], for a dependency to package foo at the same version as the package being defined, or depends: [ "bar" {os = "linux"} ] for a dependency that only applies on Linux.
  • The new conflict-class: field allows mutual conflicts among a set of packages to be declared. Useful, for example, when there are many concurrent, incompatible implementations.
  • The ocaml-version: field has been deprecated for a long time and is no longer accepted. This should now be a dependency on the ocaml package
  • Three types of checksums are now accepted: you should use md5=<hex-value>, sha256=<hex-value> or sha512=<hex-value>. We'll be gradually deprecating md5 in favour of the more secure algorithms; multiple checksums are allowed
  • Patches supplied in the patches: field must apply with patch -p1
  • The new setenv: field allows packages to export updates to environment variables;
  • Custom fields x-foo: can be used for extensions and external tools
  • """ delimiters allow unescaped strings
  • & has now the customary higher precedence than | in formulas
  • Installed files are now automatically tracked meaning that the remove: field is usually no longer required.

The full, up-to-date specification of the format can be browsed in the manual.

Repository format

In the official, default repository, and also when migrating repositories from older format versions, there are:

  • A virtual ocaml package, that depends on any implementation of the OCaml compiler. This is what packages should depend on, and the version is the corresponding base OCaml version (e.g. 4.04.0 for the 4.04.0+fp compiler). It also defines various configuration variables, see opam config list ocaml.
  • Three mutually-exclusive packages providing actual implementations of the OCaml toolchain:
    • ocaml-base-compiler is the official releases
    • ocaml-variants.<base-version>+<variant-name> contains all the other variants
    • ocaml-system-compiler maps to a compiler installed on the system outside of opam

The layout is otherwise the same, apart from:

  • The compilers/ directory is ignored
  • A repo file should be present, containing at least the line opam-version: "2.0"
  • The indexes for serving over HTTP have been simplified, and urls.txt is no longer needed. See opam admin index --help
  • The archives/ directory is no longer used. The cache now uses a different format and is configured through the repo file, defaulting to cache/ on the same server. See opam admin cache --help

Feedback

Thanks for trying out the beta! Please let us have feedback, preferably to the opam tracker; other options include the opam-devel list and #opam IRC channel on Freenode.

opam-lib 1.3

The package for opam-lib version 1.3 has just been released in the official opam repository. There is no release of opam with version 1.3, but this is an intermediate version of the library that retains compatibility of the file formats with 1.2.2.

The purpose of this release is twofold:

  • provide some fixes and enhancements over opam-lib 1.2.2. For example, 1.3 has an enhanced lint function
  • be a step towards migration to opam-lib 2.0.

This version is compatible with the current stable release of opam (1.2.2), but dependencies have been updated so that you are not (e.g.) stuck on an old version of ocamlgraph.

Therefore, I encourage all maintainers of tools based on opam-lib to migrate to 1.3.

The respective APIs are available in HTML for 1.2 and 1.3.

A note on plugins: when you write opam-related tools, remember that by setting flags: plugin in their definition and installing a binary named opam-toolname, you will enable the users to install package toolname and run your tool with a single opam toolname command.

Architectural changes

If you need to migrate from 1.2 to 1.3, these tips may help:

  • there are now 6 different ocamlfind sub-libraries instead of just 4: format contains the handlers for opam types and file formats, has been split out from the core library, while state handles the state of a given opam root and switch and has been split from the client library.

  • OpamMisc is gone and moved into the better organised OpamStd, with submodules for String, List, etc.

  • OpamGlobals is gone too, and its contents have been moved to:

    • OpamConsole for the printing, logging, and shell interface handling part
    • OpamXxxConfig modules for each of the libraries for handling the global configuration variables. You should call the respective init functions, with the options you want to set, for proper initialisation of the lib options (and handling the OPAMXXX environment variables)
  • OpamPath.Repository is now OpamRepositoryPath, and part of the repository sub-library.

opam-lib 2.0 ?

The development version of the opam-lib (2.0~alpha5 as of writing) is already available on opam. The name has been changed to provide a finer granularity, so it can actually be installed concurrently -- but be careful not to confuse the ocamlfind package names (opam-lib.format for 1.3 vs opam-format for 2.0).

The provided packages are:

  • opam-file-format: now separated from the opam source tree, this has no dependencies and can be used to parse and print the raw opam syntax.
  • opam-core: the basic toolbox used by opam, which actually doesn't include the opam specific part. Includes a tiny extra stdlib, the engine for running a graph of processes in parallel, some system handling functions, etc. Depends on ocamlgraph and re only.
  • opam-format: defines opam data types and their file i/o functions. Depends just on the two above.
  • opam-solver: opam's interface with the dose3 library and external solvers.
  • opam-repository: fetching repositories and package sources from all handled remote types.
  • opam-state: handling of the opam states, at the global, repository and switch levels.
  • opam-client: the client library, providing the top-level operations (installing packages...), and CLI.
  • opam-devel: this packages the development version of the opam tool itself, for bootstrapping. You can install it safely as it doesn't install the new opam in the PATH.

The new API can be also be browsed ; please get in touch if you have trouble migrating.

We are pleased to announce a preview release for opam 2.0, with over 700 patches since 1.2.2. Version 2.0~alpha4 has just been released, and is ready to be more widely tested.

This version brings many new features and changes, the most notable one being that OCaml compiler packages are no longer special entities, and are replaced by standard package definition files. This in turn means that opam users have more flexibility in how switches are managed, including for managing non-OCaml environments such as Coq using the same familiar tools.

A Few Highlights

This is just a sample, see the full changelog for more:

  • Sandboxed builds: Command wrappers can be configured to, for example, restrict permissions of the build and install processes using Linux namespaces, or run the builds within Docker containers.

  • Compilers as packages: This brings many advantages for opam workflows, such as being able to upgrade the compiler in a given switch, better tooling for local compilers, and the possibility to define coq as a compiler or even use opam as a generic shell scripting engine with dependency tracking.

  • Local switches: Create switches within your projects for easier management. Simply run opam switch create <directory> <compiler> to get started.

  • Inplace build: Use opam to build directly from your source directory. Ensure the package is pinned locally then run opam install --inplace-build.

  • Automatic file tracking:: opam now tracks the files installed by packages and is able to cleanly remove them when no existing files were modified. The remove: field is now optional as a result.

  • Configuration file: This can be used to direct choices at opam init automatically (e.g. specific repositories, wrappers, variables, fetch commands, or the external solver). This can be used to override all of opam's OCaml-related settings.

  • Simpler library: the OCaml API is completely rewritten and should make it much easier to write external tools and plugins. Existing tools will need to be ported.

  • Better error mitigation: Through clever ordering of the shell actions and separation of build and install, most build failures can keep your current installation intact, not resulting in removed packages anymore.

Roll out

You are very welcome to try out the alpha, and report any issues. The repository at opam.ocaml.org will remain in 1.2 format (with a 2.0 mirror at opam.ocaml.org/2.0~dev in sync) until after the release is out, which means the extensions can not be used there yet, but you are welcome to test on local or custom repositories, or package pinnings. The reverse translation (2.0 to 1.2) is planned, to keep supporting 1.2 installations after that date.

The documentation for the new version is available at https://opam.ocaml.org/doc/2.0/. This is still work in progress, so please do ask if anything is unclear.

Interface changes

Commands opam switch and opam list have been rehauled for more consistency and flexibility: the former won't implicitly create new switches unless called with the create subcommand, and opam list now allows to combine filters and finely specify the output format. They may not be fully backwards compatible, so please check your scripts.

Most other commands have also seen fixes or improvements. For example, opam doesn't forget about your set of installed packages on the first error, and the new opam install --restore can be used to reinstall your selection after a failed upgrade.

Repository changes

While users of opam 1.2 should feel at home with the changes, the 2.0 repository and package formats are not compatible. Indeed, the move of the compilers to standard packages implies some conversions, and updates to the relationships between packages and their compiler. For example, package constraints like

available: [ ocaml-version >= "4.02" ]

are now written as normal package dependencies:

depends: [ "ocaml" {>= "4.02"} ]

To make the transition easier,

  • upgrade of a custom repository is simply a matter of running opam-admin upgrade-format at its root;
  • the official repository at opam.ocaml.org already has a 2.0 mirror, to which you will be automatically redirected;
  • packages definition are automatically converted when you pin a package.

Note that the ocaml package on the official repository is actually a wrapper that depends on one of ocaml-base-compiler, ocaml-system or ocaml-variants, which contain the different flavours of the actual compiler. It is expected that it may only get picked up when requested by package dependencies.

Package format changes

The opam package definition format is very similar to before, but there are quite a few extensions and some changes:

  • it is now mandatory to separate the build: and install: steps (this allows tracking of installed files, better error recovery, and some optional security features);
  • the url and description can now optionally be included in the opam file using the section url {} and fields synopsis: and description:;
  • it is now possible to have dependencies toggled by globally-defined opam variables (e.g. for a dependency needed on some OS only), or even rely on the package information (e.g. have a dependency at the same version);
  • the new setenv: field allows packages to export updates to environment variables;
  • custom fields x-foo: can be used for extensions and external tools;
  • allow """ delimiters around unescaped strings
  • & is now parsed with higher priority than |
  • field ocaml-version: can no longer be used
  • the remove: field should not be used anymore for simple cases (just removing files)

Let's go then -- how to try it ?

First, be aware that you'll be prompted to update your ~/.opam to 2.0 format before anything else, so if you value it, make a backup. Or just export OPAMROOT to test the alpha on a temporary opam root.

Packages for opam 2.0 are already in the opam repository, so if you have a working opam installation of opam (at least 1.2.1), you can bootstrap as easily as:

opam install opam-devel

This doesn't install the new opam to your PATH within the current opam root for obvious reasons, so you can manually install it as e.g. "opam2" using:

sudo cp $(opam config var "opam-devel:lib")/opam /usr/local/bin/opam2

You can otherwise install as usual:

  • Using pre-built binaries (available for OSX and Linux x86, x86_64, armhf) and our install script:

    wget https://raw.github.com/ocaml/opam/2.0-alpha4-devel/shell/opam_installer.sh -O - | sh -s /usr/local/bin

    Equivalently, pick your version and download it to your PATH;

  • Building from our inclusive source tarball: download here and build using ./configure && make lib-ext && make && make install if you have OCaml >= 4.01 already available, make cold && make install otherwise;

  • Or from source, following the included instructions from the README. Some files have been moved around, so if your build fails after you updated an existing git clone, try to clean it up (git clean -fdx).

OPAM 1.2.2 has just been released. This fixes a few issues over 1.2.1 and brings a couple of improvements, in particular better use of the solver to keep the installation as up-to-date as possible even when the latest version of a package can not be installed.

Upgrade from 1.2.1 (or earlier)

See the normal installation instructions: you should generally pick up the packages from the same origin as you did for the last version -- possibly switching from the official repository packages to the ones we provide for your distribution, in case the former are lagging behind.

There are no changes in repository format, and you can roll back to earlier versions in the 1.2 branch if needed.

Improvements

  • Conflict messages now report the original version constraints without translation, and they have been made more concise in some cases
  • Some new opam lint checks, opam lint now numbers its warnings and may provide script-friendly output
  • Feature to automatically install plugins, e.g. opam depext will prompt to install depext if available and not already installed
  • Priority to newer versions even when the latest can't be installed (with a recent solver only. Before, all non-latest versions were equivalent to the solver)
  • Added opam list --resolve to list a consistent installation scenario
  • Be cool by default on errors in OPAM files, these don't concern end-users and packagers and CI now have opam lint to check them.

Fixes

  • OSX: state cache got broken in 1.2.1, which could induce longer startup times. This is now fixed
  • opam config report has been fixed to report the external solver properly
  • --dry-run --verbose properly outputs all commands that would be run again
  • Providing a simple path to an aspcud executable as external solver (through options or environment) works again, for backwards-compatibility
  • Fixed a fd leak on solver calls (thanks Ivan Gotovchits)
  • opam list now returns 0 when no packages match but no pattern was supplied, which is more helpful in scripts relying on it to check dependencies.

OPAM 1.2.1 has just been released. This patch version brings a number of fixes and improvements over 1.2.0, without breaking compatibility.

Upgrade from 1.2.0 (or earlier)

See the normal installation instructions: you should generally pick up the packages from the same origin as you did for the last version -- possibly switching from the official repository packages to the ones we provide for your distribution, in case the former are lagging behind.

What's new

No huge new features in this point release -- which means you can roll back to 1.2.0 in case of problems -- but lots going on under the hood, and quite a few visible changes nonetheless:

  • The engine that processes package builds and other commands in parallel has been rewritten. You'll notice the cool new display but it's also much more reliable and efficient. Make sure to set jobs: to a value greater than 1 in ~/.opam/config in case you updated from an older version.
  • The install/upgrade/downgrade/remove/reinstall actions are also processed in a better way: the consequences of a failed actions are minimised, when it used to abort the full command.
  • When using version control to pin a package to a local directory without specifying a branch, only the tracked files are used by OPAM, but their changes don't need to be checked in. This was found to be the most convenient compromise.
  • Sources used for several OPAM packages may use <name>.opam files for package pinning. URLs of the form git+ssh:// or hg+https:// are now allowed.
  • opam lint has been vastly improved.

... and much more

There is also a new manual documenting the file and repository formats.

Fixes

See the changelog for a summary or closed issues in the bug-tracker for an overview.

Experimental features

These are mostly improvements to the file formats. You are welcome to use them, but they won't be accepted into the official repository until the next release.

  • New field features: in opam files, to help with ./configure scripts and documenting the specific features enabled in a given build. See the original proposal and the section in the new manual
  • The "filter" language in opam files is now well defined, and documented in the manual. In particular, undefined variables are consistently handled, as well as conversions between string and boolean values, with new syntax for converting bools to strings.
  • New package flag "verbose" in opam files, that outputs the package's build script to stdout
  • New field libexec: in <name>.install files, to install into the package's lib dir with the execution bit set.
  • Compilers can now be defined without source nor build instructions, and the base packages defined in the packages: field are now resolved and then locked. In practice, this means that repository maintainers can move the compiler itself to a package, giving a lot more flexibility.

We are very proud to announce the availability of OPAM 1.2.0.

Upgrade from 1.1

Simply follow the usual instructions, using your preferred method (package from your distribution, binary, source, etc.) as documented on the homepage.

NOTE: There are small changes to the internal repository format (~/.opam). It will be transparently updated on first run, but in case you might want to go back and have anything precious there, you're advised to back it up.

Usability

Lot of work has been put into providing a cleaner interface, with helpful behaviour and messages in case of errors.

The documentation pages also have been largely rewritten for consistency and clarity.

New features

This is just the top of the list:

  • A extended and versatile opam pin command. See the Simplified packaging workflow
  • More expressive queries, see for example opam source
  • New metadata fields, including source repositories, bug-trackers, and finer control of package behaviour
  • An opam lint command to check the quality of packages

For more detail, see the announcement for the beta, the full changelog, and the bug-tracker.

Package format

The package format has been extended to the benefit of both packagers and users. The repository already accepts packages in the 1.2 format, and this won't affect 1.1 users as a rewrite is done on the server for compatibility with 1.1.

If you are hosting a repository, you may be interested in these administration scripts to quickly take advantage of the new features or retain compatibility.

Most package managers support some pin functionality to ensure that a given package remains at a particular version without being upgraded. The stable OPAM 1.1 already supported this by allowing any existing package to be pinned to a target, which could be a specific released version, a local filesystem path, or a remote version-controlled repository.

However, the OPAM 1.1 pinning workflow only lets you pin packages that already exist in your OPAM repositories. To declare a new package, you had to go through creating a local repository, registering it in OPAM, and adding your package definition there. That workflow, while reasonably clear, required the user to know about the repository format and the configuration of an internal repository in OPAM before actually getting to writing a package. Besides, you were on your own for writing the package definition, and the edit-test loop wasn't as friendly as it could have been.

A natural, simpler workflow emerged from allowing users to pin new package names that don't yet exist in an OPAM repository:

  1. choose a name for your new package
  2. opam pin add in the development source tree
  3. the package is created on-the-fly and registered locally.

To make it even easier, OPAM can now interactively help you write the package definition, and you can test your updates with a single command. This blog post explains this new OPAM 1.2 functionality in more detail; you may also want to check out the new Packaging tutorial relying on this workflow.

From source to package

For illustration purposes in this post I'll use a tiny tool that I wrote some time ago and never released: ocp-reloc. It's a simple binary that fixes up the headers of OCaml bytecode files to make them relocatable, which I'd like to release into the public OPAM repository.

"opam pin add"

The command opam pin add <name> <target> pins package <name> to <target>. We're interested in pinning the ocp-reloc package name to the project's source directory.

cd ocp-reloc
opam pin add ocp-reloc .

If ocp-reloc were an existing package, the metadata would be fetched from the package description in the OPAM repositories. Since the package doesn't yet exist, OPAM 1.2 will instead prompt for on-the-fly creation:

Package ocp-reloc does not exist, create as a NEW package ? [Y/n] y
ocp-reloc is now path-pinned to ~/src/ocp-reloc

NOTE: if you are using beta4, you may get a version-control-pin instead, because we added auto-detection of version-controlled repos. This turned out to be confusing (issue #1582), because your changes wouldn't be reflected until you commit, so this has been reverted in favor of a warning. Add the --kind path option to make sure that you get a path-pin.

OPAM Package Template

Now your package still needs some kind of definition for OPAM to acknowledge it; that's where templates kick in, the above triggering an editor with a pre-filled opam file that you just have to complete. This not only saves time in looking up the documentation, it also helps getting consistent package definitions, reduces errors, and promotes filling in optional but recommended fields (homepage, etc.).

opam-version: "1.2"
name: "ocp-reloc"
version: "0.1"
maintainer: "Louis Gesbert <louis.gesbert@ocamlpro.com>"
authors: "Louis Gesbert <louis.gesbert@ocamlpro.com>"
homepage: ""
bug-reports: ""
license: ""
build: [
  ["./configure" "--prefix=%{prefix}%"]
  [make]
]
install: [make "install"]
remove: ["ocamlfind" "remove" "ocp-reloc"]
depends: "ocamlfind" {build}

After adding some details (most importantly the dependencies and build instructions), I can just save and exit. Much like other system tools such as visudo, it checks for syntax errors immediately:

[ERROR] File "/home/lg/.opam/4.01.0/overlay/ocp-reloc/opam", line 13, character 35-36: '.' is not a valid token.
Errors in /home/lg/.opam/4.01.0/overlay/ocp-reloc/opam, retry editing ? [Y/n]

Installation

You probably want to try your brand new package right away, so OPAM's default action is to try and install it (unless you specified -n):

ocp-reloc needs to be installed.
The following actions will be performed:
 - install   cmdliner.0.9.5                        [required by ocp-reloc]
 - install   ocp-reloc.0.1*
=== 1 to install ===
Do you want to continue ? [Y/n]

I usually don't get it working the first time around, but opam pin edit ocp-reloc and opam install ocp-reloc -v can be used to edit and retry until it does.

Package Updates

How do you keep working on your project as you edit the source code, now that you are installing through OPAM? This is as simple as:

opam upgrade ocp-reloc

This will pick up changes from your source repository and reinstall any packages that are dependent on ocp-reloc as well, if any.

So far, we've been dealing with the metadata locally used by your OPAM installation, but you'll probably want to share this among developers of your project even if you're not releasing anything yet. OPAM takes care of this by prompting you to save the opam file back to your source tree, where you can commit it directly into your code repository.

cd ocp-reloc
git add opam
git commit -m 'Add OPAM metadata'
git push

Publishing your New Package

The above information is sufficient to use OPAM locally to integrate new code into an OPAM installation. Let's look at how other developers can share this metadata.

Picking up your development package

If another developer wants to pick up ocp-reloc, they can directly use your existing metadata by cloning a copy of your repository and issuing their own pin.

git clone git://github.com/OCamlPro/ocp-reloc.git
opam pin add ocp-reloc/

Even specifying the package name is optional since this is documented in ocp-reloc/opam. They can start hacking, and if needed use opam pin edit to amend the opam file too. No need for a repository, no need to share anything more than a versioned opam file within your project.

Cloning already existing packages

We have been focusing on an unreleased package, but the same functionality is also of great help in handling existing packages, whether you need to quickly hack into them or are just curious. Let's consider how to modify the omd Markdown library.

opam source omd --pin
cd omd.0.9.7
...patch...
opam upgrade omd

The new opam source command will clone the source code of the library you specify, and the --pin option will also pin it locally to ensure it is used in preference to all other versions. This will also take care of recompiling any installed packages that are dependent on omd using your patched version so that you notice any issues right away.

There's a new OPAM field available in 1.2 called dev-repo. If you specify this in your metadata, you can directly pin to the upstream repository via opam source --dev-repo --pin.

If the upstream repository for the package contains an opam file, that file will be picked up in preference to the one from the OPAM repository as soon as you pin the package. The idea is to have:

  • a development opam file that is versioned along with your source code (and thus accurately tracks the latest dependencies for your package).
  • a release opam file that is published on the OPAM repository and can be updated independently without making a new release of the source code.

How to get from the former to the latter will be the subject of another post! In the meantime, all users of the beta are welcome to share their experience and thoughts on the new workflow on the bug tracker.

It has only been 18 months since the first release of OPAM, but it is already difficult to remember a time when we did OCaml development without it. OPAM has helped bring together much of the open-source code in the OCaml community under a single umbrella, making it easier to discover, depend on, and maintain OCaml applications and libraries. We have seen steady growth in the number of new packages, updates to existing code, and a diverse group of contributors.

OPAM has turned out to be more than just another package manager. It is also increasingly central to the demanding workflow of industrial OCaml development, since it supports multiple simultaneous (patched) compiler installations, sophisticated package version constraints that ensure statically-typed code can be recompiled without conflict, and a distributed workflow that integrates seamlessly with Git, Mercurial or Darcs version control. OPAM tracks multiple revisions of a single package, thereby letting packages rely on older interfaces if they need to for long-term support. It also supports multiple package repositories, letting users blend the global stable package set with their internal revisions, or building completely isolated package universes for closed-source products.

Since its initial release, we have been learning from the extensive feedback from our users about how they use these features as part of their day-to-day workflows. Larger projects like XenAPI, the Ocsigen web suite, and the Mirage OS publish OPAM remotes that build their particular software suites. Complex applications such as the Pfff static analysis tool and Hack language from Facebook, the Frenetic SDN language and the Arakoon distributed key store have all appeared alongside these libraries. Jane Street pushes regular releases of their production Core/Async suite every couple of weeks.

One pleasant side-effect of the growing package database has been the contribution of tools from the community that make the day-to-day use of OCaml easier. These include the utop interactive toplevel, the IOCaml browser notebook, and the Merlin IDE extension. While these tools are an essential first step, there's still some distance to go to make the OCaml development experience feel fully integrated and polished.

Today, we are kicking off the next phase of evolution of OPAM and starting the journey towards building an OCaml Platform that combines the OCaml compiler toolchain with a coherent workflow for build, documentation, testing and IDE integration. As always with OPAM, this effort has been a collaborative effort, coordinated by the OCaml Labs group in Cambridge and OCamlPro in France. The OCaml Platform builds heavily on OPAM, since it forms the substrate that pulls together the tools and facilitates a consistent development workflow. We've therefore created this blog on opam.ocaml.org to chart its progress, announce major milestones, and eventually become a community repository of all significant activity.

Major points:

  • OPAM 1.2 beta available: Firstly, we're announcing the availability of the OPAM 1.2 beta, which includes a number of new features, hundreds of bug fixes, and pretty new colours in the CLI. We really need your feedback to ensure a polished release, so please do read the release notes below.

  • In the coming weeks, we will provide an overview of what the OCaml Platform is (and is not), and describe an example workflow that the Platform can enable.

  • Feedback: If you have questions or comments as you read these posts, then please do join the platform@lists.ocaml.org and make them known to us.

Releasing the OPAM 1.2 beta4

We are proud to announce the latest beta of OPAM 1.2. It comes packed with new features, stability and usability improvements. Here the highlights.

Binary RPMs and DEBs!

We now have binary packages available for Fedora 19/20, CentOS 6/7, RHEL7, Debian Wheezy and Ubuntu! You can see the full set at the OpenSUSE Builder site and download instructions for your particular platform.

An OPAM binary installation doesn't need OCaml to be installed on the system, so you can initialize a fresh, modern version of OCaml on older systems without needing it to be packaged there. On CentOS 6 for example:

cd /etc/yum.repos.d/
wget http://download.opensuse.org/repositories/home:ocaml/CentOS_6/home:ocaml.repo
yum install opam
opam init --comp=4.01.0

Simpler user workflow

For this version, we focused on improving the user interface and workflow. OPAM is a complex piece of software that needs to handle complex development situations. This implies things might go wrong, which is precisely when good support and error messages are essential. OPAM 1.2 has much improved stability and error handling: fewer errors and more helpful messages plus better state backups when they happen.

In particular, a clear and meaningful explanation is extracted from the solver whenever you are attempting an impossible action (unavailable package, conflicts, etc.):

$ opam install mirage-www=0.3.0
The following dependencies couldn't be met:
  - mirage-www -> cstruct < 0.6.0
  - mirage-www -> mirage-fs >= 0.4.0 -> cstruct >= 0.6.0
Your request can't be satisfied:
  - Conflicting version constraints for cstruct

This sets OPAM ahead of many other package managers in terms of user-friendliness. Since this is made possible using the tools from irill (which are also used for Debian), we hope that this work will find its way into other package managers. The extra analyses in the package solver interface are used to improve the health of the central package repository, via the OPAM Weather service.

And in case stuff does go wrong, we added the opam upgrade --fixup command that will get you back to the closest clean state.

The command-line interface is also more detailed and convenient, polishing and documenting the rough areas. Just run opam <subcommand> --help to see the manual page for the below features.

  • More expressive queries based on dependencies.

    $ opam list --depends-on cow --rec
    # Available packages recursively depending on cow.0.10.0 for 4.01.0:
    cowabloga   0.0.7  Simple static blogging support.
    iocaml      0.4.4  A webserver for iocaml-kernel and iocamljs-kernel.
    mirage-www  1.2.0  Mirage website (written in Mirage)
    opam2web    1.3.1 (pinned)  A tool to generate a website from an OPAM repository
    opium       0.9.1  Sinatra like web toolkit based on Async + Cohttp
    stone       0.3.2  Simple static website generator, useful for a portfolio or documentation pages
    
  • Check on existing opam files to base new packages from.

    $ opam show cow --raw
    opam-version: "1"
    name: "cow"
    version: "0.10.0"
    [...]
    
  • Clone the source code for any OPAM package to modify or browse the interfaces.

    $ opam source cow
    Downloading archive of cow.0.10.0...
    [...]
    $ cd cow.0.10.0
    

We've also improved the general speed of the tool to cope with the much bigger size of the central repository, which will be of importance for people building on low-power ARM machines, and added a mechanism that will let you install newer releases of OPAM directly from OPAM if you choose so.

Yet more control for the packagers

Packaging new libraries has been made as straight-forward as possible. Here is a quick overview, you may also want to check the OPAM 1.2 pinning post.

opam pin add <name> <sourcedir>

will generate a new package on the fly by detecting the presence of an opam file within the source repository itself. We'll do a followup post next week with more details of this extended opam pin workflow.

The package description format has also been extended with some new fields:

  • bug-reports: and dev-repo: add useful URLs
  • install: allows build and install commands to be split,
  • flags: is an entry point for several extensions that can affect your package.

Packagers can limit dependencies in scope by adding one of the keywords build, test or doc in front of their constraints:

depends: [
  "ocamlfind" {build & >= 1.4.0}
  "ounit" {test}
]

Here you don't specifically require ocamlfind at runtime, so changing it won't trigger recompilation of your package. ounit is marked as only required for the package's build-test: target, i.e. when installing with opam install -t. This will reduce the amount of (re)compilation required in day-to-day use.

We've also made optional dependencies more consistent by removing version constraints from the depopts: field: their meaning was unclear and confusing. The conflicts field is used to indicate versions of the optional dependencies that are incompatible with your package to remove all ambiguity:

depopts: [ "async" {>= "109.15.00"} & "async_ssl" {>= "111.06.00"} ]

becomes:

depopts: [ "async" "async_ssl" ]
conflicts: [ "async" {< "109.15.00"}
             "async_ssl" {< "111.06.00"} ]

There is an upcoming features field that will give more flexibility in a clearer and consistent way for such complex cases.

Easier to package and install

Efforts were made on the build of OPAM itself as well to make it as easy as possible to compile, bootstrap or install. There is no more dependency on camlp4 (which has been moved out of the core distribution in OCaml 4.02.0), and the build process is more conventional (get the source, run ./configure, make lib-ext to get the few internal dependencies, make and make install). Packagers can use make cold to build OPAM with a locally compiled version of OCaml (useful for platforms where it isn't packaged), and also use make download-ext to store all the external archives within the source tree (for automated builds which forbid external net access).

The whole documentation has been rewritten as well, to be better focused and easier to browse. Please leave any feedback or changes on the documentation on the issue tracker.

Try it out !

The public beta of OPAM 1.2 is just out. You're welcome to give it a try and give us feedback before we roll out the release!

We'd be most interested on feedback on how easily you can work with the new pinning features, on how the new metadata works for you... and on any errors you may trigger that aren't followed by informative messages or clean behaviour.

If you are hosting a repository, the administration scripts may help you quickly update all your packages to benefit from the new features.

If you want to contribute to a new release announcement, check out the Contributing Guide on GitHub.