148 lines
5.3 KiB
ReStructuredText
148 lines
5.3 KiB
ReStructuredText
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:
|
|
|
|
.. code:: dune
|
|
|
|
(rule
|
|
(action <action>)
|
|
<optional-fields>)
|
|
|
|
``<action>`` is what you run to produce the targets from the dependencies. See
|
|
:doc:`/reference/actions/index` for more details.
|
|
|
|
``<optional-fields>`` are:
|
|
|
|
- ``(target <filename>)`` or ``(targets <filenames>)`` is a list of filenames
|
|
(if defined with ``targets``) or exactly one filename (if defined with
|
|
``target``). 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
|
|
:doc:`/concepts/dependency-spec` 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 :doc:`/concepts/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
|
|
:doc:`/reference/boolean-language`, and the field allows for
|
|
:doc:`/concepts/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:
|
|
|
|
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:
|
|
|
|
- ``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 that ``dune 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 :doc:`subdir`,
|
|
specified using the :doc:`/reference/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 :doc:`/reference/actions/index`), the
|
|
dependencies and targets are usually obvious.
|
|
|
|
For instance:
|
|
|
|
.. code:: dune
|
|
|
|
(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:
|
|
|
|
.. code:: dune
|
|
|
|
(rule <action>)
|
|
|
|
For instance:
|
|
|
|
.. code:: dune
|
|
|
|
(rule (copy a b))
|
|
|
|
Note that in Dune, targets must always be known statically. For instance, this
|
|
``(rule ...)`` stanza is rejected by Dune:
|
|
|
|
.. code:: 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``.
|
|
|
|
.. code:: dune
|
|
|
|
(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.
|