1595 lines
55 KiB
ReStructuredText
1595 lines
55 KiB
ReStructuredText
**********
|
|
dune files
|
|
**********
|
|
|
|
``dune`` files are the main part of dune. They are used to describe libraries,
|
|
executables, tests, and everything dune needs to know about.
|
|
|
|
The syntax of ``dune`` files is described in :ref:`metadata-format` section.
|
|
|
|
Stanzas
|
|
=======
|
|
|
|
``dune`` files are composed of stanzas. For instance a typical
|
|
``dune`` looks like:
|
|
|
|
.. code:: scheme
|
|
|
|
(library
|
|
(name mylib)
|
|
(libraries base lwt))
|
|
|
|
(rule
|
|
(targets foo.ml)
|
|
(deps generator/gen.exe)
|
|
(action (run %{deps} -o %{targets})))
|
|
|
|
The following sections describe the available stanzas and their meaning.
|
|
|
|
jbuild_version
|
|
--------------
|
|
|
|
Deprecated. This stanza is no longer used and will be removed in the
|
|
future.
|
|
|
|
library
|
|
-------
|
|
|
|
The ``library`` stanza must be used to describe OCaml libraries. The
|
|
format of library stanzas is as follows:
|
|
|
|
.. code:: scheme
|
|
|
|
library
|
|
(name <library-name>
|
|
<optional-fields>
|
|
)
|
|
|
|
``<library-name>`` is the real name of the library. It determines the
|
|
names of the archive files generated for the library as well as the
|
|
module name under which the library will be available, unless
|
|
``(wrapped false)`` is used (see below). It must be a valid OCaml
|
|
module name but doesn't need to start with a uppercase letter.
|
|
|
|
For instance, the modules of a library named ``foo`` will be
|
|
available as ``Foo.XXX`` outside of ``foo`` itself. It is however
|
|
allowed to write an explicit ``Foo`` module, in which case this will
|
|
be the interface of the library and you are free to expose only the
|
|
modules you want.
|
|
|
|
Note that by default libraries and other things that consume
|
|
OCaml/Reason modules only consume modules from the directory where the
|
|
stanza appear. In order to declare a multi-directory library, you need
|
|
to use the :ref:`include_subdirs` stanza.
|
|
|
|
``<optional-fields>`` are:
|
|
|
|
- ``(public_name <name>)`` this is the name under which the library can be
|
|
referred to as a dependency when it is not part of the current workspace,
|
|
i.e. when it is installed. Without a ``(public_name ...)`` field, the library
|
|
will not be installed by dune. The public name must start by the package
|
|
name it is part of and optionally followed by a dot and anything else you
|
|
want. The package name must be one of the packages that dune knows about,
|
|
as determined by the :ref:`opam-files`
|
|
|
|
- ``(synopsis <string>)`` should give a one-line description of the library.
|
|
This is used by tools that list installed libraries
|
|
|
|
- ``(modules <modules>)`` specifies what modules are part of the library. By
|
|
default dune will use all the .ml/.re files in the same directory as the
|
|
``dune`` file. This include ones that are present in the file system as well
|
|
as ones generated by user rules. You can restrict this list by using a
|
|
``(modules <modules>)`` field. ``<modules>`` uses the `Ordered set language`_
|
|
where elements are module names and don't need to start with a uppercase
|
|
letter. For instance to exclude module ``Foo``: ``(modules (:standard \
|
|
foo))``
|
|
|
|
- ``(libraries <library-dependencies>)`` is used to specify the dependencies
|
|
of the library. See the section about `Library dependencies`_ for more details
|
|
|
|
- ``(wrapped <boolean>)`` specifies whether the modules of the library should be
|
|
available only through the top-level library module, or should all be exposed
|
|
at the top level. The default is ``true`` and it is highly recommended to keep
|
|
it this way. Because OCaml top-level modules must all be unique when linking
|
|
an executables, polluting the top-level namespace will make your library
|
|
unusable with other libraries if there is a module name clash. This option is
|
|
only intended for libraries that manually prefix all their modules by the
|
|
library name and to ease porting of existing projects to dune
|
|
|
|
- ``(preprocess <preprocess-spec>)`` specifies how to preprocess files if
|
|
needed. The default is ``no_processing``. Other options are described in the
|
|
`Preprocessing specification`_ section
|
|
|
|
- ``(preprocessor_deps (<deps-conf list>))`` specifies extra dependencies of the
|
|
preprocessor, for instance if the preprocessor reads a generated file. The
|
|
specification of dependencies is described in the `Dependency specification`_
|
|
section
|
|
|
|
- ``(optional)``, if present it indicates that the library should only be built
|
|
and installed if all the dependencies are available, either in the workspace
|
|
or in the installed world. You can use this to provide extra features without
|
|
adding hard dependencies to your project
|
|
|
|
- ``(c_names (<names>))``, if your library has stubs, you must list the C files
|
|
in this field, without the ``.c`` extension
|
|
|
|
- ``(cxx_names (<names>))`` is the same as ``c_names`` but for C++ stubs
|
|
|
|
- ``(install_c_headers (<names>))``, if your library has public C header files
|
|
that must be installed, you must list them in this field, without the ``.h``
|
|
extension
|
|
|
|
- ``(modes <modes>)`` modes which should be built by default. The
|
|
most common use for this feature is to disable native compilation
|
|
when writing libraries for the OCaml toplevel. The following modes
|
|
are available: ``byte``, ``native`` and ``best``. ``best`` is
|
|
``native`` or ``byte`` when native compilation is not available
|
|
|
|
- ``(no_dynlink)`` is to disable dynamic linking of the library. This is for
|
|
advanced use only, by default you shouldn't set this option
|
|
|
|
- ``(kind <kind>)`` is the kind of the library. The default is ``normal``, other
|
|
available choices are ``ppx_rewriter`` and ``ppx_deriver`` and must be set
|
|
when the library is intended to be used as a ppx rewriter or a ``[@@deriving
|
|
...]`` plugin. The reason why ``ppx_rewriter`` and ``ppx_deriver`` are split
|
|
is historical and hopefully we won't need two options soon
|
|
|
|
- ``(ppx_runtime_libraries (<library-names>))`` is for when the library is a ppx
|
|
rewriter or a ``[@@deriving ...]`` plugin and has runtime dependencies. You
|
|
need to specify these runtime dependencies here
|
|
|
|
- ``(virtual_deps (<opam-packages>)``. Sometimes opam packages enable a specific
|
|
feature only if another package is installed. This is for instance the case of
|
|
``ctypes`` which will only install ``ctypes.foreign`` if the dummy
|
|
``ctypes-foreign`` package is installed. You can specify such virtual
|
|
dependencies here. You don't need to do so unless you use dune to
|
|
synthesize the ``depends`` and ``depopts`` sections of your opam file
|
|
|
|
- ``js_of_ocaml``. See the section about :ref:`dune-jsoo`
|
|
|
|
- ``flags``, ``ocamlc_flags`` and ``ocamlopt_flags``. See the section about
|
|
`OCaml flags`_
|
|
|
|
- ``(library_flags (<flags>))`` is a list of flags that are passed as it to
|
|
``ocamlc`` and ``ocamlopt`` when building the library archive files. You can
|
|
use this to specify ``-linkall`` for instance. ``<flags>`` is a list of
|
|
strings supporting `Variables expansion`_
|
|
|
|
- ``(c_flags <flags>)`` specifies the compilation flags for C stubs, using the
|
|
`Ordered set language`_. This field supports ``(:include ...)`` forms
|
|
|
|
- ``(cxx_flags <flags>)`` is the same as ``c_flags`` but for C++ stubs
|
|
|
|
- ``(c_library_flags <flags>)`` specifies the flags to pass to the C compiler
|
|
when constructing the library archive file for the C stubs. ``<flags>`` uses
|
|
the `Ordered set language`_ and supports ``(:include ...)`` forms. When you
|
|
are writing bindings for a C library named ``bar``, you should typically write
|
|
``-lbar`` here, or whatever flags are necessary to to link against this
|
|
library
|
|
|
|
- ``(self_build_stubs_archive <c-libname>)`` indicates to dune that the
|
|
library has stubs, but that the stubs are built manually. The aim of the field
|
|
is to embed a library written in foreign language and/or building with another
|
|
build system. It is not for casual uses, see the `re2 library
|
|
<https://github.com/janestreet/re2>`__ for an example of use
|
|
|
|
- ``(modules_without_implementation <modules>)`` specifies a list of
|
|
modules that have only a ``.mli`` or ``.rei`` but no ``.ml`` or
|
|
``.re`` file. Such modules are usually referred as *mli only
|
|
modules*. They are not officially supported by the OCaml compiler,
|
|
however they are commonly used. Such modules must only define
|
|
types. Since it is not reasonably possible for dune to check
|
|
that this is the case, dune requires the user to explicitly list
|
|
such modules to avoid surprises. ``<modules>`` must be a subset of
|
|
the modules listed in the ``(modules ...)`` field.
|
|
|
|
- ``(allow_overlapping_dependencies)`` allows external dependencies to
|
|
overlap with libraries that are present in the workspace
|
|
|
|
- ``(no_keep_locs)`` undocumented, it is a necessary hack until this
|
|
is implemented: https://github.com/ocaml/dune/issues/921
|
|
|
|
Note that when binding C libraries, dune doesn't provide special support for
|
|
tools such as ``pkg-config``, however it integrates easily with configurator_ by
|
|
using ``(c_flags (:include ...))`` and ``(c_library_flags (:include ...))``.
|
|
|
|
.. _configurator: https://github.com/janestreet/configurator
|
|
|
|
executable
|
|
----------
|
|
|
|
The ``executable`` stanza must be used to describe an executable. The
|
|
format of executable stanzas is as follows:
|
|
|
|
.. code:: scheme
|
|
|
|
(executable
|
|
(name <name>)
|
|
<optional-fields>
|
|
)
|
|
|
|
``<name>`` is a module name that contains the main entry point of the
|
|
executable. There can be additional modules in the current directory, you only
|
|
need to specify the entry point. Given an ``executable`` stanza with ``(name
|
|
<name>)``, dune will know how to build ``<name>.exe``, ``<name>.bc`` and
|
|
``<name>.bc.js``. ``<name>.exe`` is a native code executable, ``<name>.bc`` is a
|
|
bytecode executable which requires ``ocamlrun`` to run and ``<name>.bc.js`` is a
|
|
JavaScript generated using js_of_ocaml.
|
|
|
|
Note that in case native compilation is not available, ``<name>.exe``
|
|
will in fact be a custom byte-code executable. Custom in the sense of
|
|
``ocamlc -custom``, meaning that it is a native executable that embeds
|
|
the ``ocamlrun`` virtual machine as well as the byte code. As such you
|
|
can always rely on ``<name>.exe`` being available. Moreover, it is
|
|
usually preferable to use ``<name>.exe`` in custom rules or when
|
|
calling the executable by hand. This is because running a byte-code
|
|
executable often requires loading shared libraries that are locally
|
|
built, and so requires additional setup such as setting specific
|
|
environment variables and dune doesn't do at the moment.
|
|
|
|
Native compilation is considered not available when there is no ``ocamlopt``
|
|
binary at the same place as where ``ocamlc`` was found.
|
|
|
|
Executables can also be linked as object or shared object files. See
|
|
`linking modes`_ for more information.
|
|
|
|
``<optional-fields>`` are:
|
|
|
|
- ``(public_name <public-name>)`` specifies that the executable should be
|
|
installed under that name. It is the same as adding the following stanza to
|
|
your ``dune`` file:
|
|
|
|
.. code:: scheme
|
|
|
|
(install
|
|
(section bin)
|
|
(files (<name>.exe as <public-name>)))
|
|
|
|
.. _shared-exe-fields:
|
|
|
|
- ``(package <package>)`` if there is a ``(public_name ...)`` field, this
|
|
specifies the package the executables are part of
|
|
|
|
- ``(libraries <library-dependencies>)`` specifies the library dependencies.
|
|
See the section about `Library dependencies`_ for more details
|
|
|
|
- ``(link_flags <flags>)`` specifies additional flags to pass to the linker.
|
|
This field supports ``(:include ...)`` forms
|
|
|
|
- ``(link_deps (<deps-conf list>))`` specifies the dependencies used only by the
|
|
linker, for example when using a version script. See the `Dependency
|
|
specification`_ section for more details.
|
|
|
|
- ``(modules <modules>)`` specifies which modules in the current directory
|
|
dune should consider when building this executable. Modules not listed
|
|
here will be ignored and cannot be used inside the executable described by
|
|
the current stanza. It is interpreted in the same way as the ``(modules
|
|
...)`` field of `library`_
|
|
|
|
- ``(modes (<modes>))`` sets the `linking modes`_. The default is
|
|
``(byte exe)``
|
|
|
|
- ``(preprocess <preprocess-spec>)`` is the same as the ``(preprocess ...)``
|
|
field of `library`_
|
|
|
|
- ``(preprocessor_deps (<deps-conf list>))`` is the same as the
|
|
``(preprocessor_deps ...)`` field of `library`_
|
|
|
|
- ``js_of_ocaml``. See the section about `js_of_ocaml`_
|
|
|
|
- ``flags``, ``ocamlc_flags`` and ``ocamlopt_flags``. See the section about
|
|
specifying `OCaml flags`_
|
|
|
|
- ``(modules_without_implementation <modules>)`` is the same as the
|
|
corresponding field of `library`_
|
|
|
|
- ``(allow_overlapping_dependencies)`` is the same as the
|
|
corresponding field of `library`_
|
|
|
|
Linking modes
|
|
~~~~~~~~~~~~~
|
|
|
|
The ``modes`` field allows to select what linking modes should be used
|
|
to link executables. Each mode is a pair ``(<compilation-mode>
|
|
<binary-kind>)`` where ``<compilation-mode>`` describes whether the
|
|
byte code or native code backend of the OCaml compiler should be used
|
|
and ``<binary-kind>`` describes what kind of file should be produced.
|
|
|
|
``<compilation-mode>`` must be ``byte``, ``native`` or ``best``, where
|
|
``best`` is ``native`` with a fallback to byte-code when native
|
|
compilation is not available.
|
|
|
|
``<binary-kind>`` is one of:
|
|
|
|
- ``exe`` for normal executables
|
|
- ``object`` for producing static object files that can be manually
|
|
linked into C applications
|
|
- ``shared_object`` for producing object files that can be dynamically
|
|
loaded into an application. This mode can be used to write a plugin
|
|
in OCaml for a non-OCaml application.
|
|
|
|
For instance the following ``executables`` stanza will produce byte
|
|
code executables and native shared objects:
|
|
|
|
.. code:: scheme
|
|
|
|
(executables
|
|
((names (a b c))
|
|
(modes ((byte exe) (native shared_object)))))
|
|
|
|
Additionally, you can use the following short-hands:
|
|
|
|
- ``exe`` for ``(best exe)``
|
|
- ``object`` for ``(best object)``
|
|
- ``shared_object`` for ``(best shared_object)``
|
|
- ``byte`` for ``(byte exe)``
|
|
- ``native`` for ``(native exe)``
|
|
|
|
For instance the following ``modes`` fields are all equivalent:
|
|
|
|
.. code:: scheme
|
|
|
|
(modes (exe object shared_object))
|
|
(modes ((best exe)
|
|
(best object)
|
|
(best shared_object)))
|
|
|
|
The extensions for the various linking modes are chosen as follows:
|
|
|
|
================ ============= =================
|
|
compilation mode binary kind extensions
|
|
---------------- ------------- -----------------
|
|
byte exe .bc and .bc.js
|
|
native/best exe .exe
|
|
byte object .bc%{ext_obj}
|
|
native/best object .exe%{ext_obj}
|
|
byte shared_object .bc%{ext_dll}
|
|
native/best shared_object %{ext_dll}
|
|
================ ============= =================
|
|
|
|
Where ``%{ext_obj}`` and ``%{ext_dll}`` are the extensions for object
|
|
and shared object files. Their value depends on the OS, for instance
|
|
on Unix ``%{ext_obj}`` is usually ``.o`` and ``%{ext_dll}`` is usually
|
|
``.so`` while on Windows ``%{ext_obj}`` is ``.obj`` and ``%{ext_dll}``
|
|
is ``.dll``.
|
|
|
|
Note that when ``(byte exe)`` is specified but neither ``(best exe)``
|
|
nor ``(native exe)`` are specified, Jbuilkd still knows how to build
|
|
an executable with the extension ``.exe``. In such case, the ``.exe``
|
|
version is the same as the ``.bc`` one except that it is linked with
|
|
the ``-custom`` option of the compiler. You should always use the
|
|
``.exe`` rather that the ``.bc`` inside build rules.
|
|
|
|
executables
|
|
-----------
|
|
|
|
The ``executables`` stanza is the same as the ``executable`` stanza, except that
|
|
it is used to describe several executables sharing the same configuration.
|
|
|
|
It shares the same fields as the ``executable`` stanza, except that instead of
|
|
``(name ...)`` and ``(public_name ...)`` you must use:
|
|
|
|
- ``(names <names>)`` where ``<names>`` is a list of entry point names. As for
|
|
``executable`` you only need to specify the modules containing the entry point
|
|
of each executable
|
|
|
|
- ``(public_names <names>)`` describes under what name each executable should
|
|
be installed. The list of names must be of the same length as the list in the
|
|
``(names ...)`` field. Moreover you can use ``-`` for executables that
|
|
shouldn't be installed
|
|
|
|
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:: scheme
|
|
|
|
(rule
|
|
(targets <filenames>)
|
|
(action <action>)
|
|
<optional-fields>)
|
|
|
|
``<filenames>`` is a list of file names. Note that currently dune only
|
|
support user rules with targets in the current directory.
|
|
|
|
``<action>`` is the action to run to produce the targets from the dependencies.
|
|
See the `User actions`_ section for more details.
|
|
|
|
``<optional-fields>`` are:
|
|
|
|
- ``(deps <deps-conf list>)`` to specify the dependencies of the
|
|
rule. See the `Dependency specification`_ section for more details.
|
|
|
|
- ``(mode <mode>)`` to specify how to handle the targets, see `modes`_
|
|
for details
|
|
|
|
- ``(fallback)`` is deprecated and is the same as ``(mode fallback)``
|
|
|
|
- ``(locks (<lock-names>))`` specify that the action must be run while
|
|
holding the following locks. See the `Locks`_ section for more details.
|
|
|
|
Note that 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, the target of a rule must not exist in the source tree and
|
|
dune will error out when this is the case.
|
|
|
|
However, it is possible to change this behavior using the ``mode``
|
|
field. The following modes are available:
|
|
|
|
- ``standard``, this is the standard mode
|
|
|
|
- ``fallback``, in this mode, when the targets are already present in
|
|
the source tree, dune will ignore the rule. It is an error if
|
|
only a subset of the targets are present in the tree. The common use
|
|
of fallback rules is to generate default configuration files that
|
|
may be generated by a configure script.
|
|
|
|
- ``promote``, 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
|
|
|
|
- ``promote-until-clean`` is the same as ``promote`` except than
|
|
``dune clean`` will remove the promoted files from the source
|
|
tree
|
|
|
|
|
|
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 will ``(mode promote)`` will be ignored and the
|
|
source files will be used instead. The
|
|
``-p/--for-release-of-packages`` flag implies
|
|
``--ignore-promote-rules``.
|
|
|
|
inferred rules
|
|
~~~~~~~~~~~~~~
|
|
|
|
When using the action DSL (see `User actions`_), it is most of the
|
|
time obvious what are the dependencies and targets.
|
|
|
|
For instance:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule
|
|
(targets b)
|
|
(deps a)
|
|
(action (copy %{deps} %{targets})))
|
|
|
|
In this example it is obvious by inspecting the action what the
|
|
dependencies and targets are. When this is the case you can use the
|
|
following shorter syntax, where dune infers dependencies and
|
|
targets for you:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule <action>)
|
|
|
|
For instance:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule (copy a b))
|
|
|
|
Note that in dune, targets must always be known
|
|
statically. Especially, this mean that dune must be able to
|
|
statically determine all targets. For instance, this ``(rule ...)``
|
|
stanza is rejected by dune:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule (copy a b.%{read:file}))
|
|
|
|
ocamllex
|
|
--------
|
|
|
|
``(ocamllex <names>)`` is essentially a shorthand for:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule
|
|
(targets <name>.ml)
|
|
(deps <name>.mll)
|
|
(action (chdir %{workspace_root}
|
|
(run %{bin:ocamllex} -q -o %{targets} %{deps}))))
|
|
|
|
To use a different rule mode, use the long form:
|
|
|
|
.. code:: scheme
|
|
|
|
(ocamllex
|
|
(modules <names>)
|
|
(mode <mode>))
|
|
|
|
ocamlyacc
|
|
---------
|
|
|
|
``(ocamlyacc <names>)`` is essentially a shorthand for:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule
|
|
(targets <name>.ml <name>.mli)
|
|
(deps <name>.mly)
|
|
(action (chdir %{workspace_root}
|
|
(run %{bin:ocamlyacc} %{deps}))))
|
|
|
|
To use a different rule mode, use the long form:
|
|
|
|
.. code:: scheme
|
|
|
|
(ocamlyacc
|
|
(modules <names>)
|
|
(mode <mode>))
|
|
|
|
menhir
|
|
------
|
|
|
|
A ``menhir`` stanza is available to support the menhir_ parser generator. See
|
|
the :ref:`menhir-main` section for details.
|
|
|
|
.. _alias-stanza:
|
|
|
|
alias
|
|
-----
|
|
|
|
The ``alias`` stanza lets you add dependencies to an alias, or specify an action
|
|
to run to construct the alias.
|
|
|
|
The syntax is as follows:
|
|
|
|
.. code:: scheme
|
|
|
|
(alias
|
|
(name <alias-name>)
|
|
(deps <deps-conf list>)
|
|
<optional-fields>)
|
|
|
|
``<name>`` is an alias name such as ``runtest``.
|
|
|
|
.. _alias-fields:
|
|
|
|
``<deps-conf list>`` specifies the dependencies of the alias. See the
|
|
`Dependency specification`_ section for more details.
|
|
|
|
``<optional-fields>`` are:
|
|
|
|
- ``<action>``, an action to run when constructing the alias. See the `User
|
|
actions`_ section for more details.
|
|
|
|
- ``(package <name>)`` indicates that this alias stanza is part of package
|
|
``<name>`` and should be filtered out if ``<name>`` is filtered out from the
|
|
command line, either with ``--only-packages <pkgs>`` or ``-p <pkgs>``
|
|
|
|
- ``(locks (<lock-names>))`` specify that the action must be run while
|
|
holding the following locks. See the `Locks`_ section for more details.
|
|
|
|
- ``(enabled_if <blang expression>)`` specifies the boolean condition that must
|
|
be true for the tests to run. The condition is specified using the blang_, and
|
|
the field allows for variables_ to appear in the expressions.
|
|
|
|
The typical use of the ``alias`` stanza is to define tests:
|
|
|
|
.. code:: scheme
|
|
|
|
(alias
|
|
(name runtest)
|
|
(action (run %{exe:my-test-program.exe} blah)))
|
|
|
|
See the section about :ref:`running-tests` for details.
|
|
|
|
Note that if your project contains several packages and you run test the tests
|
|
from the opam file using a ``build-test`` field, then all your ``runtest`` alias
|
|
stanzas should have a ``(package ...)`` field in order to partition the set of
|
|
tests.
|
|
|
|
install
|
|
-------
|
|
|
|
The ``install`` stanza is what lets you describe what dune should install,
|
|
either when running ``dune install`` or through opam.
|
|
|
|
Libraries and executables don't need an ``install`` stanza to be
|
|
installed, just a ``public_name`` field. Everything else needs an
|
|
``install`` stanza.
|
|
|
|
The syntax is as follows:
|
|
|
|
.. code:: scheme
|
|
|
|
(install
|
|
(section <section>)
|
|
(files <filenames>)
|
|
<optional-fields>)
|
|
|
|
``<section>`` is the installation section, as described in the opam
|
|
manual. The following sections are available:
|
|
|
|
- ``lib``
|
|
- ``lib_root``
|
|
- ``libexec``
|
|
- ``libexec_root``
|
|
- ``bin``
|
|
- ``sbin``
|
|
- ``toplevel``
|
|
- ``share``
|
|
- ``share_root``
|
|
- ``etc``
|
|
- ``doc``
|
|
- ``stublibs``
|
|
- ``man``
|
|
- ``misc``
|
|
|
|
``<files>`` is the list of files to install. Each element in the list
|
|
must be either a literal filename or a S-expression of the form:
|
|
|
|
.. code:: scheme
|
|
|
|
(<filename> as <destination>)
|
|
|
|
where ``<destination>`` describe how the file will be installed. For
|
|
instance, to install a file ``mylib.el`` as
|
|
``emacs/site-lisp/mylib.el`` in the ``share_root`` section:
|
|
|
|
.. code:: scheme
|
|
|
|
(install
|
|
(section share_root)
|
|
(files (mylib.el as emacs/site-lisp/mylib.el)))
|
|
|
|
``<optional-fields>`` are:
|
|
|
|
- ``(package <name>)``. If there are no ambiguities, you can omit this field.
|
|
Otherwise you need it to specify which package these files are part of. The
|
|
package is not ambiguous when the first parent directory to contain a
|
|
``<package>.opam`` file contains exactly one ``<package>.opam`` file
|
|
|
|
Handling of the .exe extension on Windows
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Under Microsoft Windows, executables must be suffixed with
|
|
``.exe``. Dune tries to make sure that executables are always
|
|
installed with this extension on Windows.
|
|
|
|
More precisely, when installing a file via an ``(install ...)``
|
|
stanza, if the source file has extension ``.exe`` or ``.bc``, then
|
|
dune implicitly adds the ``.exe`` extension to the destination, if
|
|
not already present.
|
|
|
|
copy_files
|
|
----------
|
|
|
|
The ``copy_files`` and ``copy_files#`` stanzas allow to specify that
|
|
files from another directory could be copied if needed to the current
|
|
directory.
|
|
|
|
The syntax is as follows:
|
|
|
|
.. code:: scheme
|
|
|
|
(copy_files <glob>)
|
|
|
|
``<glob>`` represents the set of files to copy, see the :ref:`glob
|
|
<glob>` for details.
|
|
|
|
The difference between ``copy_files`` and ``copy_files#`` is the same
|
|
as the difference between the ``copy`` and ``copy#`` action. See the
|
|
`User actions`_ section for more details.
|
|
|
|
include
|
|
-------
|
|
|
|
The ``include`` stanza allows to include the contents of another file into the
|
|
current dune file. Currently, the included file cannot be generated and must be
|
|
present in the source tree. This feature is intended to be used in conjunction
|
|
with promotion, when parts of a dune file are to be generated.
|
|
|
|
For instance:
|
|
|
|
.. code:: scheme
|
|
|
|
(include dune.inc)
|
|
|
|
(rule (with-stdout-to dune.inc.gen (run ./gen-dune.exe)))
|
|
|
|
(alias
|
|
(name runtest)
|
|
(action (diff dune.inc dune.inc.gen)))
|
|
|
|
With this dune file, running dune as follow will replace the
|
|
``dune.inc`` file in the source tree by the generated one:
|
|
|
|
.. code:: shell
|
|
|
|
$ dune build @runtest --auto-promote
|
|
|
|
.. _tests-stanza:
|
|
|
|
tests
|
|
-----
|
|
|
|
The ``tests`` stanza allows one to easily define multiple tests. For example we
|
|
can define two tests at once with:
|
|
|
|
.. code:: scheme
|
|
|
|
(tests
|
|
(names mytest expect_test)
|
|
<optional fields>)
|
|
|
|
This will define an executable named ``mytest.exe`` that will be executed as
|
|
part of the ``runtest`` alias. If the directory also contains an
|
|
``expect_test.expected`` file, then ``expect_test`` will be used to define an
|
|
expect test. That is, the test will be executed and its output will be compared
|
|
to ``expect_test.expected``.
|
|
|
|
The optional fields that are supported are a subset of the alias and executables
|
|
fields. In particular, all fields except for ``public_names`` are supported from
|
|
the `executables stanza <shared-exe-fields>`_. Alias fields apart from ``name``
|
|
and ``action`` are allowed.
|
|
|
|
test
|
|
----
|
|
|
|
The ``test`` stanza is the singular form of ``tests``. The only difference is
|
|
that it's of the form:
|
|
|
|
.. code:: scheme
|
|
|
|
(test
|
|
(name foo)
|
|
<optional fields>)
|
|
|
|
where the ``name`` field is singular. The same optional fields are supported.
|
|
|
|
.. _dune-env:
|
|
|
|
env
|
|
---
|
|
|
|
The ``env`` stanza allows to modify the environment. The syntax is as
|
|
follow:
|
|
|
|
.. code:: scheme
|
|
|
|
(env
|
|
(<profile1> <settings1>)
|
|
(<profile2> <settings2>)
|
|
...
|
|
(<profilen> <settingsn>))
|
|
|
|
The first form ``(<profile> <settings>)`` that correspond to the
|
|
selected build profile will be used to modify the environment in this
|
|
directory. You can use ``_`` to match any build profile.
|
|
|
|
Currently ``<settings>`` can be any OCaml flags field, see `OCaml
|
|
flags`_ for more details.
|
|
|
|
.. _dune-ignored_subdirs:
|
|
|
|
ignored_subdirs
|
|
---------------
|
|
|
|
The ``ignored_subdirs`` stanza allows to tell Dune to ignore one or
|
|
more sub-directories. The syntax is as follow:
|
|
|
|
.. code:: scheme
|
|
|
|
(ignored_subdirs (<sub-dir1> <sub-dir2> ...))
|
|
|
|
A directory that is ignored will not be eagerly scanned by Dune. Any
|
|
``dune`` or other special files in it won't be interpreted either and
|
|
will be treated as raw data. It is however possible to depend on files
|
|
inside ignored sub-directories.
|
|
|
|
.. _include_subdirs:
|
|
|
|
include_subdirs
|
|
---------------
|
|
|
|
The ``include_subdirs`` stanza is used to control how dune considers
|
|
sub-directories of the current directory. The syntax is as follow:
|
|
|
|
.. code:: scheme
|
|
|
|
(include_subdirs <mode>)
|
|
|
|
Where ``<mode>`` maybe be one of:
|
|
|
|
- ``no``, the default
|
|
- ``unqualified``
|
|
|
|
When the ``include_subdirs`` stanza is not present or ``<mode>`` is
|
|
``no``, dune considers sub-directories as independent. When ``<mode>``
|
|
is ``unqualified``, dune will assume that the sub-directories of the
|
|
current directory are part of the same group of directories. In
|
|
particular, dune will scan all these directories at once when looking
|
|
for OCaml/Reason files. This allows you to split a library between
|
|
several directories. ``unqualified`` means that modules in
|
|
sub-directories are seen as if they were all in the same directory. In
|
|
particular, you cannot have two modules with the same name in two
|
|
different directories. It is planned to add a ``qualified`` mode in
|
|
the future.
|
|
|
|
Note that sub-directories are included recursively, however the
|
|
recursion will stop when encountering a sub-directory that contains
|
|
another ``include_subdirs`` stanza. Additionally, it is not allowed
|
|
for a sub-directory of a directory with ``(include_subdirs <x>)``
|
|
where ``<x>`` is not ``no`` to contain one of the following stanzas:
|
|
|
|
- ``library``
|
|
- ``executable(s)``
|
|
- ``test(s)``
|
|
|
|
Common items
|
|
============
|
|
|
|
.. _ordered-set-language:
|
|
|
|
Ordered set language
|
|
--------------------
|
|
|
|
A few fields takes as argument an ordered set and can be specified using a small
|
|
DSL.
|
|
|
|
This DSL is interpreted by dune into an ordered set of strings using the
|
|
following rules:
|
|
|
|
- ``:standard`` denotes the standard value of the field when it is absent
|
|
- an atom not starting with a ``:`` is a singleton containing only this atom
|
|
- a list of sets is the concatenation of its inner sets
|
|
- ``(<sets1> \ <sets2>)`` is the set composed of elements of ``<sets1>`` that do
|
|
not appear in ``<sets2>``
|
|
|
|
In addition, some fields support the inclusion of an external file using the
|
|
syntax ``(:include <filename>)``. This is useful for instance when you need to
|
|
run a script to figure out some compilation flags. ``<filename>`` is expected to
|
|
contain a single S-expression and cannot contain ``(:include ...)`` forms.
|
|
|
|
Note that inside an ordered set, the first element of a list cannot be
|
|
an atom except if it starts with `-` or `:`. The reason for this is
|
|
that we are planning to add simple programmatic features in the
|
|
futures so that one may write:
|
|
|
|
.. code::
|
|
|
|
(flags (if (>= %{ocaml_version} 4.06) ...))
|
|
|
|
This restriction will allow to add this feature without introducing a
|
|
breaking changes. If you want to write a list where the first element
|
|
doesn't start by `-`, you can simply quote it: ``("x" y z)``.
|
|
|
|
Most fields using the ordered set language also support `Variables expansion`_.
|
|
Variables are expanded after the set language is interpreted.
|
|
|
|
.. _blang:
|
|
|
|
Boolean Language
|
|
----------------
|
|
|
|
The boolean language allows the user to define simple boolean expressions that
|
|
dune can evaluate. Here's a semi formal specification of the language:
|
|
|
|
.. code::
|
|
|
|
op := '=' | '<' | '>' | '<>' | '>=' | '<='
|
|
|
|
expr := (and <expr>+)
|
|
| (or <expr>+)
|
|
| (<op> <template> <template>)
|
|
| <template>
|
|
|
|
After an expression is evaluated, it must be exactly the string ``true`` or
|
|
``false`` to be considered as a boolean. Any other value will be treated as an
|
|
error.
|
|
|
|
Here's a simple example of a condition that expresses running on OSX and having
|
|
an flambda compiler with the help of variable expansion:
|
|
|
|
.. code:: scheme
|
|
|
|
(and %{ocamlc-config:flambda} (= %{ocamlc-config:system} macosx))
|
|
|
|
.. _variables:
|
|
|
|
Variables expansion
|
|
-------------------
|
|
|
|
Some fields can contains variables of the form ``%{var}`` that are
|
|
expanded by dune.
|
|
|
|
Dune supports the following variables:
|
|
|
|
- ``project_root`` is the root of the current project. It is typically
|
|
the toplevel directory of your project and as long as you have a
|
|
``dune-project`` file there, ``project_root`` is independent of the
|
|
workspace configuration
|
|
- ``workspace_root`` is the root of the current workspace. Note that
|
|
the value of ``workspace_root`` is not constant and depends on
|
|
whether your project is vendored or not
|
|
- ``CC`` is the C compiler command line (list made of the compiler
|
|
name followed by its flags) that was used to compile OCaml in the
|
|
current build context
|
|
- ``CXX`` is the C++ compiler command line being used in the
|
|
current build context
|
|
- ``ocaml_bin`` is the path where ``ocamlc`` lives
|
|
- ``ocaml`` is the ``ocaml`` binary
|
|
- ``ocamlc`` is the ``ocamlc`` binary
|
|
- ``ocamlopt`` is the ``ocamlopt`` binary
|
|
- ``ocaml_version`` is the version of the compiler used in the
|
|
current build context
|
|
- ``ocaml_where`` is the output of ``ocamlc -where``
|
|
- ``arch_sixtyfour`` is ``true`` if using a compiler targeting a
|
|
64 bit architecture and ``false`` otherwise
|
|
- ``null`` is ``/dev/null`` on Unix or ``nul`` on Windows
|
|
- ``ext_obj``, ``ext_asm``, ``ext_lib``, ``ext_dll`` and ``ext_exe``
|
|
are the file extension used for various artifacts
|
|
- ``ocaml-config:v`` for every variable ``v`` in the output of
|
|
``ocamlc -config``. Note that dune processes the output
|
|
of ``ocamlc -config`` in order to make it a bit more stable across
|
|
versions, so the exact set of variables accessible this way might
|
|
not be exactly the same as what you can see in the output of
|
|
``ocamlc -config``. In particular, variables added in new versions
|
|
of OCaml needs to be registered in dune before they can be used
|
|
- ``profile`` the profile selected via ``--profile``
|
|
|
|
In addition, ``(action ...)`` fields support the following special variables:
|
|
|
|
- ``targets`` expands to the list of target
|
|
- ``deps`` expands to the list of dependencies
|
|
- ``^`` expands to the list of dependencies, separated by spaces
|
|
- ``dep:<path>`` expands to ``<path>`` (and adds ``<path>`` as a dependency of
|
|
the action)
|
|
- ``exe:<path>`` is the same as ``<path>``, except when cross-compiling, in
|
|
which case it will expand to ``<path>`` from the host build context
|
|
- ``bin:<program>`` expands to a path to ``program``. If ``program``
|
|
is installed by a package in the workspace (see `install`_ stanzas),
|
|
the locally built binary will be used, otherwise it will be searched
|
|
in the ``PATH`` of the current build context. Note that ``(run
|
|
%{bin:program} ...)`` and ``(run program ...)`` behave in the same
|
|
way. ``%{bin:...}`` is only necessary when you are using ``(bash
|
|
...)`` or ``(system ...)``
|
|
- ``lib:<public-library-name>:<file>`` expands to a path to file ``<file>`` of
|
|
library ``<public-library-name>``. If ``<public-library-name>`` is available
|
|
in the current workspace, the local file will be used, otherwise the one from
|
|
the installed world will be used
|
|
- ``libexec:<public-library-name>:<file>`` is the same as ``lib:...`` except
|
|
when cross-compiling, in which case it will expand to the file from the host
|
|
build context
|
|
- ``lib-available:<library-name>`` expands to ``true`` or ``false`` depending on
|
|
whether the library is available or not. A library is available iff at least
|
|
one of the following condition holds:
|
|
|
|
- it is part the installed worlds
|
|
- it is available locally and is not optional
|
|
- it is available locally and all its library dependencies are
|
|
available
|
|
|
|
- ``version:<package>`` expands to the version of the given
|
|
package. Note that this is only supported for packages that are
|
|
being defined in the current scope
|
|
- ``read:<path>`` expands to the contents of the given file
|
|
- ``read-lines:<path>`` expands to the list of lines in the given
|
|
file
|
|
- ``read-strings:<path>`` expands to the list of lines in the given
|
|
file, unescaped using OCaml lexical convention
|
|
|
|
The ``%{<kind>:...}`` forms are what allows you to write custom rules that work
|
|
transparently whether things are installed or not.
|
|
|
|
Note that aliases are ignored by ``%{deps}``
|
|
|
|
The intent of this last form is to reliably read a list of strings
|
|
generated by an OCaml program via:
|
|
|
|
.. code:: ocaml
|
|
|
|
List.iter (fun s -> print_string (String.escaped s)) l
|
|
|
|
#. Expansion of lists
|
|
|
|
Forms that expands to list of items, such as ``%{cc}``, ``%{deps}``,
|
|
``%{targets}`` or ``%{read-lines:...}``, are suitable to be used in, say,
|
|
``(run <prog> <arguments>)``. For instance in:
|
|
|
|
.. code:: scheme
|
|
|
|
(run foo %{deps})
|
|
|
|
if there are two dependencies ``a`` and ``b``, the produced command
|
|
will be equivalent to the shell command:
|
|
|
|
.. code:: shell
|
|
|
|
$ foo "a" "b"
|
|
|
|
If you want the two dependencies to be passed as a single argument,
|
|
you have to quote the variable as in:
|
|
|
|
.. code:: scheme
|
|
|
|
(run foo "%{deps}")
|
|
|
|
which is equivalent to the following shell command:
|
|
|
|
.. code:: shell
|
|
|
|
$ foo "a b"
|
|
|
|
(the items of the list are concatenated with space).
|
|
Note that, since ``%{deps}`` is a list of items, the first one may be
|
|
used as a program name, for instance:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule
|
|
(targets result.txt)
|
|
(deps foo.exe (glob_files *.txt))
|
|
(action (run %{deps})))
|
|
|
|
Here is another example:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule
|
|
(targets foo.exe)
|
|
(deps foo.c)
|
|
(action (run %{cc} -o %{targets} %{deps} -lfoolib)))
|
|
|
|
|
|
Library dependencies
|
|
--------------------
|
|
|
|
Dependencies on libraries are specified using ``(libraries ...)`` fields in
|
|
``library`` and ``executables`` stanzas.
|
|
|
|
For libraries defined in the current scope, you can use either the real name or
|
|
the public name. For libraries that are part of the installed world, or for
|
|
libraries that are part of the current workspace but in another scope, you need
|
|
to use the public name. For instance: ``(libraries base re)``.
|
|
|
|
When resolving libraries, libraries that are part of the workspace are always
|
|
preferred to ones that are part of the installed world.
|
|
|
|
.. _alternative-deps:
|
|
|
|
Alternative dependencies
|
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
In addition to direct dependencies you can specify alternative dependencies.
|
|
This is described in the :ref:`Alternative dependencies <alternative-deps>`
|
|
section
|
|
|
|
It is sometimes the case that one wants to not depend on a specific library, but
|
|
instead on whatever is already installed. For instance to use a different
|
|
backend depending on the target.
|
|
|
|
Dune allows this by using a ``(select ... from ...)`` form inside the list
|
|
of library dependencies.
|
|
|
|
Select forms are specified as follows:
|
|
|
|
.. code:: scheme
|
|
|
|
(select <target-filename> from
|
|
(<literals> -> <filename>)
|
|
(<literals> -> <filename>)
|
|
...)
|
|
|
|
``<literals>`` are lists of literals, where each literal is one of:
|
|
|
|
- ``<library-name>``, which will evaluate to true if ``<library-name>`` is
|
|
available, either in the workspace or in the installed world
|
|
- ``!<library-name>``, which will evaluate to true if ``<library-name>`` is not
|
|
available in the workspace or in the installed world
|
|
|
|
When evaluating a select form, dune will create ``<target-filename>`` by
|
|
copying the file given by the first ``(<literals> -> <filename>)`` case where
|
|
all the literals evaluate to true. It is an error if none of the clauses are
|
|
selectable. You can add a fallback by adding a clause of the form ``(->
|
|
<file>)`` at the end of the list.
|
|
|
|
Preprocessing specification
|
|
---------------------------
|
|
|
|
Dune accepts three kinds of preprocessing:
|
|
|
|
- ``no_preprocessing``, meaning that files are given as it to the compiler, this
|
|
is the default
|
|
- ``(action <action>)`` to preprocess files using the given action
|
|
- ``(pps <ppx-rewriters-and-flags>)`` to preprocess files using the given list
|
|
of ppx rewriters
|
|
- ``(staged_pps <ppx-rewriters-and-flags>)`` is similar to ``(pps
|
|
...)`` but behave slightly differently and is needed for certain
|
|
ppx rewriters (see below for details)
|
|
|
|
Dune normally assumes that the compilation pipeline is sequenced as
|
|
follow:
|
|
|
|
- code generation (including preprocessing)
|
|
- dependency analysis
|
|
- compilation
|
|
|
|
Dune uses this fact to optimize the pipeline and in particular share
|
|
the result of code generation and preprocessing between the dependency
|
|
analysis and compilation phases. However, some specific code
|
|
generators or preprocessors require feedback from the compilation
|
|
phase. As a result they must be applied in stages as follows:
|
|
|
|
- first stage of code geneneration
|
|
- dependency analysis
|
|
- second step of code generation in parallel with compilation
|
|
|
|
This is the case for ppx rewriters using the OCaml typer for
|
|
instance. When using such ppx rewriters, you must use ``staged_pps``
|
|
instead of ``pps`` in order to force Dune to use the second pipeline,
|
|
which is slower but necessary in this case.
|
|
|
|
Preprocessing with actions
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
``<action>`` uses the same DSL as described in the `User actions`_
|
|
section, and for the same reason given in that section, it will be
|
|
executed from the root of the current build context. It is expected to
|
|
be an action that reads the file given as only dependency named
|
|
``input-file`` and outputs the preprocessed file on its standard output.
|
|
|
|
More precisely, ``(preprocess (action <action>))`` acts as if
|
|
you had setup a rule for every file of the form:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule
|
|
(targets file.pp.ml)
|
|
(deps file.ml)
|
|
(action (with-stdout-to %{targets}
|
|
(chdir %{workspace_root} <action>))))
|
|
|
|
The equivalent of a ``-pp <command>`` option passed to the OCaml compiler is
|
|
``(system "<command> %{input-file}")``.
|
|
|
|
Preprocessing with ppx rewriters
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
``<ppx-rewriters-and-flags>`` is expected to be a sequence where each
|
|
element is either a command line flag if starting with a ``-`` or the
|
|
name of a library. If you want to pass command line flags that do not
|
|
start with a ``-``, you can separate library names from flags using
|
|
``--``. So for instance from the following ``preprocess`` field:
|
|
|
|
.. code:: scheme
|
|
|
|
(preprocess (pps ppx1 -foo ppx2 -- -bar 42))
|
|
|
|
The list of libraries will be ``ppx1`` and ``ppx2`` and the command line
|
|
arguments will be: ``-foo -bar 42``.
|
|
|
|
Libraries listed here should be libraries implementing an OCaml AST rewriter and
|
|
registering themselves using the `ocaml-migrate-parsetree.driver API
|
|
<https://github.com/let-def/ocaml-migrate-parsetree>`__.
|
|
|
|
Dune will build a single executable by linking all these libraries and their
|
|
dependencies. Note that it is important that all these libraries are linked with
|
|
``-linkall``. Dune automatically uses ``-linkall`` when the ``(kind ...)``
|
|
field is set to ``ppx_rewriter`` or ``ppx_deriver``.
|
|
|
|
Per module preprocessing specification
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
By default a preprocessing specification will apply to all modules in the
|
|
library/set of executables. It is possible to select the preprocessing on a
|
|
module-by-module basis by using the following syntax:
|
|
|
|
.. code:: scheme
|
|
|
|
(preprocess (per_module
|
|
(<spec1> (<module-list1>))
|
|
(<spec2> (<module-list2>))
|
|
...))
|
|
|
|
Where ``<spec1>``, ``<spec2>``, ... are preprocessing specifications
|
|
and ``<module-list1>``, ``<module-list2>``, ... are list of module
|
|
names.
|
|
|
|
For instance:
|
|
|
|
.. code:: scheme
|
|
|
|
(preprocess (per_module
|
|
(((action (run ./pp.sh X=1 %{input-file})) (foo bar)))
|
|
(((action (run ./pp.sh X=2 %{input-file})) (baz)))))
|
|
|
|
.. _deps-field:
|
|
|
|
Dependency specification
|
|
------------------------
|
|
|
|
Dependencies in ``dune`` files can be specified using one of the following
|
|
syntax:
|
|
|
|
- ``(:name <dependencies>)`` will bind the 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>)``: depend on the construction of this alias, for
|
|
instance: ``(alias src/runtest)``
|
|
- ``(alias_rec <alias-name>)``: depend 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)``, ...
|
|
- ``(glob_files <glob>)``: depend on all files matched by ``<glob>``, see the
|
|
:ref:`glob <glob>` for details
|
|
|
|
.. _source_tree:
|
|
|
|
- ``(source_tree <dir>)``: depend on all source files in the subtree with root
|
|
``<dir>``
|
|
|
|
- ``(universe)``: depend 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>)`` depend 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
|
|
|
|
In all these cases, the argument supports `Variables expansion`_.
|
|
|
|
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}`` and ``%{targets}`` built in variables).
|
|
|
|
One instance where this is useful is for naming globs. Here's an
|
|
example of an imaginary bundle command:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule
|
|
(targets 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 %{targets})))
|
|
|
|
Note that such named dependency list can also include unnamed
|
|
dependencies (like ``index.html`` in the example above). Also, such
|
|
user defined names wil shadow built in variables. So
|
|
``(:workspace_root x)`` will shadow the built in ``%{workspace_root}``
|
|
variable.
|
|
|
|
.. _glob:
|
|
|
|
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``.
|
|
|
|
Currently dune only support globbing files in a single directory. And in
|
|
particular 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
|
|
|
|
The glob syntax is interpreted as follows:
|
|
|
|
- ``\<char>`` matches exactly ``<char>``, even if it is 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>``, ...
|
|
|
|
OCaml flags
|
|
-----------
|
|
|
|
In ``library``, ``executable``, ``executables`` and ``env`` stanzas,
|
|
you can specify OCaml compilation flags using the following fields:
|
|
|
|
- ``(flags <flags>)`` to specify flags passed to both ``ocamlc`` and
|
|
``ocamlopt``
|
|
- ``(ocamlc_flags <flags>)`` to specify flags passed to ``ocamlc`` only
|
|
- ``(ocamlopt_flags <flags>)`` to specify flags passed to ``ocamlopt`` only
|
|
|
|
For all these fields, ``<flags>`` is specified in the `Ordered set language`_.
|
|
These fields all support ``(:include ...)`` forms.
|
|
|
|
The default value for ``(flags ...)`` is taken from the environment,
|
|
as a result it is recommended to write ``(flags ...)`` fields as
|
|
follows:
|
|
|
|
.. code:: scheme
|
|
|
|
(flags (:standard <my options>))
|
|
|
|
.. _dune-jsoo:
|
|
|
|
js_of_ocaml
|
|
-----------
|
|
|
|
A :ref:`dune-jsoo-field` exists in executable and libraries stanzas that allows
|
|
one to customize options relevant to jsoo.
|
|
|
|
.. _user-actions:
|
|
|
|
User actions
|
|
------------
|
|
|
|
``(action ...)`` fields describe user actions.
|
|
|
|
User actions are always run from the same subdirectory of the current build
|
|
context as the dune file they are defined in. So for instance an action defined
|
|
in ``src/foo/dune`` will be run from ``_build/<context>/src/foo``.
|
|
|
|
The argument of ``(action ...)`` fields is a small DSL that is interpreted by
|
|
dune directly and doesn't require an external shell. All atoms in the DSL
|
|
support `Variables expansion`_. Moreover, you don't need to specify dependencies
|
|
explicitly for the special ``%{<kind>:...}`` forms, these are recognized and
|
|
automatically handled by dune.
|
|
|
|
The DSL is currently quite limited, so if you want to do something complicated
|
|
it is recommended to write a small OCaml program and use the DSL to invoke it.
|
|
You can use `shexp <https://github.com/janestreet/shexp>`__ to write portable
|
|
scripts or configurator_ for configuration related tasks.
|
|
|
|
The following constructions are available:
|
|
|
|
- ``(run <prog> <args>)`` to execute a program. ``<prog>`` is resolved
|
|
locally if it is available in the current workspace, otherwise it is
|
|
resolved using the ``PATH``
|
|
- ``(chdir <dir> <DSL>)`` to change the current directory
|
|
- ``(setenv <var> <value> <DSL>)`` to set an environment variable
|
|
- ``(with-<outputs>-to <file> <DSL>)`` to redirect the output to a file, where
|
|
``<outputs>`` is one of: ``stdout``, ``stderr`` or ``outputs`` (for both
|
|
``stdout`` and ``stderr``)
|
|
- ``(ignore-<outputs> <DSL)`` to ignore the output, where
|
|
``<outputs>`` is one of: ``stdout``, ``stderr`` or ``outputs``
|
|
- ``(progn <DSL>...)`` to execute several commands in sequence
|
|
- ``(echo <string>)`` to output a string on stdout
|
|
- ``(write-file <file> <string>)`` writes ``<string>`` to ``<file>``
|
|
- ``(cat <file>)`` to print the contents of a file to stdout
|
|
- ``(copy <src> <dst>)`` to copy a file
|
|
- ``(copy# <src> <dst>)`` to copy a file and add a line directive at
|
|
the beginning
|
|
- ``(system <cmd>)`` to execute a command using the system shell: ``sh`` on Unix
|
|
and ``cmd`` on Windows
|
|
- ``(bash <cmd>)`` to execute a command using ``/bin/bash``. This is obviously
|
|
not very portable
|
|
- ``(diff <file1> <file2>)`` is similar to ``(run diff <file1>
|
|
<file2>)`` but is better and allows promotion. See `Diffing and
|
|
promotion`_ for more details
|
|
- ``(diff? <file1> <file2>)`` is the same as ``(diff <file1>
|
|
<file2>)`` except that it is ignored when ``<file1>`` or ``<file2>``
|
|
doesn't exists
|
|
- ``(cmp <file1> <file2>)`` is similar to ``(run cmp <file1>
|
|
<file2>)`` but allows promotion. See `Diffing and promotion`_ for
|
|
more details
|
|
|
|
As mentioned ``copy#`` inserts a line directive at the beginning of
|
|
the destination file. More precisely, it inserts the following line:
|
|
|
|
.. code:: ocaml
|
|
|
|
# 1 "<source file name>"
|
|
|
|
Most languages recognize such lines and update their current location,
|
|
in order to report errors in the original file rather than the
|
|
copy. This is important as the copy exists only under the ``_build``
|
|
directory and in order for editors to jump to errors when parsing the
|
|
output of the build system, errors must point to files that exist in
|
|
the source tree. In the beta versions of dune, ``copy#`` was
|
|
called ``copy-and-add-line-directive``. However, most of time one
|
|
wants this behavior rather than a bare copy, so it was renamed to
|
|
something shorter.
|
|
|
|
Note: expansion of the special ``%{<kind>:...}`` is done relative to the current
|
|
working directory of the part of the DSL being executed. So for instance if you
|
|
have this action in a ``src/foo/dune``:
|
|
|
|
.. code:: scheme
|
|
|
|
(action (chdir ../../.. (echo %{path:dune})))
|
|
|
|
Then ``%{path:dune}`` will expand to ``src/foo/dune``. When you run various
|
|
tools, they often use the filename given on the command line in error messages.
|
|
As a result, if you execute the command from the original directory, it will
|
|
only see the basename.
|
|
|
|
To understand why this is important, let's consider this dune file living in
|
|
``src/foo``:
|
|
|
|
::
|
|
|
|
(rule
|
|
(targets blah.ml)
|
|
(deps blah.mll)
|
|
(action (run ocamllex -o %{targets} %{deps})))
|
|
|
|
Here the command that will be executed is:
|
|
|
|
.. code:: bash
|
|
|
|
ocamllex -o blah.ml blah.mll
|
|
|
|
And it will be executed in ``_build/<context>/src/foo``. As a result, if there
|
|
is an error in the generated ``blah.ml`` file it will be reported as:
|
|
|
|
::
|
|
|
|
File "blah.ml", line 42, characters 5-10:
|
|
Error: ...
|
|
|
|
Which can be a problem as you editor might think that ``blah.ml`` is at the root
|
|
of your project. What you should write instead is:
|
|
|
|
::
|
|
|
|
(rule
|
|
(targets blah.ml)
|
|
(deps blah.mll)
|
|
(action (chdir %{workspace_root} (run ocamllex -o %{targets} %{deps}))))
|
|
|
|
Locks
|
|
-----
|
|
|
|
Given two rules that are independent, dune will assume that there
|
|
associated action can be run concurrently. Two rules are considered
|
|
independent if none of them depend on the other, either directly or
|
|
through a chain of dependencies. This basic assumption allows to
|
|
parallelize the build.
|
|
|
|
However, it is sometimes the case that two independent rules cannot be
|
|
executed concurrently. For instance this can happen for more
|
|
complicated tests. In order to prevent dune from running the
|
|
actions at the same time, you can specify that both actions take the
|
|
same lock:
|
|
|
|
.. code:: scheme
|
|
|
|
(alias
|
|
(name runtest)
|
|
(deps foo)
|
|
(locks m)
|
|
(action (run test.exe %{deps})))
|
|
|
|
(alias
|
|
(name runtest)
|
|
(deps bar)
|
|
(locks m)
|
|
(action (run test.exe %{deps})))
|
|
|
|
Dune will make sure that the executions of ``test.exe foo`` and
|
|
``test.exe bar`` are serialized.
|
|
|
|
Although they don't live in the filesystem, lock names are interpreted as file
|
|
names. So for instance ``(with-lock m ...)`` in ``src/dune`` and ``(with-lock
|
|
../src/m)`` in ``test/dune`` refer to the same lock.
|
|
|
|
Note also that locks are per build context. So if your workspace has two build
|
|
contexts setup, the same rule might still be executed concurrently between the
|
|
two build contexts. If you want a lock that is global to all build contexts,
|
|
simply use an absolute filename:
|
|
|
|
.. code:: scheme
|
|
|
|
(alias
|
|
(name runtest)
|
|
(deps foo)
|
|
(locks /tcp-port/1042)
|
|
(action (run test.exe %{deps})))
|
|
|
|
.. _ocaml-syntax:
|
|
|
|
Diffing and promotion
|
|
---------------------
|
|
|
|
``(diff <file1> <file2>)`` is very similar to ``(run diff <file1>
|
|
<file2>)``. In particular it behaves in the same way:
|
|
|
|
- when ``<file1>`` and ``<file2>`` are equal, it doesn't nothing
|
|
- when they are not, the differences are shown and the action fails
|
|
|
|
However, it is different for the following reason:
|
|
|
|
- the exact command used to diff files can be configured via the
|
|
``--diff-command`` command line argument. Note that it is only
|
|
called when the files are not byte equals
|
|
|
|
- by default, it will use ``patdiff`` if it is installed. ``patdiff``
|
|
is a better diffing program. You can install it via opam with:
|
|
|
|
.. code:: sh
|
|
|
|
$ opam install patdiff
|
|
|
|
- on Windows, both ``(diff a b)`` and ``(diff? a b)`` normalize the end of
|
|
lines before comparing the files
|
|
|
|
- since ``(diff a b)`` is a builtin action, dune knowns that ``a``
|
|
and ``b`` are needed and so you don't need to specify them
|
|
explicitly as dependencies
|
|
|
|
- you can use ``(diff? a b)`` after a command that might or might not
|
|
produce ``b``. For cases where commands optionally produce a
|
|
*corrected* file
|
|
|
|
- it allows promotion. See below
|
|
|
|
Note that ``(cmp a b)`` does no end of lines normalization and doesn't
|
|
print a diff when the files differ. ``cmp`` is meant to be used with
|
|
binary files.
|
|
|
|
Promotion
|
|
~~~~~~~~~
|
|
|
|
Whenever an action ``(diff <file1> <file2>)`` or ``(diff? <file1>
|
|
<file2>)`` fails because the two files are different, dune allows
|
|
you to promote ``<file2>`` as ``<file1>`` if ``<file1>`` is a source
|
|
file and ``<file2>`` is a generated file.
|
|
|
|
More precisely, let's consider the following dune file:
|
|
|
|
.. code:: scheme
|
|
|
|
(rule
|
|
(with-stdout-to data.out (run ./test.exe)))
|
|
|
|
(alias
|
|
(name runtest)
|
|
(action (diff data.expected data.out)))
|
|
|
|
Where ``data.expected`` is a file committed in the source
|
|
repository. You can use the following workflow to update your test:
|
|
|
|
- update the code of your test
|
|
- run ``dune runtest``. The diff action will fail and a diff will
|
|
be printed
|
|
- check the diff to make sure it is what you expect
|
|
- run ``dune promote``. This will copy the generated ``data.out``
|
|
file to ``data.expected`` directly in the source tree
|
|
|
|
You can also use ``dune runtest --auto-promote`` which will
|
|
automatically do the promotion.
|
|
|
|
OCaml syntax
|
|
============
|
|
|
|
If a ``dune`` file starts with ``(* -*- tuareg -*- *)``, then it is
|
|
interpreted as an OCaml script that generates the ``dune`` file as described
|
|
in the rest of this section. The code in the script will have access to a
|
|
`Jbuild_plugin
|
|
<https://github.com/ocaml/dune/blob/master/plugin/jbuild_plugin.mli>`__
|
|
module containing details about the build context it is executed in.
|
|
|
|
The OCaml syntax gives you an escape hatch for when the S-expression
|
|
syntax is not enough. It is not clear whether the OCaml syntax will be
|
|
supported in the long term as it doesn't work well with incremental
|
|
builds. It is possible that it will be replaced by just an ``include``
|
|
stanza where one can include a generated file.
|
|
|
|
Consequently **you must not** build complex systems based on it.
|