\documentclass[a4paper,10pt]{article}

\usepackage{url}
\usepackage{eurosym}
%\usepackage[french]{babel}
\usepackage[T1]{fontenc}
\usepackage{pdfswitch}
\usepackage{verbatim}
\usepackage{fullpage}
\usepackage{fancyvrb}

\newenvironment{remark}[1][Remark]{\begin{trivlist}
\item[\hskip \labelsep {\bfseries #1}]}{\end{trivlist}}
\RecustomVerbatimEnvironment{Verbatim}{Verbatim}{fontsize=\small,frame=single}

\title{
OPAM: A Package Management System for OCaml\\
Developer Manual (version 1.2.1)\\ ~\ \\
~\ \\}
\author{Thomas GAZAGNAIRE\\
\url{thomas@gazagnaire.org}\\
Louis GESBERT\\
\url{louis.gesbert@ocamlpro.com}\\
}


\begin{document}

\newcommand{\OPAM}{{\sc Opam}}

\maketitle

\vfill

\tableofcontents

\section*{Overview}

\OPAM\ is a source-based package manager for OCaml. It supports multiple
simultaneous compiler installations, flexible package constraints, and
a Git-friendly development work-flow.\\

A package management system has typically two kinds of users: {\em
  end-users} who install and use packages for their own projects; and
{\em packagers}, who create and upload packages. End-users want to
install on their machine a consistent collection of {\em packages} --
a package being a collection of OCaml libraries and/or programs.
Packagers want to take a collection of their own libraries and
programs and make them available to other developpers.\\

This document describes the design of \OPAM\ to answer both of these needs.

\subsection*{Conventions}

In this document, \verb+$home+, \verb+$opam+, and
\verb+$path+ are assumed to be defined as follows:

\begin{itemize}

\item {\tt \$home} refers to the end-user home path, typically {\tt
  /home/thomas/} on linux and {\tt /Users/thomas/} on OSX.
%  {\tt
%  C:\textbackslash Documents and Settings\textbackslash
%  thomas\textbackslash} on Windows.

\item {\tt \$opam} refers to the filesystem subtree containing the
  client state. Default directory is {\tt \$home/.opam}.

\item {\tt \$path} refers to a list of paths in the packager filesystem, where
  lives the collection of programs ({\tt ocamlc}, {\tt ocamldep}, {\tt ocamlopt},
  {\tt ocamlbuild}, ...).

\end{itemize}

User variables are written in capital letters, prefixed by \verb+$+. For
instance package names will be written \verb+$NAME+, package versions
\verb+$VERSION+, and the version of the ocaml compiler currently
installed \verb+$SWITCH+.\\

This document is organized as follows: Section~\ref{section:packages}
describes the core of \OPAM, e.g. the management of
packages. Section~\ref{section:repositories} describes how
repositories are handled, Section~\ref{section:switches} focus on
compiler switches and finally Section~\ref{section:config} explain how
packages can define configuration variables (which can be later used
by the build system).

\section{Managing Packages}
\label{section:packages}

\subsection{State}

The client state is stored on the filesystem, under {\tt \$opam}.
All the configurations files, libraries and binaries related to a
specific instance of the OCaml compiler in \verb+$opam/$SWITCH+, where
\verb+$SWITCH+ is the name of that specific compiler instance. See
Section~\ref{section:switches} for more details about compiler
switches.

\begin{itemize}

\item {\tt \$opam/config} is the main configuration file. It defines
  the version of \OPAM, the repository addresses and the current compiler
  version. The file format is described in \S\ref{file:config}.

\item \verb+$opam/packages/$NAME/$NAME.$VERSION/opam+ is the
  specification for the package \verb+$NAME+ with version
  \verb+$VERSION+ (which might not be installed). The format of {\tt opam}
  files is described in \S\ref{file:opam}.

\item \verb+$opam/packages/$NAME/$NAME.$VERSION/descr+ contains the
  description for the version \verb+$VERSION+ of package \verb+$NAME+
  (which might not be installed). The first line of this file is the
  package synopsis.

\item \verb+$opam/packages/$NAME/$NAME.$VERSION/url+ contains the
  upstream location for version \verb+$VERSION+ of package \verb+$NAME+
  (which might not be installed). The format of {\tt url} files is
  described in \S\ref{file:url}.

\item \verb+$opam/packages/$NAME/$NAME.$VERSION/files/+ contains the
  optional overlay files on top of the upstream sources, for version
  \verb+$VERSION+ of package \verb+$NAME+ (which might not be
  installed). This files are copied in the build directory before
  building and installing a package.

\item \verb+$opam/archives/$NAME.$VERSION+opam.tar.gz+ contains the source
  archives for the version \verb+$VERSION+ of package
  \verb+$NAME+. This archive might be a bit different from the
  upstream library as it might have been repackaged by \OPAM\ to include
  the evenutal overlay files.

\item \verb+$opam/packages.dev.+ contains cached information for
  development packages. \OPAM\ uses it on update to check which
  package needs to be upgraded.

\end{itemize}

\subsection{Files}

\subsubsection{General Syntax of Structured Files}
\label{file:general}

Most of the files in the client and server states share the same
syntax defined in this section.

\begin{description}

\item[Comments] Two kinds of comments are available: the usual
  \verb+(* ... *)+ OCaml comment blocks and also \verb+#+ which
  discard everything until the end of the current line.

\item[Base types] The base types for values are:

\begin{itemize}
\item {\tt BOOL} is  either {\tt true} or {\tt false}
\item {\tt STRING} is a doubly-quoted OCaml string, for instance: {\tt
  "foo"}, {\tt "foo-bar"}, $\ldots$
\item {\tt SYMBOL} contains only non-letter and non-digit characters,
  for instance: {\tt =}, {\tt <=}, $\ldots$ Some symbols have a special
  meaning and thus are not valid {\tt SYMBOL}s: ``\verb+(+ \verb+)+
  \verb+[+ \verb+]+ \verb+{+ \verb+}+ \verb+:+''.
\item {\tt IDENT} starts with a letter and is followed by any number of
  letters, digit and symbols, for instance: {\tt foo}, {\tt foo-bar},
  $\ldots$.
\end{itemize}


\item[Compound types] Types can be composed together to build more
  complex values:

\begin{itemize}
\item {\tt X Y } is a space-separated pair of value.
\item {\tt X | Y } is a value of type either {\tt X} or {\tt Y}.
\item {\tt ?X} is zero or one occurrence of a value of type {\tt X}.
\item {\tt X+} is a space-separated list of values of at least one value
  of type {\tt X}.
\item {\tt X*} is a space-separated list of values of values of type
  {\tt X} (it might contain no value).
\end{itemize}

\end{description}

All structured files share the same syntax:

\begin{Verbatim}
<file>  := <item>*

<item>  := IDENT : <value>
         | ?IDENT: <value>
         | IDENT STRING { <item>+ }

<value> := BOOL
         | INT
         | STRING
         | SYMBOL
         | IDENT
         | [ <value>+ ]
         | value { <value>+ }
\end{Verbatim}

\subsubsection{Global Configuration File: {\tt config}}
\label{file:config}

\verb+$opam/config+ follows the syntax defined in \S\ref{file:general} with
the following restrictions:

\begin{Verbatim}
<file> :=
    opam-version: "1.2"
    repositories: [ STRING+ ]
    switch: STRING
    ?jobs: INT
    ?solver: <single-command>
    ?solver-criteria: STRING
    ?solver-upgrade-criteria: STRING
    ?solver-fixup-criteria: STRING
    ?download-command: <single-command>
    ?download-jobs: INT

<single-command> := [ (<argument> ?{ <filter> })+ ]
\end{Verbatim}

\begin{itemize}
\item {\tt opam-version} indicates the current \OPAM\ repository format --
  normally corresponding to the \OPAM\ minor version (\verb+MAJOR.MINOR+)
\item {\tt repositories} contains the names of the currently configured
  repositories.
\item {\tt switch} is the name of the currently active \OPAM\ switch.
\item {\tt jobs} is the maximum number of build processes that can be run
  simultaneously.
\item {\tt solver} is the external solver to call. The value may be either the
  single identifiers \verb+aspcud+ or \verb+packup+, which have built-in
  support, or a command. The string variables \verb+input+, \verb+output+ and
  \verb+criteria+ (only) are defined when evaluating this field.
\item {\tt solver-criteria}, {\tt solver-upgrade-criteria} and {\tt
    solver-fixup-criteria} are the optimisation criteria provided to the solver
  resp. in the default case (install requested packages at their latest version,
  minimising the impact on other packages), for global upgrades (minimise
  outdated packages) and for fixup (resolve dependencies while minimising
  changes).
\item {\tt download-command} will be called to fetch remote files over http(s)
  or ftp. The value may be either the single identifiers \verb+curl+ or
  \verb+wget+, which have built-in support, or a custom command. Only the
  special variables \verb+url+, \verb+out+, \verb+retries+ (strings) and
  \verb+compress+ (bool) can be used in this field.
\item {\tt download-jobs} is the maximum number of simultaneous downloads (all
  remote hosts included)
\end{itemize}

\subsubsection{Package Specification files: {\tt opam}}
\label{file:opam}

\verb+$opam/packages/$NAME/$NAME.$VERSION/opam+ follows the syntax defined in
\S\ref{file:general} with the following restrictions:

\begin{Verbatim}
<file> :=
    opam-version: "1.2"
    ?name:          STRING
    ?version:       STRING
    maintainer:     STRING
    ?authors:       [ STRING+ ]
    ?license:       STRING
    ?homepage:      STRING
    ?doc:           STRING
    ?bug-reports:   STRING
    ?dev-repo:      STRING
    ?tags:          [ STRING+ ]
    ?patches:       [ (STRING ?{ <filter> } )+ ]
    ?subst:         [ STRING+ ]
    ?build:         commands
    ?install:       commands
    ?build-doc:     commands
    ?build-test:    commands
    ?remove:        commands
    ?depends:       [ <and-formula(package-with-flags)> ]
    ?depopts:       [ (STRING ?{ <flags> })+ ]
    ?conflicts:     [ <package>+ ]
    ?depexts:       [ [[STRING+] [STRING+]]+ ]
    ?messages:      [ (STRING ?{ <filter> } )+ ]
    ?post-messages: [ (STRING ?{ <filter> } )+ ]
    ?available:     [ <filter> ]
    ?os:            [ <formula(os)>+ ]
    ?ocaml-version: [ <and-formula(constraint)>+ ]
    ?libraries:     [ STRING+ ]
    ?syntax:        [ STRING+ ]
    ?flags:         [ IDENT+ ]
    ?features:      [ (IDENT STRING <filter>)+ ]

<argument>       := STRING
                  | IDENT

<command>        := [ (<argument> ?{ <filter> })+ ] ?{ <filter> }

<commands>       := <command>
                  | [ <command>+ ]

<filter>         := <argument>
                  | !<argument>
                  | <argument> <comp> <argument>
                  | formula(<filter>)

<formula(x)>     := <formula(x)> '&' <formula(x)>
                  | <formula(x)> '|' <formula(x)>
                  | ( <formula(x)> )
                  | !<formula(x)>
                  | <x>

<package>        := STRING
                  | STRING { <and-formula(constraint)> }

<flags>          := IDENT
                  | IDENT '&' <flags>

<package-with-flags>
                 := STRING
                  | STRING { <flags> }
                  | STRING { ?(<flags> '&') <and-formula(constraint)> }

<constraint>     := <comp> STRING
<comp>           := '=' | '<' | '>' | '>=' | '<=' | '!='

<and-formula(x)> := <x> <and-formula(x)>
                  | <formula(x)>

<or-formula(x)>  := <x> <or-formula(x)>
                  | <package(x)>

<os>             := STRING
                  | '!' STRING
\end{Verbatim}

\begin{itemize}

\item {\tt opam-version} specifies the file format version, it should be the
  current \OPAM\ version in the format {\tt MAJOR.MINOR} (\emph{i.e.} with patch
  version omitted)

\item {\tt name}, {\tt version} contain resp. \verb+$NAME+ and \verb+$VERSION+,
  specifying the package. Both fields are optional when they can be inferred
  from the directory name (\emph{e.g.} when the file sits in the repository).

\item {\tt maintainer} is a mandatory contact address for the package maintainer
  (the format {\tt "name <email>"} is allowed).

\item {\tt authors} is a list of strings listing the original authors of the
  software.

\item {\tt license} is the abbreviated name of the license under which the
  source software is available.

\item {\tt homepage}, {\tt doc}, {\tt bug-reports} are URLs pointing to the
  related pages for the package.

\item {\tt dev-repo} is the URL of the package's source repository, which may be
  useful for developpers: not to be mistaken with the URL file, which points to
  the specific packaged version. It is typically a version-control address, and
  follows the format allowed for {\tt TARGET} by {\tt opam pin add}. You can use
  an address of the form {\tt vcs+scheme://xxx} to specify the version control
  system to use, {\em e.g.} {\tt git+ssh://address} or {\tt hg+https://address}.
  (Note: this has been added in OPAM 1.2.1)

\item {\tt tags} contains an optional list of semantic tags used to classify the
  packages. The {\tt "org:foo"} tag is reserved for packages officially
  distributed by organization ``foo''.

\item {\tt patches} is a list of files relative to the project source root
  (often added through the {\tt files/} metadata subdirectory). The listed patch
  files will be applied sequentially to the source like with the {\tt patch}
  command, after having gone through {\em variable interpolation expansion} like
  files listed in {\tt subst}. Patches may be applied conditionally by adding
  {\em filters}.

\item {\tt subst} contains a list of files relative to the project source root.
  Variable interpolations will be expanded on these files before the build takes
  place (see \S\ref{file:subst} for the file format and \S\ref{section:config}
  for the semantic of file substitution).

\item {\tt build} is the list of commands that will be run in order to compile
  the package. Any command is allowed, but these should write exclusively to the
  package's source directory (given as {\tt CWD} to the command), be
  non-interactive and perform no network i/o. All libraries, syntax extensions,
  binaries, platform-specific configuration and install files
  (\verb+$NAME.config+ and \verb+$NAME.install+, see \S\ref{file:config} and
  \S\ref{file:install}) should be produced within the source directory subtree
  during this step. Each command is provided as a list of terms (a command and
  zero or more arguments) ; individual terms as well as full commands can be
  made conditional by adding {\em filters}: they will be ignored if the {\em
    filter} evaluates to {\tt false} or is undefined.

  Additionally, strings in each term undergo variable expansion: {\tt
    "\%\{foo\}\%"} is replaced by the contents of variable {\tt foo}. Variable
  {\tt foo}, if undefined globally, implicitly refers to the package being
  defined, in the version being defined (while {\tt \$NAME:foo} refers to the
  {\em installed} version of the package). See \S\ref{subsection:variables} and
  the output of the command {\tt opam config list} for a list of predefined
  variables.

  Filters typically refer to the {\tt os} variable, like in the following
  example:

\begin{Verbatim}
build: [
  ["mv" "Makefile.unix"  "Makefile"] {os != "win32"}
  ["mv" "Makefile.win32" "Makefile"] {os  = "win32"}
  [make]
]
\end{Verbatim}

\item {\tt install} follows the exact same format as {\tt build}, but should
  only be used to move products of {\tt build} from the build directory to their
  final destination under the current {\tt prefix}, and adjust some
  configuration files there when needed. Commands in {\tt install} are executed
  sequentially after the build is finished. These commands should only write to
  subdirectories of {\tt prefix}, without altering the source directory itself.

  This field contains typically just {\tt [make "install"]}. It is recommended
  to prefer the usage of a \verb+$NAME.install+ file and omit the {\tt install}
  field.

\item {\tt build-doc} and {\tt build-test} follow the same specification as the
  {\tt build} field. They are processed after the build phase when documentation
  or tests have been requested.

\item {\tt remove} follows the same format as {\tt build}, and is used to
  uninstall the package. It should be the reverse operation of {\tt install},
  and absent when {\tt install} is.

\item {\tt depends} describes the requirements on other packages for this
  package to be built and installed. It contains a list of formulas over package
  names, optionally parametrized by version constraints, e.g.:

  \begin{itemize}
  \item A simple package name: {\tt "foo"};
  \item A package name with version constraints:
    \verb+"foo" {>= "1.2" & <= "3.4"}+
  \end{itemize}

  Elements of the list are implicitely ANDed: \verb+["foo" "bar"]+ is equivalent
  to \verb+["foo" & "bar"]+, and
  \verb+"foo" {<= "1.2"} ("bar" | "gna" {= "3.14"})+ is to be understood as
  ``{\em {\tt "foo"} is required, at a version lesser or equal to $1.2$, as well
    as one of "{\tt bar}" or "{\tt gna}" version $3.14$}''

  Additionally, the version constraints may be prefixed by {\em dependency
    flags}. These are one of \verb+build+, \verb+test+ and \verb+doc+ and limit
  the meaning of the dependency:
  \begin{itemize}
  \item \verb+build+ dependencies are no longer needed at run-time: they won't
    trigger recompilations of your package.
  \item \verb+test+ dependencies are only needed when building tests
    (by instructions in the \verb+build-test+ field)
  \item likewise, \verb+doc+ dependecies are only required when building the
    package documentation
  \end{itemize}
  For example:
\begin{verbatim}
depends: [
  "foo" {build}
  "bar" {build & doc}
  "baz" {build & >= "3.14"}
]
\end{verbatim}

\item {\tt depopts}, for ``optional dependencies'', is similar to {\tt depends}
  in format, with some restrictions. It contains packages that are {\em used},
  if present, by the package being defined, either during build or runtime, but
  that are not {\em required} for its installation. The implementation uses this
  information to define build order and trigger recompilations, but won't
  automatically install {\em depopts} when installing your package.

  The optional dependencies may have {\em dependency flags}, but they may not
  specify version constraints nor formulas. {\tt depopts} can be combined with
  {\tt conflicts} to add version constraints on the optional dependencies. Note
  that this changed in \OPAM\ 1.2: previously these constraints could be put in
  {\tt depopts}. You should now write \verb+depopts: "foo"+,
  \verb+conflicts: "foo" {< "2"}+ rather than \verb+depopts: "foo" {>= "2"}+
  which had a non-obvious meaning.

\item {\tt conflicts} is a list of package names with optional version
  constraints indicating that the current package can't coexist with some
  packages or some specific versions.

\item {\tt depexts}, for ``external dependencies'', is a list that can be used
  for describing the dependencies of the package towards software or packages
  external to the OPAM ecosystem, for various system. It contains pairs of lists
  of the form \verb+[ predicates ext-packages ]+. {\tt predicates} is used to
  select the element of the list based on the current system: it is a list of
  tags (strings) that can correspond to the OS, architecture or distribution.
  The {\tt predicates} is used as a conjunction: the pair will only be selected
  when {\em all} tags are active. The resulting {\tt ext-packages} should be
  identifiers of packages recognised by the system's package manager.

  There is currently no definite specification for the precise tags you should
  use, but the closest thing is the {\em opam-depext} project
  (\url{https://github.com/OCamlPro/opam-depext}). The {\tt depexts} information
  can be retrieved through the {\tt opam list --external} command.

\item {\tt messages} (since version $1.0.1$) is used to
  display an additional (one-line) message when prompting a solution implying
  the given package. The typical use-case is to tell the user that
  some functionality will not be available as some optional
  dependencies are not installed.

\item {\tt post-messages} (since version $1.1.0$) allows to print
  specific messages to the user after the end of installation. The special
  boolean variable \verb+failure+ is defined in the scope of the filter, and can
  be used to print messages in case there was an error (typically, a hint on how
  it can be resolved, or a link to an open issue). \verb+success+ is also
  defined as syntactic sugar for \verb+!failure+.

\item {\tt available} field (since version $1.1.0$) can be used to add
  constraints on the OS and OCaml versions currently in use, using the built-in
  \verb+os+ and \verb+ocaml-version+ variables. In case the filter is not valid,
  the package is disabled. The {\tt os} and {\tt ocaml-version} fields are
  deprecated, please use {\tt available} instead in newly created packages.

\item {\tt libraries} and {\tt syntax} contain the
  libraries and syntax extensions defined by the package. See
  Section~\ref{section:config} for more details.

\item {\tt flags} allow a limited set of idents that give special handling
  instructions for the package:
  \begin{description}
  \item{\tt light-uninstall} the package's uninstall instructions don't require the
    package source. This is currently inferred when the only uninstall
    instructions have the form `ocamlfind remove...`, but making it explicit is
    preferred (since \OPAM\ 1.2.0).
  \item{\tt verbose} when this is present, the stdout of the package's build and
    install instructions will be printed to the user (since \OPAM\ 1.2.1).
  \item{\tt plugin} the package installs a program named \verb+opam-$NAME+. OPAM
    will hand over to it when run with subcommand \verb+$NAME+, automatically
    installing it if necessary (since \OPAM\ 1.2.2).
  \end{description}
  Since some of those wheren't known in \OPAM\ 1.2.0, which will complain about
  them, they shouldn't be used in the 1.2 branch. Using a {\tt flags:foo} {\em
    tag} instead is thus allowed as a compatible way to activate flag {\tt foo}
  on 1.2.x versions.

\item {\tt features} is currently experimental and shouldn't be used on the main
  package repository. It allows to define custom variables that better document
  what {\em features} are available in a given package build. Each feature is
  defined as an identifier, a documentation string, and a filter expression. The
  filter expression can evaluate to either a boolean or a string, and the
  defined identifier can be used as a variable in any filter (but recursive
  features are not allowed and will return {\tt undefined}).

  This is typically useful to pass appropriate flags to {\tt ./configure}
  scripts, depending on what is installed.
\end{itemize}

\subsubsection{URL files: {\tt url}}
\label{file:url}

The syntax of {\tt url} files follows the one described in
\S\ref{file:general} with the following restrictions:

\begin{Verbatim}
<file> :=
    ?src:       STRING
    ?archive:   STRING
    ?http:      STRING
    ?local:     STRING
    ?git:       STRING
    ?darcs:     STRING
    ?hg:        STRING
    ?mirrors:   [ STRING+ ]
    ?checksum:  STRING
\end{Verbatim}

{\tt src}, {\tt archive}, {\tt http}, {\tt local}, {\tt git}, {\tt
  hg}, {\tt darcs} are the location where the package upstream sources
can be downloaded. It can be one of:

\begin{itemize}
\item A directory on the local file system (which will be copied to
  the build directory). Use {\tt local}.
\item An archive file on the local file system (which will be unpacked
  into the build directory). Use {\tt local}.
\item An archive file at a URL that is understood by either curl or
  wget (which will be fetched using either curl (if that available) or
  wget (if curl is not available) and unpacked into the build
  directory). Use {\tt http}.
\item a version-controlled repository under git, darcs or
  hg, or a specific commit, tag or branch in that repository if
  the string ends by \verb+#<SHA1>+ or \verb+#<tag-name>+ or
  \verb+#<branch-name>+. Use {\tt git}, {\tt hg} or {\tt darcs}.
\item \OPAM\ will try to guess the source kind if you use {\tt src} or
  {\tt archive}. It shouldn't be used for version control systems, for
  which the above are preferred.
\end{itemize}

{\tt mirrors}, if specified, is assumed to be a list of addresses of the same
kind as the primary address. Mirrors will be tried in order in case the download
from the primary upstream fails.

\subsection{Commands}

\subsubsection{Creating a Fresh Client State}
\label{opam-init}

When an end-user starts \OPAM\ for the first time, he needs to
initialize \verb+$opam/+ in a consistent state. In order to do so, he
should run:

\begin{verbatim}
    $ opam init [--kind $KIND] $REPO $ADDRESS [--comp $VERSION]
\end{verbatim}

Where:
\begin{itemize}
\item \verb+$KIND+ is the kind of \OPAM\ repository (default is {\tt
  http});
\item \verb+$REPO+ is the name of the repository (default is {\tt
  default}); and
\item \verb+$ADDRESS+ is the repository address (default is
  \verb+http://opam.ocamlpro.com/pub+).
\item \verb+$COMP+ is the compiler version to use (default is the
  version of the compiler installed on the system).
\end{itemize}

This command will:

\begin{enumerate}

\item Create the file \verb+$opam/config+ (as specified in
  \S\ref{file:config})

\item Create an empty \verb+$opam/$SWITCH/installed+ file,
  \verb+$SWITCH+ %being the result of ``{\tt ocamlc -version}''.
  is the version from the OCaml used to compile \verb+$opam+.
  In particular, we will not fail now
  if there is no \verb+ocamlc+ in \verb+$path+.

\item Initialize \verb+$opam/repo/$REPO+ by running the
  appropriate operations (depending on the repository kind).

\item Copy all \OPAM\ and description files (ie. copy
  every file in \verb+$opam/repo/$REPO/packages/+ to
  \verb+$opam/packages/+).

\item Create \verb+$opam/repo/package-index+ and for each version
  \verb+$VERSION+ of package \verb+$NAME+ appearing in the repository,
  append the line \verb+'$REPO $NAME $VERSION'+ to the file.

\item Create the empty directories \verb+$opam/archives+,
  \verb+$opam/$SWITCH/lib/+, \verb+$opam/$SWITCH/bin/+ and \verb+$opam/$SWITCH/doc/+.

\end{enumerate}

\subsubsection{Listing Packages}
\label{opam-list}

When an end-user wants to have information on all available packages,
he should run:

\begin{verbatim}
    $ opam list
\end{verbatim}

This command will parse \verb+$opam/$SWITCH/installed+ to know the
installed packages, and
\verb+$opam/packages/$NAME/$NAME.$VERSION/opam+ to get all the
available packages. It will then build a summary of each packages. The
description of each package will be read in
\verb+$opam/packages/$NAME/$NAME.$VERSION/descr+ if it exists.

For instance, if {\tt batteries} version {\tt 1.1.3} is installed,
{\tt ounit} version {\tt 2.3+dev} is installed and {\tt camomille} is
not installed, then running the previous command should display:

\begin{verbatim}
    batteries   1.1.3  Batteries is a standard library replacement
    ounit     2.3+dev  Test framework
    camomile       --  Unicode support
\end{verbatim}

\subsubsection{Getting Package Info}

In case the end-user wants a more details view of a specific package,
he should run:

\begin{verbatim}
    $ opam info $NAME
\end{verbatim}

This command will parse \verb+$opam/$SWITCH/installed+ to get the
installed version of \verb+$NAME+, will process
\verb+$opam/repo/index+ to get the repository where the package comes
from and will look for \verb+$opam/packages/$NAME/$NAME.$VERSION/opam+
to get available versions of \verb+$NAME+. It can then display:

\begin{verbatim}
    package: $NAME
    version: $VERSION
    versions: $VERSION1, $VERSION2, ...
    libraries: $LIB1, $LIB2, ...
    syntax: $SYNTAX1, $SYNTAX2, ...
    repository: $REPO
    description:
      $SYNOPSIS

      $LINE1
      $LINE2
      $LINE3
      ...
\end{verbatim}

\subsubsection{Installing a Package}
\label{opam-install}

When an end-user wants to install a new package, he should run:

\begin{verbatim}
    $ opam install $NAME
\end{verbatim}

This command will:

\begin{enumerate}

\item Compute the transitive closure of dependencies and conflicts of
  packages using the dependency solver (see \S\ref{deps}). If the
  dependency solver returns more than one answer, the tool will ask
  the user to pick one, otherwise it will proceed directly. The
  dependency solver should also mark the packages to recompile.

\item The dependency solver sorts the collections of packages in
  topological order. Then, for each of them do:

\begin{enumerate}

\item Check whether the package is already installed by looking for
  the line \verb+$NAME $VERSION+ in \verb+$opam/$SWITCH/installed+.
  If not, then:

\item Look into the archive cache to see whether it has already been
  downloaded. The cache location is:
  \verb+$opam/archives/$NAME.VERSION.tar.gz+

\item If not, process \verb+$opam/repo/index/+ (see
  \ref{section:repositories}) to get the repository
  \verb+$REPO+ where the archive is available and then ask the
  repository to download the archive if necessary.

  Once this is done, the archive might become available in
  \verb+$opam/repo/$REPO/archives/+. It it is, copy it in the global
  state (in \verb+$opam/archives+). If it is not, download it upstream
  by looking at \verb|$opam/packages/$NAME/$NAME.$VERSION/url| and add
  the optional overlay files located in
  \verb|$opam/packages/$NAME/$NAME.$VERSION/files|. Note: this files
  can be overwritten by anything present in
  \verb|$opam/$SWITCH/overlay/$NAME/|.

\item Decompress the archive into \verb+$opam/$SWITCH/build/$NAME.$VERSION/+.

\item Substitute the required files.

\item Run the list of commands to build the package with \verb+$opam/$SWITCH/bin+
  in the path.

\item Process \verb+$opam/$SWITCH/build/$NAME.$VERSION/$NAME.install+ to install
  the created files. The file format is described in \S\ref{file:install}.

\item Install the installation file
  \verb+$opam/$SWITCH/build/$NAME.$VERSION/$NAME.install+ in
  \verb+$opam/$SWITCH/install/+ and the configuration file
  \verb+$opam/$SWITCH/build/$NAME.$VERSION/$NAME.config+ in
  \verb+$opam/$SWITCH/config/+.

\end{enumerate}
\end{enumerate}

\subsubsection{Updating Index Files}
\label{opam-update}

When an end-user wants to know what are the latest packages available,
he will write:

\begin{verbatim}
    $ opam update
\end{verbatim}

This command will follow the following steps:

\begin{itemize}

\item Update each repositories in \verb+$opam/config+.

\item For each repositories in \verb+$opam/config+, call the
  corresponding update scripts. Then, look at the difference between
  the digest of files in the global state and in each repositories,
  and fix the discrepancies (while notifying the user) if necessary.
  Here, the order in which the repositories are specified
  is important: the first repository containing a given version for a
  package will be the one providing it (this can be changed manually
  by editing \verb+$opam/repo/index+ later).

\item For each installed pinned and development packages, look at what
  changed upstream and if something has changed, update
  \verb+$opam/$SWITCH/reinstall+ accordingly (for each compiler
  version \verb+$SWITCH+).

\item Packages in \verb+$opam/$SWITCH/reinstall+ will be reinstalled (or
  upgraded if a new version is available) on the next {\tt opam
    upgrade} (see \S\ref{opam-upgrade}), with \verb+$SWITCH+ being
  the current compiler version when the upgrade command is run.

\end{itemize}

\subsubsection{Upgrading Installed Packages}
\label{opam-upgrade}

When an end-user wants to upgrade the packages installed on his host,
he will write:

\begin{verbatim}
    $ opam upgrade
\end{verbatim}

This command will:

\begin{itemize}

\item Call the dependency solver (see \S\ref{deps}) to
find a consistent state where {\bf most} of the installed packages are
upgraded to their latest version. Moreover, packages listed in
\verb+$opam/$SWITCH/reinstall+ will be reinstalled (or upgraded if a new
version is available). It will install each non-installed packages in
topological order, similar to what it is done during the install step,
See \S\ref{opam-install}.

\item Once this is done the command will delete
  \verb+$opam/$SWITCH/reinstall+.

\end{itemize}
\subsubsection{Removing Packages}
\label{opam-remove}

When the user wants to remove a package, he should write:

\begin{verbatim}
    $ opam remove $NAME
\end{verbatim}

This command will check whether the package \verb+$NAME+ is installed,
and if yes, it will display to the user the list packages that will be
uninstalled (ie. the transitive closure of all forward-dependencies).
If the user accepts the list, all the packages should be uninstalled,
and the client state should be let in a consistent state.

\subsubsection{Dependency Solver}
\label{deps}

Dependency solving is a hard problem and we do not plan to start from
scratch implementing a new SAT solver. Thus our plan to integrate (as
a library) the Debian depency solver for CUDF files, which is written
in OCaml.

\begin{itemize}
\item the dependency solver should run on the client; and
\item the dependency solver should take as input a list of packages
  (with some optional version information) the user wants to install,
  upgrade and remove and it should return a consistent list of
  packages (with version numbers) to install, upgrade, recompile and
  remove.
\end{itemize}

\section{Managing Compiler Switches}
\label{section:switches}

\OPAM\ is able to manage concurrent compiler installations.

\subsection{State}

Compiler descriptions are stored in two files:

\begin{itemize}

\item \verb|$opam/compilers/$VERSION/$VERSION[+$TAG]/comp| contains the meta-data
  for a given compiler.\verb+$VERSION+ is the compiler version and
  \verb+$TAG+ an optional tag (such as \verb|4.01+fp|).
  The format of {\tt .comp} file is described in \ref{file:comp}.

\item (optional) \verb|$opam/compilers/$VERSION/$VERSION[+$TAG]/descr|
  contains the description of that compiler. \verb+$VERSION+ is the
  compiler version and \verb+$TAG+ an optional tag (such as
  \verb|4.01+fp|). The first line of that line is used as synopsis and
  is displayed with {\tt opam repository list}.

\end{itemize}

Switch-related meta-data are stored under \verb+$opam/$SWITCH/+:

\begin{itemize}

\item \verb+$opam/$SWITCH/installed+ is the list of installed
  packages for the compiler instance \verb+$SWITCH+. The file format
  is described in \S\ref{file:installed}.

\item \verb+$opam/$SWITCH/installed.root+ is the list of installed
  packages roots for the compiler instance \verb+$SWITCH+.
  The file format is described in \S\ref{file:installed}. A package
  root has been explicitly installed by the user.

\item \verb+$opam/$SWITCH/config/$NAME.config+ is a
  platform-specific configuration file of for the installed package
  \verb+$NAME+ with the compiler instance \verb+$SWITCH+. The file
  format is described in \S\ref{file:config}.

\item \verb+$opam/$SWITCH/install/$NAME.install+ is a
  platform-specific package installation file for the installed
  package \verb+$NAME+ with the compiler instance \verb+$SWITCH+. The
  file format is described in \S\ref{file:install}.

\item \verb+$opam/$SWITCH/lib/$NAME/+ contains the libraries
  associated to the installed package \verb+$NAME+ with the compiler
  instance \verb+$SWITCH+.

\item \verb+$opam/$SWITCH/doc/$NAME/+ contains the documentation
  associated to the installed package {\tt NAME} with the compiler
  instance \verb+$SWITCH+.

\item \verb+$opam/$SWITCH/bin/+ contains the program files for all
  installed packages with the compiler instance
  \verb+$SWITCH+.

\item \verb+$opam/$SWITCH/build/$NAME.$VERSION/+ is a tempory folder
  used to build package \verb+$NAME+ with version \verb+$VERSION+,
  with compiler instance \verb+$SWITCH+.

\item \verb+$opam/$SWITCH/reinstall+ contains the list of packages
  which has been changed upstream since the last upgrade. This can
  happen for instance when a packager uploads a new archive or fix the
  {\tt opam} file for a specific package version. Every package appearing in
  this file will be reinstalled (or upgraded if a new version is
  available) during the next upgrade when the current instance of the
  compiler is \verb+$SWITCH+. The file format is similar to the one
  described in \S\ref{file:installed}.

\item \verb+$opam/$SWITCH/pinned+ contains the list of pinned
  packages. The file format is described in \S\ref{file:pinned}.

\item \verb+$opam/$SWITCH/overlay/$NAME/+ contains overlay
  files for package \verb+$NAME+, for the
  switch \verb+$SWITCH+. These possible overlay files are {\tt opam}, {\tt
    url}, {\tt descr} or the directory {\tt files/}. If one of this
  file (or directory) is present, the file (or directory) will be used
  instead of the global one.

\item \verb+$opam/$SWITCH/packages.dev+ contains cached information
  for dev and pinned packages. \OPAM\ uses it on update to check which
  package needs to be upgraded.

\end{itemize}

\subsection{Files}

\subsubsection{Package List: {\tt installed} and {\tt reinstall}}
\label{file:installed}

The following configuration files: \verb+$opam/$SWITCH/installed+,
\verb+$opam/$SWITCH/reinstall+, and \verb+$opam/repo/$REPO/updated+
follow a very simple syntax. The file is a list of lines which
contains a space-separated name and a version. Each line
\verb+$NAME $VERSION+ means that the version \verb+$VERSION+ of
package \verb+$NAME+ has been compiled with the compiler instance
\verb+$SWITCH+ and has been installed on the system in
\verb+$opam/$SWITCH/lib/$NAME+ and \verb+$opam/$SWITCH/bin/+. \\

For instance, if {\tt batteries} version {\tt 1.0+beta} and {\tt
  ocamlfind} version {\tt 1.2} are installed, then
\verb+$opam/$SWITCH/installed+ will contain:

\begin{Verbatim}
batteries 1.0+beta
ocamlfind 1.2
\end{Verbatim}

\subsubsection{Compiler Description Files: {\tt comp}}
\label{file:comp}

The syntax of {\tt comp} files follows the one described in
\S\ref{file:general} with the following restrictions:

\begin{Verbatim}
<file> :=
    opam-version: "1.2"
    name:       STRING
    ?src:       STRING
    ?archive:   STRING
    ?http:      STRING
    ?local:     STRING
    ?git:       STRING
    ?darcs:     STRING
    ?hg:        STRING
    ?make:      STRING+ ]
    ?build:     [[STRING+]]
    ?patches:   [ STRING+ ]
    ?configure: [ STRING+ ]
    ?packages:  <package>+
    ?preinstalled: BOOL
    ?env:       [ <env>+ ]

<env>    := IDENT <eq> STRING
<eq>     := '=' | '+=' | '=+' | ':=' | '=:'
\end{Verbatim}
\begin{itemize}

\item {\tt name} is the compiler name, it should be identical to the filename.
\item {\tt src}, {\tt archive}, {\tt http}, {\tt local}, {\tt git},
  {\tt hg}, {\tt darcs} are the location where the compiler sources
  can be downloaded. It can be:

\begin{itemize}
\item A directory on the local file system (which will be linked or,
  if file system doesn't support links, copied to the build
  directory). Use {\tt local}.
\item An archive file on the local file system (which will be unpacked
  into the build directory). Use {\tt local}.
\item An archive file at a URL that is understood by either curl or
  wget (which will be fetched using either curl (if that available) or
  wget (if curl is not available) and unpacked into the build
  directory). Use {\tt http}.
\item a version-controlled repository under git, darcs or
  hg, or a specific commit, tag or branch in that repository if
  the string ends by \verb+#<SHA1>+ or \verb+#<tag-name>+ or
  \verb+#<branch-name>+. Use {\tt git}, {\tt hg} or {\tt darcs}.
\item \OPAM\ will try to guess the source kind if you use {\tt src} or
  {\tt archive}.
\end{itemize}

\item {\tt patches} are optional patch addresses, available via {\tt
  http} or locally on the filesystem.

\item {\tt configure} are the optional flags to pass to the configure
  script. The order is relevant: {\tt --prefix=\$opam/SWITCH/} will be automatically
  added at the end to these options.
  Remark that if these flags contain {\tt --bindir}, {\tt --libdir},
  and {\tt --mandir}, then every {\tt --prefix} will be ignored by {\tt configure}.

\item {\tt make} are the flags to pass to {\tt make}.
  It must at least contain some target like {\tt world} or {\tt
    world.opt}. If {\tt make} is not present, \OPAM\ will execute all
  the commands listed in {\tt build}.

\item {\tt packages} is the list of packages to install just after the
  compiler installation finished.

\item {\tt preinstall} is {\tt true} when the version of the compiler available
  in the path is the same as {\tt name}.

\item {\tt env} is the list of environment variables to set in the
  given compiler switch:
\begin{itemize}
\item {\tt VAR = "value"} set the variable to the given value;
\item {\tt VAR += "value"} prepend the given value to the variable;
\item {\tt VAR =+ "value"} append the given value to the variable;
\item {\tt VAR := "value"} prepend the given value to the variable,
  separated by a colon. If the variable was empty, add the
  colon anyway.
\item {\tt VAR =: "value"} append the given value to the variable,
  separated by a colon. If the variable was empty, add the colon
  anyway.
\end{itemize}
\end{itemize}

For instance the file, {\tt 3.12.1+memprof.comp} describes OCaml,
version $3.12.1$ with the memory profiling patch enabled:

\begin{verbatim}
opam-version: "1.2"
name:         "3.12.1"
src:          "http://caml.inria.fr/pub/distrib/ocaml-3.12/ocaml-3.12.1.tar.gz"
make:         [ "world" "world.opt" ]
patches:      [ "http://bozman.cagdas.free.fr/documents/ocamlmemprof-3.12.0.patch" ]
env:          [ CAML_LD_LIBRARY_PATH = "%{lib}%/stublibs" ]
\end{verbatim}

And the file {\tt trunk-g-notk-byte.comp} describes OCaml from SVN
trunk, with no {\em tk} support and only in bytecode, and all the
libraries built with {\tt -g}:

\begin{verbatim}
opam-version: "1.2"
name:         "trunk-g-notk-byte"
src:          "http://caml.inria.fr/pub/distrib/ocaml-3.12/ocaml-3.12.1.tar.gz"
configure:    [ "-no-tk" ]
make:         [ "world" ]
bytecomp:     [ "-g" ]
bytelink:     [ "-g" ]
env:          [ CAML_LD_LIBRARY_PATH = "%{lib}%/stublibs" ]
\end{verbatim}


\subsubsection{Package installation files: {\tt *.install}}
\label{file:install}

\verb+$opam/$SWITCH/install/NAME.install+ follows the syntax defined
in \S\ref{file:general} with the following restrictions:

\begin{Verbatim}
<file> :=
    ?lib:        [ <mv>+ ]
    ?libexec:    [ <mv>+ ]
    ?bin:        [ <mv>+ ]
    ?sbin:       [ <mv>+ ]
    ?toplevel:   [ <mv>+ ]
    ?share:      [ <mv>+ ]
    ?share_root: [ <mv>+ ]
    ?etc:        [ <mv>+ ]
    ?doc:        [ <mv>+ ]
    ?misc:       [ <mv>+ ]
    ?stublibs:   [ <mv>+ ]
    ?man:        [ <mv>+ ]

<mv> := STRING
      | STRING { STRING }
\end{Verbatim}

\begin{itemize}
\item Files listed under {\tt lib} are copied into \verb+$opam/$SWITCH/lib/$NAME/+.
\item Files listed under {\tt libexec} are copied into \verb+$opam/$SWITCH/lib/$NAME/+, but with execution permission.
\item Files listed under {\tt bin} are copied into \verb+$opam/$SWITCH/bin/+.
\item Files listed under {\tt sbin} are copied into \verb+$opam/$SWITCH/sbin/+.
\item Files listed under {\tt doc} are copied into \verb+$opam/$SWITCH/doc/$NAME/+.
\item Files listed under {\tt share} are copied into \verb+$opam/$SWITCH/share/$NAME/+.
\item Files listed under {\tt share\_root} are copied into \verb+$opam/$SWITCH/share/+.
\item Files listed under {\tt etc} are copied into \verb+$opam/$SWITCH/etc/$NAME/+.
\item Files listed under {\tt toplevel} are copied into \verb+$opam/$SWITCH/lib/toplevel/+.
\item Files lister under {\tt stublibs} are copied into \verb+$opam/$SWITCH/lib/stublibs/+
\item Files listed under {\tt man} are copied into
  \verb+$opam/$SWITCH/man/manN+, where \verb+N+ is taken from the extension of
  the source file if $1\dots8$ (not considering a \verb+.gz+ extension). If the
  destination is explicit, it will be taken relative to
  \verb+$opam/$SWITCH/man+, e.g.
  \verb+man: [ "foo.1" ]+ is equivalent to \verb+man: [ "foo.1" {"man1/foo.1"} ]+
\item Files listed under {\tt misc} are processed as follows:
  for each pair \verb+$SRC { $DST }+, the tool asks the user if
  he wants to install \verb+$SRC+ to the absolute path \verb+$DST+.
\end{itemize}

General remarks:
\begin{itemize}

\item You control where the files are copied under the given prefix by
  using the optional argument. For instance:
  \verb+doc: [ "_build/foo.html" {"foo/index.html"} ]+ will copy the
  given HTML page under \verb+$opam/$SWITCH/doc/$NAME/foo/index.html+.

\item \OPAM\ will try to install all the files in sequence, and it will
  fail in case a source filename is not available. To tell \OPAM\ a
  source filename might not be generated (because of byte/native
  constraints or because of optional dependencies) the source filename
  should be prefixed with \verb+?+.

\item It is much cleaner if the underlying build-system can generate
  the right \verb+$NAME.install+ files, containing the existing files only.

\item File permissions are set to $0644$, except for {\tt libexec}, {\tt bin},
  {\tt sbin}, {\tt stublibs} for which it's $0755$. {\tt umask} may apply.

\item These files can be used for installation outside of the scope of \OPAM
  using the {\tt opam-installer} program shipped with \OPAM .

\end{itemize}

\subsubsection{Pinned Packages: {\tt pinned}}
\label{file:pinned}

\verb+$opam/$SWITCH/pinned+ contains a list of lines of the form:

\begin{Verbatim}
<name> <kind> <path>
\end{Verbatim}

\begin{itemize}
\item \verb+<name>+ is the name of the pinned package

\item \verb+<kind>+ is the kind of pinning. This could be \verb+version+,
\verb+local+, \verb+git+ or \verb+darcs+.

\item \verb+<path>+ is either the version number (if kind is
  \verb+version+) or the path to synchronize with.
\end{itemize}

\subsection{Commands}

\subsubsection{Switching Compiler Version}

If the user wants to switch to another compiler version, he should run:

\begin{verbatim}
    $ opam switch [-alias-of $COMPILER] $SWITCH
\end{verbatim}

This command will:

\begin{itemize}

\item If \verb+$COMPILER+ is not set, set it to \verb+$SWITCH+

\item Look for an existing \verb+$opam/$COMPILER+ directory.

\begin{itemize}
\item If it
  exists, then change the {\tt ocaml-version} content to
  \verb+$COMPILER+ in  \verb+$opam/config+.

\item If it does not exist, look for an existing
  \verb|$opam/compilers/$VERSION/$VERSON[+$TAG]/comp|, where
  \verb|$COMPILER = $VERSION[+TAG]| If the file does not exists, the
  command will fail with a well-defined error.

\item If the file exist, then build the new compiler with the right
  options (and pass \verb+--prefix $opam/$SWITCH+ to
  \verb+./configure+) and initialize everything in \verb+$opam/+
  in a consistent state as if ``\verb+opam init+'' has just been called.

\item Update the file \verb+$opam/aliases+ with the line
  \verb+$SWITCH $COMPILER+

\end{itemize}

\end{itemize}

\section{Managing Repositories}
\label{section:repositories}

\subsection{State}
\label{state-repo}

Configuration files for the remote repository \verb+REPO+ are stored in
\verb+$opam/repo/$REPO+. Repositories can be of different kinds
(stored on the local filesystem, available via HTTP, stored under git,
$\ldots$); they all share the same filesystem hierachy, which is
updated by different operations, depending on the repository kind.

\begin{itemize}

\item \verb+$opam/repo/$REPO/version+ contains the minimum version of
  \OPAM\ which can read that repository meta-data.

\item \verb+$opam/repo/$REPO/config+ contains the configuration
  of the repository \verb+$REPO+.
%  The format of repository config
%  files is described in \S\ref{file:repo-config}.

\item \verb+$opam/repo/$REPO/packages/$PREFIX/$NAME.$VERSION/opam+ is
  the {\tt opam} file for the package \verb+$NAME+ with version
  \verb+$VERSION+ (which might not be installed) with any possible
  \verb+$PREFIX+. The format of {\tt opam} files is described in
  \S\ref{file:opam}.

\item (optional) \verb+$opam/repo/$REPO/packages/$PREFIX/$NAME.$VERSION/descr+
  contains the textual description for the version \verb+$VERSION+ of
  package \verb+$NAME+ (which might not be installed) with any
  possible \verb+$PREFIX+ -- it should be in the same loacation as the
  corresponding {\tt opam} file. The first line of this file is the
  package synopsis.

\item (optional) \verb+$opam/repo/$REPO/packages/$PREFIX/$NAME.$VERSION/url+
  contains the upstream location for the version \verb+$VERSION+ of
  package \verb+$NAME+ (which might not be installed) with any
  possible \verb+$PREFIX+ -- it should be in the same loacation as the
  corresponding {\tt opam} file. The format of {\tt url} files is
  described in \S\ref{file:url}.

\item (optional) \verb+$opam/repo/$REPO/packages/$PREFIX/$NAME.$VERSION/files/+
  contains the overlay files for the version \verb+$VERSION+ of
  package \verb+$NAME+ (which might not be installed) with any
  possible \verb+$PREFIX+ -- it should be in the same loacation as the
  corresponding {\tt opam} file. The overlay files are added to the
  build directory when a package is built and installed.

\item (optional)
  \verb+$opam/repo/$REPO/archives/$NAME.$VERSION.tar.gz+ contains the
  source archives for the version \verb+$VERSION+ of package
  \verb+$NAME+. This folder is populated when a package needs to be
  downloaded and that the given repository expose such a file. If the
  file is not present, \OPAM\ will download the package from the
  upstream sources.

\end{itemize}

\subsection{Files}

\subsubsection{Index of packages}
\label{file:index}

\verb+$opam/repo/index+ follows a very simple syntax: each line of the
file contains a space separated list of words
\verb|$NAME.$VERSION $REPO+| specifying that all the version
\verb+$VERSION+ of package \verb+$NAME+ is available in the remote
repositories \verb|$REPO+|. The file contains information on all
available packages (e.g. not only on the installed one). \\

For instance, if {\tt batteries} version {\tt 1.0+beta} is available
in the {\tt testing} repository and {\tt ocamlfind} version {\tt 1.2}
is available in the {\tt default} and testing repositories (where {\tt
  default} is one being used), then \verb+$opam/repo/index+ will
contain:

\begin{Verbatim}
batteries.1.0+beta testing
ocamlfind.1.2 default testing
\end{Verbatim}

\subsection{Commands}

\subsubsection{Managing Remote Repository}

An user can manage remote repositories, by writing:

\begin{verbatim}
    $ opam repository list # 'opam repository' works as well
    $ opam repository add [--kind $KIND] $REPO $ADRESS
    $ opam repository remove $REPO
\end{verbatim}

\begin{itemize}
\item \verb+list+ lists the current repositories by looking at
  \verb+$opam/config+

\item \verb+add [--kind $KIND] $REPO $ADDRESS+ initializes
  \verb+$REPO+ as described in \S\ref{opam-init}.

\item For distributed version controlled repository, the user can use
  \verb+url#hash+ or \verb+url#name+ where {\tt hash} is a given
  revision name and {\tt name} it the name of a tag or a branch.

\item \verb+remove $REPO+ deletes \verb+$opam/repo/$REPO+ and removes
  \verb+$REPO+ from the {\tt repositories} list in \verb+$opam/config+.
  Then, for each package in \verb+$opam/repo/index+ it updates the link
  between packages and repositories (ie. it either deletes packages or
  symlink them to the new repository containing the package).

\end{itemize}

\section{Managing Configurations}
\label{section:config}

\subsection{State}

\subsection{Variables}
\label{subsection:variables}

Variables can appear in some fields of {\tt opam} files (see \S\ref{file:opam}),
and in substition files (see below). There are three kinds. Note that this list
is often out of date, you should check \verb+opam config list+ for a complete
overview.

\begin{enumerate}
\item Global variables, corresponding to the current configuration
  \begin{itemize}
  \item \verb+opam-version+ the running version of OPAM
  \item \verb+ocaml-version+ the currently used version of OCaml
  \item \verb+switch+ the user-defined name (alias) of the current switch
  \item \verb+compiler+ the full OPAM name of the current OCaml compiler
  \item \verb+preinstalled+ whether the compiler was preinstalled on the system
    or managed by OPAM
  \item \verb+ocaml-native+ whether native compilation is available ({\tt
      ocamlopt})
  \item \verb+ocaml-native-tools+ whether the {\tt .opt} variant of the
    compilers are available ({\bf not} the {\tt ocamlopt} native compiler itself)
  \item \verb+ocaml-native-dynlink+ whether native dynlink is available
  \item \verb+jobs+ the configured number of parallel jobs to run
  \item \verb+arch+ the host architecture, as returned by \verb+uname -m+
  \end{itemize}
\item Package-local variables. Variable \verb+$VAR+ of package \verb+$NAME+ is
  normally accessed using \verb+%{$NAME:$VAR}%+, which can be abbreviated as
  \verb+%{$VAR}%+ within \verb+$NAME+'s own opam file (but global variables take
  precedence, in particular directory names. Check \verb+opam config list+).
  Some are only available from the opam file or when the corresponding package
  is installed.
  \begin{itemize}
  \item \verb+installed+ whether the package is installed
  \item \verb+enable+ same as \verb+installed+, but takes the value
    \verb+"enable"+ or \verb+"disable"+. To be used in configure scripts
  \item \verb+pinned+ whether the package is pinned
  \item \verb+bin+, \verb+sbin+, \verb+lib+, \verb+man+, \verb+doc+,
    \verb+share+, \verb+etc+, the installation directories used by the package
  \item \verb+name+ the name of the package
  \item \verb+version+ the version of the package (the one corresponding to the
    current opam file if relevant, the installed one otherwise)
  \item \verb+build+ the temporary build directory of this package
  \item \verb+depends+ the list of current direct dependencies of this package.
    Optional dependencies are included if they are currently available
  \item \verb+hash+ the md5 of the opam archive of the package, if available.
    For cache mechanisms
  \end{itemize}
  Boolean variables can also be written as \verb!foo+bar:var! as a shortcut to
  \verb!foo:var & bar:var!.
\item User-defined variables, as defined in {\tt *.config} files (see
  \S\ref{file:dotconfig}). This can also be used to override values of the above
  variables.
\end{enumerate}

As an experimental feature in \OPAM\ 1.2.1 ({\em i.e.} not to be used on the
main package repository), converters of boolean variables to strings can be
specified with the following syntax:
\verb+"%{var?string-if-true:string-if-false-or-undefined}%"+. Either string may
be empty.

\subsection{Files}

\subsubsection{Substitution files: {\tt *.in}}
\label{file:subst}

Any file can be processed using generated using a special mode of
{\tt opam} which can perform tests and substitutes variables (see
\S\ref{section:config} for the exact command to run). Substitution files
contains some templates which will be replaced with some contents. The
syntax of templates is the following:

\begin{itemize}

\item templates such as \verb+%{$NAME:$VAR}%+ are replaced by the value
  of the variable \verb+$VAR+ defined at the root of the file
  \verb+$opam/$SWITCH/config/NAME.config+.

\item templates such as \verb+%{$NAME.$LIB:$VAR}%+ are replaced by the
  value of the variable \verb+$VAR+ defined in the \verb+$LIB+ section
  in the file \verb+$opam/$SWITCH/config/$NAME.config+

\end{itemize}

\paragraph{Local and global variables}

The definitions ``{\tt IDENT: BOOL}'', ``{\tt IDENT: STRING}'' and ``{\tt IDENT:
  [ STRING+ ]}'', are used to defined variables associated to this
package, and are used to substitute variables in template files (see
\S\ref{subst}):

\begin{itemize}

\item \verb+%{$NAME:$VAR}%+ will refer to the variable \verb+$VAR+
  defined at the root of the configuration file \verb+$opam/$SWITCH/config/NAME.config+.

\item Run {\tt opam config var} for the full list of available
  variables.

\end{itemize}

\subsection{Commands}

\subsubsection{Getting Package Configuration}
\label{opam-config}

\OPAM\ contains the minimal information to be able to use installed
libraries. In order to do so, the end-user (or the packager) should
run:

\begin{verbatim}
    $ opam config list
    $ opam config var $NAME:$VAR
    $ opam config var $NAME.$LIB:$VAR
    $ opam config subst $FILENAME+
\end{verbatim}

\begin{itemize}
\item \verb+var $var+ will return the value associated to the
  variable \verb+$var+
\item \label{subst}\verb+subst $FILENAME+ replace any occurrence of
  \verb+%{$NAME:$VAR}%+ and \verb+%{$NAME.$LIB:$VAR}%+ as specified in
  \S\ref{file:subst} in \verb+$FILENAME.in+ to create \verb+$FILENAME+.
\end{itemize}


\end{document}
