Managing Dependencies¶
The OCaml ecosystem has a wealth of third-party packages that are available for use. In this section we will look into how to use them with Dune.
Adding Dependencies¶
Much like in regular projects, to add a library we need to add a dependency to
it. For simplicity we will use the popular fmt
library as an example, but any
package from the package repository can be used.
First we update the dune-project
file to add a dependeny on the opam package.
dune-project
(lang dune 3.17)
(name test)
(package
(name test)
(depends
(ocaml (>= 4.14))
fmt))
After this change to our project dependencies, we need to relock dependencies to update our lock directory with the new packages.
$ dune pkg lock
Solution for dune.lock:
- base-unix.base
- fmt.0.9.0
- ocaml.5.2.0
- ocaml-base-compiler.5.2.0
- ocaml-config.3
- ocamlbuild.0.15.0+dune
- ocamlfind.1.9.6+dune
- topkg.1.0.7
You can see a lot of new dependencies, among these fmt
.
Note
The list of packages being output includes all dependencies of your project, including transitive dependencies.
This will take care of installing the dependencies, but we still need to add it to our build as a library as usual:
dune
(executable
(public_name test)
(libraries fmt))
Adding a library dependency to our dune
file via the libraries
stanza.
This will allow us to use the Fmt
module in our OCaml code.
test.ml
let langs = ["OCaml"; "Rust"]
let () =
let pp_langs = Fmt.(list ~sep:(any ", ") string) in
Format.printf "Hello, %a!\n" pp_langs langs
We update the code to define an Fmt.t
pretty-printer for the list of strings
and then use it to print the value.
To build it we just call build
again.
$ dune build
which will download and install the new dependencies and build our project as before.
As we see, the code works and uses fmt
to do the pretty-printing:
$ dune exec ./test.exe
Hello, OCaml, Rust!
Dependency Constraints¶
Packages are often only compatible with some versions of dependencies. To
specify a version range, use the regular Dune dependency syntax
used for opam dependencies in the dune-project
file.
dune-project
(lang dune 3.17)
(name test)
(package
(name test)
(depends
(ocaml (>= 4.14))
(fmt (and (>= 0.6) (< 1.0)))))
This ensures the fmt
package to install will be compatible with
our request. These constraints will be taken into account the next time the
package is locked:
$ dune pkg lock
Solution for dune.lock:
- base-unix.base
- fmt.0.9.0
- ocaml.5.2.0
- ocaml-base-compiler.5.2.0
- ocaml-config.3
- ocamlbuild.0.15.0+dune
- ocamlfind.1.9.6+dune
- topkg.1.0.7
The version of fmt
picked is indeed between 0.6
and 1.0
.
Removing Dependencies¶
Given all dependencies are defined in the dune-project
file, removing a
dependency means to remove the dependency from the depends
field of your
dune-project
and relocking the project.
The new lock directory will not depend on the package anymore, and in future
builds, the package will not be accessible as library
anymore.
Note
The removed dependency might still be part of the lock directory if some other dependency of your project depends on it.