Jan
17
2013

OPAM is a source-based package manager for OCaml. It supports multiple simultaneous compiler installations, flexible package constraints, and a Git-friendly development workflow. I have recently announced the beta-release of OPAM on the caml-list, and this blog post introduces the basics to new OPAM users.

Why OPAM

We have decided to start writing a brand new package manager for OCaml in the beginning of 2012, after looking at the state of affairs in the OCaml community and not being completely satisfied with the existing solutions, especially regarding the management of dependency constraints between packages. Existing technologies such as GODI, oasis, odb and ocamlbrew did contain lots of good ideas that we shamelessly stole but the final user-experience was not so great -- and we disagreed with some of the architectural choices, so it wasn't so easy to contribute to fix the existing flaws. Thus we started to discuss the specification of a new package manager with folks from Jane Street who decided to fund the project and from the Mancoosi project to integrate state-of-the-art dependency management technologies. We then hired an engineer to do the initial prototyping work -- and this effort finally gave birth to OPAM!

Installing OPAM

OPAM packages are already available for homebrew, macports and arch-linux. Debian and Ubuntu packages should be available quite soon. In any cases, you can either use a binary installer or simply install it from sources. To learn more about the installation process, read the installation instructions.

Initializing OPAM

Once you've installed OPAM, you have to initialize it. OPAM will store all its state under ~/.opam, so if you want to reset your OPAM configuration, simply remove that directory and restart from scratch. OPAM can either use the compiler installed on your system or it can also install a fresh version of the compiler:

opam init                # Use the system compiler
opam init --comp 4.00.1  # Use OCaml 4.00.1

OPAM will prompt you to add a shell script fragment to your .profile. It is highly recommended to follow these instructions, as it let OPAM set-up correctly the environment variables it needs to compile and configure the packages.

Getting help

OPAM user manual is integrated:

opam --help       # Get help on OPAM itself
opam init --help  # Get help on the init sub-command

Basic commands

Once OPAM is initialized, you can ask it to list the available packages, get package information and search for a given pattern in package descriptions:

opam list *foo* # list all the package containing 'foo' in their name
opam info foo   # Give more information on the 'foo' package
opam search foo # search for the string 'foo' in all package descriptions

Once you've found a package you would like to install, just run the usual install command.

opam install lwt # install lwt and its dependencies
opam remove lwt  # remove lwt and its dependencies

Later on, you can check whether new packages are available and you can upgrade your package installation.

opam update  # check if new packages are available
opam upgrade # upgrade your packages to the latest version

Casual users of OCaml won't need to know more about OPAM. Simply remind to update and upgrade OPAM regularly to keep your system up-to-date.

Use-case 1: Managing Multiple Compilers

A new release of OCaml is available and you want to be able to use it. How to do this in OPAM ? This is as simple as:

opam update        # pick-up the latest compiler descriptions
opam switch 4.00.2 # switch to the new 4.00.2 release
opam switch export --switch=system | opam switch import -y

The first line will get the latest package and compiler descriptions, and will tell you if new packages or new compilers are available. Supposing that 4.00.2 is now available, you can then switch to that version using the second command. The last command imports all the packages installed by OPAM for the OCaml compiler installed on your system (if any).

You can also easily use the latest unstable version of OCaml if you want to give it a try:

opam switch 4.01.0dev+trunk            # install trunk
opam switch reinstall 4.01.0dev+trunk  # reinstall trunk

Reinstalling trunk means getting the latest changesets and recompiling the packages already installed for that compiler switch.

Use-case 2: Managing Multiple Repositories

Sometimes, you want to let people use a new version of your software early. Or you are working in a company and expose internal libraries to your coworkers but you don't want them to be available to anybody using OPAM. How can you do that with OPAM? It's easy! You can set-up your own repository (see for instance xen-org's development packages) and add it to your OPAM configuration:

opam repository list  # list the repositories available in your config
opam repository add xen-org git://github.com/xen-org/opam-repo-dev.git
opam repository list  # new xen-org repository available

This will add the repository to your OPAM configuration and it will display the newly available packages. The next time you run opam update OPAM will then scan for any change in the remote git repository.

Repositories can either be local (e.g. on your filesystem), remote (available through HTTP) and stored in git or darcs.

Use-case 3: Using Development Packages

You want to try the latest version of a package which have not yet been released, or you have a patched version of a package than you want to try. How could you do it? OPAM has a pin sub-command which let you do that easily:

opam pin lwt /local/path/
opam install lwt          # install the version of lwt stored in /local/path

You can also use a given branch in a given git repository. For instance, if you want the library re to be compiled with the code in the experimental branch of its development repository you can do:

opam pin re git://github.com/ocaml/ocaml-re.git#experimental
opam install re

When building the packages, OPAM will use the path set-up with the pin command instead of using the upstream archives. Also, on the next update, OPAM will automatically check whether some changes happened and if the packages needs to be recompiled:

opam update lwt     # check for changes in /local/path
opam update re      # check for change in the remote git branch
opam upgrade lwt re # upgrade re and lwt if necessary

Conclusion

I've briefly explained some of the main features of OPAM. If you want to go further, I would advise to read the user and packager tutorials. If you really want to understand the internals of OPAM, you can also read the developer manual.