rule¶
The rule
stanza is used to create custom user rules. It tells Dune how to
generate a specific set of files from a specific set of dependencies.
The syntax is as follows:
(rule
(action <action>)
<optional-fields>)
<action>
is what you run to produce the targets from the dependencies. See
Actions for more details.
<optional-fields>
are:
(target <filename>)
or(targets <filenames>) ``<filenames>
is a list of filenames (if defined withtargets
) or exactly one filename (if defined withtarget
). Dune needs to statically know targets of each rule.(targets)
can be omitted if it can be inferred from the action. See inferred rules.(deps <deps-conf list>)
specifies the dependencies of the rule. See Dependency Specification for more details.(mode <mode>)
specifies how to handle the targets. See modes for details.(fallback)
is deprecated and is the same as(mode fallback)
.(locks (<lock-names>))
specifies that the action must be run while holding the following locks. See Locks for more details.(alias <alias-name>)
specifies this rule’s alias. Building this alias means building the targets of this rule.(aliases <alias-name list>)
specifies many aliases for this rule.(package <package>)
specifies this rule’s package. This rule will be unavailable when installing other packages in release mode.(enabled_if <blang expression>)
specifies the Boolean condition that must be true for the rule to be considered. The condition is specified using the Boolean Language, and the field allows for Variables to appear in the expressions.
Please note: contrary to makefiles or other build systems, user rules currently
don’t support patterns, such as a rule to produce %.y
from %.x
for any
given %
. This might be supported in the future.
Modes¶
By default, a rule’s target must not exist in the source tree because Dune will
error out when this is the case; however, it’s possible to change this behavior
using the mode
field. The following modes are available:
standard
- the standard mode.fallback
- in this mode, when the targets are already present in the source tree, Dune will ignore the rule. It’s an error if only a subset of the targets are present in the tree. Fallback rules are commonly used to generate default configuration files that may be generated by a configure script.
promote
or(promote <options>)
- in this mode, the files in the source tree will be ignored. Once the rule has been executed, the targets will be copied back to the source tree. The following options are available:(until-clean)
means thatdune clean
will remove the promoted files from the source tree.(into <dir>)
means that the files are promoted in<dir>
instead of the current directory. This feature has been available since Dune 1.8.(only <predicate>)
means that only a subset of the targets should be promoted. The argument is similar to the argument of subdir, specified using the Predicate Language. This feature has been available since Dune 1.10.
There are two use cases for promote
rules. The first one is when the
generated code is easier to review than the generator, so it’s easier to commit
the generated code and review it. The second is to cut down dependencies during
releases. By passing --ignore-promoted-rules
to Dune, rules with (mode
promote)
will be ignored, and the source files will be used instead. The
-p/--for-release-of-packages
flag implies --ignore-promote-rules
.
However, rules that promote only a subset of their targets via (only ...)
are never ignored.
Inferred Rules¶
When using the action DSL (see Actions), the dependencies and targets are usually obvious.
For instance:
(rule
(target b)
(deps a)
(action (copy %{deps} %{target})))
In this example, the dependencies and targets are obvious by inspecting the action. When this is the case, you can use the following shorter syntax and have Dune infer dependencies and targets for you:
(rule <action>)
For instance:
(rule (copy a b))
Note that in Dune, targets must always be known statically. For instance, this
(rule ...)
stanza is rejected by Dune:
(rule (copy a b.%{read:file}))
Directory targets¶
Note that at this time, Dune officially only supports user rules with targets in
the current directory. However, starting from Dune 3.0, we provide an
experimental support for directory targets, where an action can produce a
whole tree of build artifacts. To specify a directory target, you can use the
(dir <dirname>)
syntax. For example, the following stanza describes a rule
with a file target foo
and a directory target bar
.
(rule
(targets foo (dir bar))
(action <action>))
To enable this experimental feature, add (using directory-targets 0.1)
to
your dune-project
file. However note that currently rules with a directory
target are always rebuilt. We are working on fixing this performance bug.