\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}}

\title{
OPAM: A Package Management System for OCaml\\
Developer Manual (version 1.1)\\ ~\ \\
~\ \\}
\author{Thomas GAZAGNAIRE\\
\url{thomas.gazagnaire@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
  eventual 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:

{\small
\begin{Verbatim}[frame=single]
<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:

{\small
\begin{Verbatim}[frame=single]
<file> :=
    opam-version: "1"
    repositories: [ STRING+ ]
    switch: STRING
    cores: INT
\end{Verbatim}
}

The field {\tt opam-version} indicates the current \OPAM\ format.

The field {\tt repositories} contains the list of \OPAM\ repositories.

The field {\tt switch} corresponds to the current compiler instance.

The field {\tt cores} is the number of parallel process that
\OPAM\ will use when trying to build the packages.

\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:

{\small
\begin{Verbatim}[frame=single]
<file> :=
    opam-version: "1"
    ?name:          STRING
    ?version:       STRING
    maintainer:     STRING
    ?homepage:      STRING
    ?authors:       [ STRING+ ]
    ?doc:           STRING
    ?license:       STRING
    ?tags:          [ STRING+ ]
    ?subst:         [ STRING+ ]
    ?patches:       [ (STRING ?{ <filter> } )+ ]
    ?build:         commands
    ?build-doc:     commands
    ?build-test:    commands
    ?remove:        commands
    ?depends:       [ <and-formula(package)>+ ]
    ?depopts:       [ <or-formula(package)>+ ]
    ?depexts:       [ [[STRING+] [STRING+]]+ ]
    ?conflicts:     [ <package>+ ]
    ?messages:      [ (STRING ?{ <filter> } )+ ]
    ?post-messages: [ (STRING ?{ <filter> } )+ ]
    ?available:     [ <filter> ]
    ?os:            [ <formula(os)>+ ]
    ?ocaml-version: [ <and-formula(constraint)>+ ]
    ?libraries:     [ STRING+ ]
    ?syntax:        [ STRING+ ]

<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)> )
                  | <x>

<package>        := STRING
                  | STRING { <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 The first line specifies the \OPAM\ version.

\item The content of {\tt name} is \verb+$NAME+, the content of {\tt
  version} is \verb+$VERSION+. Both fields are optional are they can
  be inferred from the filename.

\item The content of {\tt maintainer} is the contact address of the
  package maintainer.

\item The {\tt license}, {\tt homepage} {\tt doc} and {\tt authors}
  fields are optional. {\tt doc} should be the address of the online
  documentation for the package.

\item The {\tt tags} field is optional contains a list of tags to
  classify the package.

\item The content of {\tt subst} is the list of files to substitute
  variable (see \S\ref{file:subst} for the file format and
  \S\ref{section:config} for the semantic of file substitution).

\item The content of {\tt patches} is a list of patches to be applied.
  Substitutions happen before patch application, so patches can
  contain strings which will substituted.

\item The content of {\tt build} is the list of commands to run in
  order to build the package libraries. The build script should build
  all the libraries and syntax extensions exported by the package and
  it should produce the platform-specific configuration and install
  files (e.g. \verb+$NAME.config+ and \verb+$NAME.install+, see
  \S\ref{file:config} and \S\ref{file:install}).

   Each command and command argument is substituted (see
   \S\ref{file:subst} and \S\ref{section:config}, with the identifier
   {\tt X} being equivalent to the string {\tt "\%\{X\}\%"})
   and can be followed by an optional filter, whose evaluation will
   result in the command (or the command argument) being executed
   or not. Filter expressions are typed and must evaluate to a
   boolean and binary operations apply to version strings.

   A typical example is OS-related filters, where we can choose
   to execute commands depending on the current OS:

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

\item {\tt build-doc} is optional and describes how the documentation
  is built.

\item {\tt build-test} is optional and describes how the tests are
  built and run.

\item The content of {\tt remove} is the command to run before deleting
  the installed file.

\item The {\tt depends}, {\tt depopts} and {\tt conflicts} fields
  contain formulas over package names, optionally parametrized by
  version constraints. Some examples or package formula:

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

{\tt depends} is an {\em AND} formula, which means that top-level
\verb+&+ are not mandatory. For instance,
 \verb+ "foo" {<= "1.2"} ("bar" | "gna" {= "3.14"})+ has the following
 semantic:  ``{\em both any version of package
  {\tt "foo"} lesser or equal to $1.2$ and either any version of package
  {\tt "bar"} or the version $3.14$ of package {\tt "gna"}.}''  \\

The {\tt depopts} field contains a {\em OR} formula over
  package names, which means that top-level \verb+|+ are not
  mandatory. This field express optional dependencies that
  \OPAM\ will not try to install. However, when installing a new
  package it will check if it is an optional dependency of already
  installed packages. If it is the case, it will re-install the
  packages (and their transitive forward-dependency closure).

\item The {\tt depexts} field is optional and contains tags describing the
  external dependencies. It contains pairs of lists of the form
  \verb+[ [predicates] [ext-packages] ]+. The predicates are tags that must be
  specified to {\tt opam install}'s {\tt --external} flag to get the
  corresponding external package set. Tags should normally be distribution or
  architecture names (e.g. \verb+"debian"+, \verb+"x86"+, in which case the
  \verb+ext-package+ list will correspond to {\tt apt-get} package names).

\item The {\tt messages} field (since version $1.0.1$) is used to
  display an alternative 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 The {\tt post-messages} field (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 The {\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 The {\tt libraries} and {\tt syntax} fields contain the
  libraries and syntax extensions defined by the package. See
  Section~\ref{section:config} for more details.

\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}[frame=single]
<file> :=
    ?src:       STRING
    ?archive:   STRING
    ?http:      STRING
    ?local:     STRING
    ?git:       STRING
    ?darcs:     STRING
    ?hg:        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:

\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}.
\end{itemize}

\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/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
    camomille      --  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 eventual 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.$VERSION/|.

\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 et 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 explicitely 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.$VERSION/+ contains overlay
  files for the version \verb+$VERSION+ of 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:

{\small
\begin{Verbatim}[frame=single]
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}[frame=single]
<file> :=
    opam-version: "1"
    name:       STRING
    ?src:       STRING
    ?archive:   STRING
    ?http:      STRING
    ?local:     STRING
    ?git:       STRING
    ?darcs:     STRING
    ?hg:        STRING
    ?make:      STRING+ ]
    ?build:     [[STRING+]]
    ?patches:   [ STRING+ ]
    ?configure: [ STRING+ ]
    ?bytecomp:  [ STRING+ ]
    ?asmcomp:   [ STRING+ ]
    ?bytelink:  [ STRING+ ]
    ?asmlink:   [ STRING+ ]
    ?packages:  <cnf-formula>
    ?requires:  [ STRING+ ]
    ?pp:        [ <ppflag>+ ]
    ?preinstalled: BOOL
    ?env:       [ <env>+ ]

<ppflag> := CAMLP4 { STRING+ }
          | STRING+

<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 bytecomp}, {\tt asmcomp}, {\tt bytelink} and {\tt asmlink}
  are the compilation and linking flags to pass to the OCaml
  compiler. They will be taken into account by the \verb+opam config+
  command (see \S\ref{opam-config}).

\item {\tt packages} is the list of packages to install just after the
  compiler installation finished. These libraries will not consider
  what is in the {\tt requires} nor {\tt pp} (as {\tt requires} and
  {\tt pp} might want to use things already installed with {\tt
    packages}).

\item {\tt requires} is a list of libraries and syntax extensions
  dependencies which will be added to every packages installed with
  this compiler. The libraries and syntax extensions should be present
  in packages defined in {\tt packages}, otherwise an error should be
  thrown.

\item {\tt pp} is the command to use with the {\tt -pp} command-line
  argument. It is either a full command line or a {\tt camlp4} command,
  such as \verb+CAMLP4 [ "pp-trace" ]+: this will look for the
  compilation flags for the syntax extension \verb+"pp-trace"+ and expand
  the {\tt camlp4} command-line accordingly. All the syntax extensions used
  should be present in {\tt packages}.

\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"
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"
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:

{\small
\begin{Verbatim}[frame=single]
<file> :=
    ?lib:      [ <mv>+ ]
    ?bin:      [ <mv>+ ]
    ?sbin:     [ <mv>+ ]
    ?toplevel: [ <mv>+ ]
    ?share:    [ <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 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 etc} are copied into \verb+$opam/$SWITCH/etc/$NAME/+.
\item Files listed under {\tt toplevel} are copied into \verb+$opam/$SWITCH/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/man3+. You can change the sub-directory by setting
  the right optional argument (for instance:
  \verb+man: [ "foo.1" {"man1"} ]+.
\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 start 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.

\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:

{\small
\begin{Verbatim}[frame=single]
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{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}

\subsubsection{Package configuration files: {\tt *.config}}
\label{file:dotconfig}

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

{\small
\begin{Verbatim}[frame=single]
<file>    := <item>*
<item>    := <def> | <section>
<section> :=
    <kind> STRING {
      ?asmcomp:  [ STRING+ ]
      ?bytecomp: [ STRING+ ]
      ?asmlink : [ STRING+ ]
      ?bytelink: [ STRING+ ]
      ?requires: [ STRING+ ]
      <def>*
    }
<kind>    := library | syntax
<def>     := IDENT: BOOL
           | IDENT: STRING
           | IDENT: [ STRING+ ]
\end{Verbatim}
}

\verb+$NAME.config+ contains platform-dependent information which can
be useful for other libraries or syntax extensions that want to use
libraries defined in the package \verb+$NAME+.

\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 \verb+%{$NAME.$LIB:$VAR}%+ will refer to the variable \verb+$VAR+
  defined in the {\tt library} or {\tt syntax} section named
  \verb+$LIB+ in the configuration file \verb+$opam/$SWITCH/config/$NAME.config+.

\end{itemize}

\paragraph{Library and syntax sections}

Each {\tt library} and {\tt syntax} section defines an OCaml library
and the specific compilation flags to enable when using and linking
with this library.

The distinction between libraries and syntax extensions is only useful
at compile time to know whether the options should be used as
compilation or pre-processing arguments (ie. should they go on the
compiler command line or should they be passed to the {\tt -pp}
option). This is the responsibility of the build tool to do the right
thing and the {\tt <kind>} of sections is only used for documentation
purposes in \OPAM. \\

The available options are:

\begin{itemize}
\item {\tt asmcomp} are compilation options to give to the native
  compiler (when using the {\tt -c} option)
\item {\tt bytecomp} are compilation options to give to the bytecode
  compiler (when using the {\tt -c} option)
\item {\tt asmlink} are linking options to give to the native compiler
\item {\tt bytlink} are linking options to give to the bytecode
  compiler
\item {\tt requires} is the list of libraries and syntax extensions
  the current block is depending on. The full list of compilation
  and linking options is built by looking at the transitive closure of
  dependencies. The contents of {\tt dep}s is the list of libraries or
  syntax extension the current section depends on. Note that we do not
  refer here to any package name, as multiple packages can expose libraries
  with the same name and interface and thus we want the user to be able
  to switch between them easily.
\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+
    $ opam config [-R] include  $NAME+
    $ opam config [-R] bytecomp $NAME.$LIB+
    $ opam config [-R] asmcomp  $NAME.$LIB+
    $ opam config [-R] bytelink $NAME.$LIB+
    $ opam config [-R] asmlink  $NAME.$LIB+
\end{verbatim}

\begin{itemize}
\item \verb+list+ will return the list of all variables defined
  in installed packages (see \S\ref{file:dotconfig})
\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+.
\item \verb+includes $NAME+ will return the list of paths to include when
  compiling a project using the package \verb+$NAME+ (\verb+-R+ gives
  a result taking into account the transitive closure of
  dependencies).
\item \verb+bytecomp+, \verb+asmcomp+, \verb+bytelink+ and
  \verb+asmlink+ return the associated value for the section
  \verb+$LIB+ in the file \verb+$opam/$SWITCH/config/$NAME.config+ (\verb+-R+ gives
  a result taking into account the transitive closure of all
  dependencies).
\end{itemize}


\end{document}
