****************
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"] {dev}
      ["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's 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, etc., 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 3.7)
   (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.
