Dependency Specification

Dependencies in dune files can be specified using one of the following:

  • (:name <dependencies>) will bind the list of dependencies to the name variable. This variable will be available as %{name} in actions.

  • (file <filename>), or simply <filename>, depend on this file.

  • (alias <alias-name>) depends on the construction of this alias. For instance: (alias src/runtest).

  • (alias_rec <alias-name>) depends on the construction of this alias recursively in all children directories wherever it is defined. For instance: (alias_rec src/runtest) might depend on (alias src/runtest), (alias src/foo/bar/runtest), etc.

  • (glob_files <glob>) depends on all files matched by <glob>. See the glob for details.

  • (glob_files_rec <glob>) is the recursive version of (glob_files <glob>). See the glob for details.

  • (source_tree <dir>) depends on all source files in the subtree with root <dir>.

  • (universe) depends on everything in the universe. This is for cases where dependencies are too hard to specify. Note that Dune will not be able to cache the result of actions that depend on the universe. In any case, this is only for dependencies in the installed world. You must still specify all dependencies that come from the workspace.

  • (package <pkg>) depends on all files installed by <package>, as well as on the transitive package dependencies of <package>. This can be used to test a command against the files that will be installed.

  • (env_var <var>) depends on the value of the environment variable <var>. If this variable becomes set, becomes unset, or changes value, the target will be rebuilt.

  • (sandbox <config>) requires a particular sandboxing configuration. <config> can be one (or many) of:

    • always: the action requires a clean environment

    • none: the action must run in the build directory

    • preserve_file_kind: the action needs the files it reads to look like normal files (so Dune won’t use symlinks for sandboxing)

  • (include <file>) read the s-expression in <file> and interpret it as additional dependencies. The s-expression is expected to be a list of the same constructs enumerated here.

In all these cases, the argument supports Variables.

Named Dependencies

Dune allows a user to organize dependency lists by naming them. The user is allowed to assign a group of dependencies a name that can later be referred to in actions (like the %{deps}, %{target}, and %{targets} built in variables).

One instance where this is useful is for naming globs. Here’s an example of an imaginary bundle command:

(rule
 (target archive.tar)
 (deps
  index.html
  (:css (glob_files *.css))
  (:js foo.js bar.js)
  (:img (glob_files *.png) (glob_files *.jpg)))
 (action
  (run %{bin:bundle} index.html -css %{css} -js %{js} -img %{img} -o %{target})))

Note that a named dependency list can also include unnamed dependencies (like index.html in the example above). Also, such user defined names will shadow build in variables, so (:workspace_root x) will shadow the built-in %{workspace_root} variable.

Glob

You can use globs to declare dependencies on a set of files. Note that globs will match files that exist in the source tree as well as buildable targets, so for instance you can depend on *.cmi.

Dune supports globbing files in a single directory via (glob_files ...) and, starting with Dune 3.0, in all subdirectories recursively via (glob_files_rec ...). The glob is interpreted as follows:

  • anything before the last / is taken as a literal path

  • anything after the last /, or everything if the glob contains no /, is interpreted using the glob syntax

Absolute paths are permitted in the (glob_files ...) term only. It’s an error to pass an absolute path (i.e., a path beginning with a /) to (glob_files_rec ...)`.

The glob syntax is interpreted as follows:

  • \<char> matches exactly <char>, even if it’s a special character (*, ?, …).

  • * matches any sequence of characters, except if it comes first, in which case it matches any character that is not . followed by anything.

  • ** matches any character that is not . followed by anything, except if it comes first, in which case it matches anything.

  • ? matches any single character.

  • [<set>] matches any character that is part of <set>.

  • [!<set>] matches any character that is not part of <set>.

  • {<glob1>,<glob2>,...,<globn>} matches any string that is matched by one of <glob1>, <glob2>, etc.

Glob syntax examples

Syntax

Files matched

Files not matched

x

x

y

\*

*

x

file*.txt

file1.txt, file2.txt

f.txt

*.txt

f.txt

.hidden.txt

a**

aml

a.ml

**

a/b, a.b

(none)

a?.txt

a1.txt, a2.txt

b1.txt, a10.txt

f[xyz].txt

fx.txt, fy.txt, fz.txt

f2.txt, f.txt

f[!xyz].txt

f2.txt, fa.txt

fx.txt, f.txt

a.{ml,mli}

a.ml, a.mli

a.txt, b.ml

../a.{ml,mli}

../a.ml, ../a.mli

a.ml