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

Generating opam files

Dune is able to use metadata specified in the dune-project file to generate .opam files. To enable this integration, add the following field to the dune-project file:

(generate_opam_files true)

Dune uses the following global fields to set the metadata for all packages defined in the project:

  • (license <name>) - Specifies the license of the project, ideally as an identifier from the SPDX License List
  • (authors <authors>) - A list of authors
  • (maintainers <maintainers>) - A list of maintainers
  • (source <source>) - where the source is specified two ways: (github <user/repo>) or (uri <uri>)
  • (bug_reports <url>) - Where to report bugs. This defaults to the GitHub issue tracker if the source is specified as a GitHub repository
  • (homepage <url>) - The homepage of the project
  • (documentation <url>) - Where the documentation is hosted

Package specific information is specified in the (package <package>) stanza. It contains the following fields:

  • (name <string>) is the name of the package. This must be specified.
  • (synopsis <string>) is a short package description
  • (description <string>) is a longer package description
  • (depends <dep-specification>) are package dependencies
  • (conflicts <dep-specification) are package conflicts
  • (depopts <dep-specification) are optional package dependencies
  • (tags <tags>) are the list of tags for the package

The list of dependencies <dep-specification> is modeled after opam’s own language: The syntax is as a list of the following elements:

op := '=' | '<' | '>' | '<>' | '>=' | '<='

stage := :with_test | :build | :dev

constr := (<op> <version>)

logop := or | and

dep := (name <stage>)
     | (name <constr>)
     | (name (<logop> (<stage> | <constr>)*))

dep-specification = dep+

Here’s a complete example of a dune file with opam metadata specification:

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

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

 (name cohttp-async)
 (synopsis "HTTP client and server for the Async library")
 (description "A _really_ long description")
  (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.