****************
OPAM integration
****************

opam_ is the official package manager for OCaml, and dune offers some
integration with it.

Invocation from opam
====================

You should set the ``build:`` field of your ``<package>.opam`` file as
follows:

::

    build: [
      ["dune" "subst"] {pinned}
      ["dune" "build" "-p" name "-j" jobs]
    ]

``-p pkg`` is a shorthand for ``--root . --only-packages pkg --profile
release --default-target @install``. ``-p`` is the short version of
``--for-release-of-packages``.

This has the following effects:

-  it tells dune to build everything that is installable and to
   ignore packages other than ``name`` defined in your project
-  it sets the root to prevent dune from looking it up
-  it silently ignores all rules with ``(mode promote)``
-  it sets the build profile to ``release``
-  it uses whatever concurrency option opam provides
-  it sets the default target to ``@install`` rather than ``@@default``

Note that ``name`` and ``jobs`` are variables expanded by opam. ``name`` expands
to the package name and ``jobs`` to the number of jobs available to build the
package.

Tests
-----

To setup the building and running of tests in opam, add this line to your
``<package>.opam`` file:

::

    build: [
      (* Previous lines here... *)
      ["dune" "runtest" "-p" name "-j" jobs] {with-test}
    ]

.. _opam-files:

<package>.opam files
====================

When a ``<package>.opam`` file is present, dune will know that the
package named ``<package>`` exists. It will know how to construct a
``<package>.install`` file in the same directory to handle installation
via `opam <https://opam.ocaml.org/>`__. Dune also defines the
recursive ``install`` alias, which depends on all the buildable
``<package>.install`` files in the workspace. So for instance to build
everything that is installable in a workspace, run at the root:

::

    $ dune build @install

Declaring a package this way will allow you to add elements such as libraries,
executables, documentation, ... to your package by declaring them in ``dune``
files.

Such elements can only be declared in the scope defined by the
corresponding ``<package>.opam`` file. Typically, your
``<package>.opam`` files should be at the root of your project, since
this is where ``opam pin ...`` will look for them.

Note that ``<package>`` must be non-empty, so in particular ``.opam``
files are ignored.

.. _opam-generation:

Generating opam files
=====================

dune will generate ``.opam`` files if the ``dune-project`` file

- sets ``(generate_opam_files true)``, and
- declares one or more packages as per, :ref:`declaring-a-package`.

Here's a complete example of a ``dune-project`` file with opam metadata. This
configuration will tell ``dune`` to generate two opam files: ``cohttp.opam`` and
``cohttp-async.opam``. (See )

.. code:: scheme

   (lang dune 2.9)
   (name cohttp)
   ; version field is optional
   (version 1.0.0)

   (generate_opam_files true)

   (source (github mirage/ocaml-cohttp))
   (license ISC)
   (authors "Anil Madhavapeddy" "Rudi Grinberg")
   (maintainers "team@mirage.org")

   (package
    (name cohttp)
    (synopsis "An OCaml library for HTTP clients and servers")
    (description "A longer description")
    (depends
     (alcotest :with-test)
     (dune (> 1.5))
     (foo (and :dev (> 1.5) (< 2.0)))
     (uri (>= 1.9.0))
     (uri (< 2.0.0))
     (fieldslib (> v0.12))
     (fieldslib (< v0.13))))

   (package
    (name cohttp-async)
    ; optional version override to allow single package point
    ; releases.
    (version 1.0.1)
    (synopsis "HTTP client and server for the Async library")
    (description "A _really_ long description")
    (depends
     (cohttp (>= 1.0.2))
     (conduit-async (>= 1.0.3))
     (async (>= v0.10.0))
     (async (< v0.12))))

Opam template
-------------

A user may want to manually fill in some field in the opam file. In these
situations, dune provides an escape hatch in the form of a user written opam
template. An opam template must be named ``<package>.opam.template`` and should
be a syntactically valid opam file. Any field defined in this template file will
be taken as is by dune and never overwritten.

*Note* the template file cannot be generated by a rule and must be available in
the source tree.

.. _opam: https://opam.ocaml.org/

Odig conventions
================

Dune follows the `odig <http://erratique.ch/software/odig>`__
conventions and automatically installs any README\*, CHANGE\*, HISTORY\*
and LICENSE\* files in the same directory as the ``<package>.opam`` file
to a location where odig will find them.

Note that this includes files present in the source tree as well as
generated files. So for instance a changelog generated by a user rule
will be automatically installed as well.
