Stanza Reference¶
dune-project¶
These files are used to mark the root of projects as well as define project-wide
parameters. The first line of dune-project
must be a lang
stanza with no
extra whitespace or comments. The lang
stanza controls the names and
contents of all configuration files read by Dune and looks like:
(lang dune 3.11)
Additionally, they can contains the following stanzas.
accept_alternative_dune_file_name¶
- (accept_alternative_dune_file_name ...)¶
New in version 3.0.
Specify that the alternative filename
dune-file
is accepted in addition todune
.This may be useful to avoid problems with
dune
files that have the executable permission in a directory in thePATH
, which can unwittingly happen on Windows.Note that
dune
continues to be accepted even after enabling this option, but if a file nameddune-file
is found in a directory, it will take precedence overdune
.
cram¶
- (cram <status>)¶
Define whether Cram-style tests are enabled for the project.
<status> can be either
enable
ordisable
. The default isenable
starting from the language version 3.0.See also
dialect¶
- (dialect ...)¶
Declare a new dialect.
- (name <name>)¶
The name of the dialect being defined. It must be unique in a given project.
This field is required.
- (implementation ...)¶
Details related to the implementation files (corresponding to *.ml).
Changed in version 3.9: This field is made optional.
- (extension <string>)¶
Specify the file extension used for this dialect.
The extension string must not start with a period and be unique in a given project (so that a given extension can be mapped back to a corresponding dialect). In Dune 3.9 and later, the extension string may contain periods (e.g., cppo.ml).
This field is required.
- (preprocess <action>)¶
Run <action> to produce a valid OCaml abstract syntax tree.
This action is expected to read the file given in the variable named
%{input-file}
and output a binary abstract syntax tree on its standard output.If the field is not present, it is assumed that the corresponding source code is already valid OCaml code and can be passed to the OCaml compiler as-is.
See also
- (format <action>)¶
Run <action> to format source code for this dialect.
The action is expected to read the file given in the variable named
%{input-file}
and output the formatted source code on its standard output.If the field is not present, the behaviour depends on the presence of
(preprocess)
: if it is also not present (that is, the dialect consists of valid OCaml code), then the dialect will be formatted as any other OCaml code. Otherwise no special formatting will be done.See also
- (interface ...)¶
Details related to the interface files (corresponding to *.mli).
This field supports the same sub-fields as
implementation
.Changed in version 3.9: This field is made optional.
executables_implicit_empty_intf¶
- (executables_implicit_empty_intf ...)¶
New in version 2.9.
Automatically generate empty interface files for executables and tests that do not already have them.
By default, executables defined via
(executables(s) ...)
or(test(s) ...)
stanzas are compiled with the interface file provided (e.g.,.mli
orrei
). Since these modules cannot be used as library dependencies, it is common to give them empty interface files to strengthen the compiler’s ability to detect unused values in these modules.This option, when enabled, will generate an empty *.mli file.
Example:
(executables_implicit_empty_intf true)
This option is enabled by default starting with Dune lang 3.0.
expand_aliases_in_sandbox¶
- (expand_aliases_in_sandbox ...)¶
When a sandboxed action depends on an alias, copy the expansion of the alias inside the sandbox. For instance, in the following example:
(alias (name foo) (deps ../x)) (cram (deps (alias foo)))
File x will be visible inside the Cram test if and only if this option is enabled. This option is a better default in general; however, it currently causes Cram tests to run noticeably slower. So it is disabled by default until the performance issue with Cram test is fixed.
explicit_js_mode¶
- (explicit_js_mode ...)¶
Do not implicitly add
js
to the(modes ...)
field of executables.In projects that use dune lang 1.x, JavaScript targets are defined for every bytecode executable. This is not very precise and does not interact well with the
@all
alias.It is possible to opt out of this behavior by using:
(explicit_js_mode)
When this is enabled, an explicit
js
mode needs to be added to the(modes ...)
field of executables in order to trigger the JavaScript compilation. Explicit JS targets declared like this will be attached to the@all
alias.Starting with Dune 2.0, this behavior is the default, and there is no way to disable it.
formatting¶
- (formatting ...)¶
New in version 2.0.
Control automatic formatting. Several forms are accepted:
To disable automatic formatting completely (equivalent to the behaviour in language 1.x):
(formatting disabled)
To restrict the languages that are considered for formatting:
(formatting (enabled_for <languages>))
The list of <languages> can be either
dune
(formatting of dune files) or a dialect name.
See also
generate_opam_files¶
- (generate_opam_files ...)¶
Use metadata specified in the
dune-project
file to generate.opam
files.To enable this integration, add the following field to the
dune-project
file:(generate_opam_files)
Dune uses the following global fields to set the metadata for all packages defined in the project:
- (license <strings>)¶
Specify the license of the project, ideally as an identifier from the SPDX License List.
Example:
(license MIT)
Multiple licenses may be specified.
- (authors <strings>)¶
Specify authors.
Example:
(authors "Jane Doe <jane.doe@example.com>" "John Doe <john.doe@example.com>")
- (maintainers <strings>)¶
Specify maintainers.
Example:
(maintainers "Jane Doe <jane.doe@example.com>" "John Doe <john.doe@example.com>")
- (source ...)¶
Specify where the source for the package can be found.
It can be specified as
(uri <uri>)
or using shortcuts for some hosting services:Service
Syntax
(github user/repo)
(bitbucket user/repo)
(gitlab user/repo)
(sourcehut user/repo)
Examples:
(source (github ocaml/dune))
(source (uri https://dev.example.com/project.git))
- (bug_reports <url>)¶
Where bugs should be reported.
If a hosting service is used in
(source)
, a default value is provided.Example:
(bug_reports https://dev.example.com/project/issues)
- (homepage <url>)¶
The homepage of the project.
If a hosting service is used in
(source)
, a default value is provided.Example:
(bug_reports https://example.com/)
- (documentation <url>)¶
Where the documentation is hosted.
With these fields, every time one calls Dune to execute some rules (either via
dune build
, dune runtest
, or something else), the opam files get
generated.
Some or all of these fields may be overridden for each package of the project, see package.
implicit_transitive_deps¶
- (implicit_transitive_deps ...)¶
Control whether transitive dependencies are made implicitly visible.
By default, Dune allows transitive dependencies of dependencies used when compiling OCaml. However, this can be disabled by specifying:
(implicit_transitive_deps false)
Then all dependencies directly used by a library or an executable must be added in the
libraries
field.We recommend users experiment with this mode and report any problems.
Note that you must use
threads.posix
instead ofthreads
when using this mode. This isn’t an important limitation, asthreads.vm
is deprecated anyway.In some situations, it can be desirable to selectively preserve the behavior of transitive dependencies’ availability a library’s users. For example, if we define a library
foo_more
that extendsfoo
, we might wantfoo_more
users to immediately havefoo
available as well. To do this, we must define the dependency onfoo
as re-exported:(library (name foo_more) (libraries (re_export foo)))
name¶
- (name <string>)¶
Set the name of the project.
It is used by dune subst and error messages.
opam_file_location¶
- (opam_file_location <location>)¶
New in version 3.8.
Configure where generated
.opam
files are located. <location> can be one of the following:relative_to_project
: the.opam
files are generated in the project root directory. This is the default.inside_opam_directory
: the.opam
files are generated in a directory namedopam
in the project root directory.
package¶
- (package ...)¶
Define package-specific metadata.
- (name <string>)¶
The name of the package.
This must be specified.
- (synopsis <string>)¶
A short package description.
- (description <string>)¶
A longer package description.
- (depends <dep-specification>)¶
Package dependencies, as
dep_specification
.
- (conflicts <dep-specification>)¶
Package conflicts, as
dep_specification
.
- (depopts <dep-specification>)¶
Optional package dependencies, as
dep_specification
.
- (tags <tags>)¶
A list of tags.
- (deprecated_package_names <name list>)¶
A list of names that can be used with the deprecated_library_name stanza to migrate legacy libraries from other build systems that do not follow Dune’s convention of prefixing the library’s public name with the package name.
- (license ...)¶
New in version 2.0.
The same as (and takes precedences over) the corresponding global field.
- (authors ...)¶
New in version 2.0.
The same as (and takes precedences over) the corresponding global field.
- (maintainers ...)¶
New in version 2.0.
The same as (and takes precedences over) the corresponding global field.
- (source ...)¶
New in version 2.0.
The same as (and takes precedences over) the corresponding global field.
- (bug_reports ...)¶
New in version 2.0.
The same as (and takes precedences over) the corresponding global field.
- (homepage ...)¶
New in version 2.0.
The same as (and takes precedences over) the corresponding global field.
- (documentation ...)¶
New in version 2.0.
The same as (and takes precedences over) the corresponding global field.
- (sites ...)¶
Define a site.
(sites (<section> <name>) ...)
defines a site named<name>
in the section<section>
.
Adding libraries to different packages is done via the public_name
and
package
fields. See library section for details.
The list of dependencies dep_specification
is modelled after
opam’s own language. The syntax is a list of the following elements:
op ::= '=' | '<' | '>' | '<>' | '>=' | '<=' filter ::= :dev | :build | :with-test | :with-doc | :post constr ::= (<op> <version>) logop ::= or | and dep ::= <name> (<name> <filter>) (<name> <constr>) (<name> (<logop> (<filter> | <constr>))*) dep_specification ::= <dep>+
Filters will expand to any opam variable name if prefixed by :
, not just the
ones listed in filter
. This also applies to version numbers.
For example, to generate depends: [ pkg { = version } ]
, use (depends
(pkg (= :version)))
.
Note that the use of a using
stanza (see using) doesn’t
automatically add the associated library or tool as a dependency. They have to
be added explicitly.
subst¶
- (subst <bool>)¶
Control whether dune subst is enabled for this project.
(subst disabled)
, means that any call ofdune subst
in this project is forbidden and will result in an error. This line will be omitted from the build instructions when generating opam files.(subst enabled)
allows substitutions explicitly. This is the default.
use_standard_c_and_cxx_flags¶
- (use_standard_c_and_cxx_flags ...)¶
New in version 2.8.
Control how flags coming grom
ocamlc -config
are passed to the C compiler command line.Historically, they have been systematically prepended without a way to override them.
If the following is passed, the mechanism is slightly altered:
(use_standard_c_and_cxx_flags)
In this mode, Dune will populate the
:standard
set of C flags with the content ofocamlc_cflags
andocamlc_cppflags
. These flags can be completed or overridden using the Ordered Set Language.This is the default in the language version 3.0.
using¶
- (using <plugin> <version>)¶
Enable a dune language extension.
The language of configuration files read by Dune can be extended to support additional stanzas (e.g.,
menhir
,coq.theory
,mdx
).<plugin> is the name of the plugin that defines this stanza and <version> describes the configuration language’s version. Note that this version has nothing to do with the version of the associated tool or library. In particular, adding a
using
stanza will not result in a build dependency in the generated.opam
file. See generate_opam_files.Example:
(using mdx 0.3)
version¶
- (version <version>)¶
Set the version of the project.
Example:
(version 1.2.3)
wrapped_executables¶
- (wrapped_executables <bool>)¶
New in version 1.11.
Control wrapping of modules in executables.
Executables are made of compilation units whose names may collide with libraries’ compilation units. To avoid this possibility, Dune prefixes these compilation unit names with
Dune__exe__
. This is entirely transparent to users except when such executables are debugged. In which case, the mangled names will be visible in the debugger.with
(wrapped_executables false)
, the original names are used.with
(wrapped_executables true)
, the names are mangled.
Starting in language version 2.0, the default value is
true
.
map_workspace_root¶
- (map_workspace_root <bool>)¶
Control references to the file system locations where the project has been built.
with
(map_workspace_root true)
, dune rewrites references to the workspace root to/workspace_root
. Note that when this mapping is enabled, the debug information produced by the bytecode compiler is incorrect, as the location information is lost.with
(map_workspace_root false)
, the references are not rewritten.
The default is
(map_workspace_root true)
.New in version 3.0: Initial version with the mapping always enabled.
Changed in version 3.7: Add a way to disable the mapping.
warnings¶
dune¶
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
Lexical Conventions.
dune
files are composed of stanzas, as shown below:
(library
(name mylib)
(libraries base lwt))
(rule
(target foo.ml)
(deps generator/gen.exe)
(action (run %{deps} -o %{target})))
The following sections describe the available stanzas and their meanings.
alias¶
The alias
stanza adds dependencies to an alias or specifies an action to run
to construct the alias.
The syntax is as follows:
(alias
(name <alias-name>)
(deps <deps-conf list>)
<optional-fields>)
<name>
is an alias name such as runtest
.
<deps-conf list>
specifies the dependencies of the alias. See
Dependency Specification for more details.
<optional-fields>
are:
<action>
, an action for constructing the alias. See User Actions for more details. Note that this is removed in Dune 2.0, so users must port their code to use therule
stanza with thealias
field instead.(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>))
specifies that the action must be run while holding the following locks. See Locks 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 Boolean Language, and the field allows for Variables to appear in the expressions.
The typical use of the alias
stanza is to define tests:
(rule
(alias runtest)
(action (run %{exe:my-test-program.exe} blah)))
See the section about Running Tests for details.
Please note: if your project contains several packages, and you run the tests
from the opam file using a build-test
field, all your runtest
alias
stanzas should have a (package ...)
field in order to partition the set of
tests.
cinaps¶
A cinaps
stanza is available to support the cinaps
tool. See the
cinaps website for more details.
copy_files¶
The copy_files
and copy_files#
stanzas specify that files from another
directory could be copied to the current directory, if needed.
The syntax is as follows:
(copy_files
<optional-fields>
(files <glob>))
<glob>
represents the set of files to copy. See the glob for
details.
<optional-fields>
are:
(alias <alias-name>)
specifies an alias to which to attach the targets.(mode <mode>)
specifies how to handle the targets. See modes for details.(enabled_if <blang expression>)
conditionally disables this stanza. The condition is specified using the Boolean Language.
The short form:
(copy_files <glob>)
is equivalent to:
(copy_files (files <glob>))
The difference between copy_files
and copy_files#
is the same as the
difference between the copy
and copy#
actions. See
User Actions section for more details.
coq.theory¶
See the documentation on the coq.theory, coq.extraction, coq.pp, and related stanzas.
data_only_dirs¶
New in version 1.6.
Dune allows the user to treat directories as data only. dune
files in
these directories won’t be evaluated for their rules, but the contents of these
directories will still be usable as dependencies for other rules.
The syntax is the same as for the dirs
stanza except that :standard
is
empty by default.
Example:
;; dune files in fixtures_* dirs are ignored
(data_only_dirs fixtures_*)
deprecated_library_name¶
The deprecated_library_name
stanza enables redirecting an old deprecated
name after a library has been renamed. It’s syntax is as follows:
(deprecated_library_name
(old_public_name <name>)
(new_public_name <name>))
When a developer uses the old public name in a list of library dependencies, it will be transparently replaced by the new name. Note that it’s not necessary for the new name to exist at definition time, as it is only resolved at the point where the old name is used.
The old_public_name
can also be one of the names declared in the
deprecated_package_names
field of the package declaration in the
dune-project
file. In this case, the “old” library is understood to be a
library whose name is not prefixed by the package name. Such a library cannot be
defined in Dune, but other build systems allow it. This feature is meant to help
migration from those systems.
dirs¶
New in version 1.6.
The dirs
stanza allows specifying the subdirectories Dune will include in a
build. The syntax is based on Dune’s Predicate Language and
allows the following operations:
The special value
:standard
which refers to the default set of used directories. These are the directories that don’t start with.
or_
.Set operations. Differences are expressed with backslash:
* \ bar
; unions are done by listing multiple items.Sets can be defined using globs.
Examples:
(dirs *) ;; include all directories
(dirs :standard \ ocaml) ;; include all dirs except ocaml
(dirs :standard \ test* foo*) ;; exclude all dirs that start with test or foo
Dune will not scan a directory that isn’t included in this stanza. Any contained
dune
(or other special) files won’t be interpreted either and will be
treated as raw data. It is however possible to depend on files inside ignored
subdirectories.
documentation¶
Additional manual pages may be attached to packages using the documentation
stanza. These .mld
files must contain text in the same syntax as OCamldoc
comments.
(documentation (<optional-fields>))
Where <optional-fields>
are:
(package <name>)
defines the package this documentation should be attached to. If this is absent, Dune will try to infer it based on the location of the stanza.(mld_files <arg>)
: the<arg>
field follows the Ordered Set Language. This is a set of extensionless MLD file basenames attached to the package, where:standard
refers to all the.mld
files in the stanza’s directory.
For more information, see Generating Documentation.
env¶
The env
stanza allows one to modify the environment. The syntax is as
follows:
(env
(<profile1> <settings1>)
(<profile2> <settings2>)
...
(<profilen> <settingsn>))
The first form (<profile> <settings>)
that corresponds to the selected build
profile will be used to modify the environment in this directory. You can use
_
to match any build profile.
Fields supported in <settings>
are:
any OCaml flags field. See OCaml Flags for more details.
(link_flags <flags>)
specifies flags to OCaml when linking an executable. See executables stanza.(c_flags <flags>)
and(cxx_flags <flags>)
specify compilation flags for C and C++ stubs, respectively. See library for more details.(env-vars (<var1> <val1>) .. (<varN> <valN>))
will add the corresponding variables to the environment where the build commands are executed and are used bydune exec
.(menhir_flags <flags>))
specifies flags for Menhir stanzas.(js_of_ocaml (flags <flags>)(build_runtime <flags>)(link_flags <flags>))
specifiesjs_of_ocaml
flags. See jsoo-field for more details.(js_of_ocaml (compilation_mode <mode>))
controls whether to use separate compilation or not where<mode>
is eitherwhole_program
orseparate
.(js_of_ocaml (runtest_alias <alias-name>))
specifies the alias under which Inline Tests and tests (tests-stanza) run for the js mode.(binaries <binaries>)
, where<binaries>
is a list of entries of the form(<filepath> as <name>)
.(<filepath> as <name>)
makes the binary<filepath>
available in the command search as just<name>
. For instance, in a(run <name> ...)
action,<name>
will resolve to this file path. You can also write just the file path, in which case the name will be inferred from the basename of<filepath>
by dropping the.exe
suffix, if it exists. For example,(binaries bin/foo.exe (bin/main.exe as bar))
would add the commandsfoo
andbar
to the search path.(inline_tests <state>)
, where<state>
is eitherenabled
,disabled
, orignored
. This field has been available since Dune 1.11. It controls the variable’s value%{inline_tests}
, which is read by the inline test framework. The default value isdisabled
for therelease
profile andenabled
otherwise.(odoc <fields>)
allows passing options toodoc
. See Passing Options to odoc for more details.(coq (flags <flags>))
allows passing options to Coq. See coq.theory for more details.(formatting <settings>)
allows the user to set auto-formatting in the current directory subtree (see formatting).(bin_annot <bool>)
allows the user to specify whether to generate *.cmt and *.cmti in the current directory subtree.
executable¶
The executable
stanza must be used to describe an executable. The format of
executable stanzas is as follows:
(executable
(name <name>)
<optional-fields>)
<name>
is a module name that contains the executable’s main entry point.
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
. If requested, it will also know how
to build <name>.bc
and <name>.bc.js
(Dune 2.0 and up also need specific
configuration (see the modes
optional field below).
<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
.
Please note: in case native compilation is not available, <name>.exe
will be
a custom bytecode executable, in the sense of ocamlc -custom
. This means
it’s a native executable that embeds the ocamlrun
virtual machine as well as
the bytecode, so 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 because running a bytecode executable often
requires loading shared libraries that are locally built. This requires
additional setup, such as setting specific environment variables, which Dune
doesn’t do at the moment.
Native compilation isn’t available when there is no ocamlopt
binary at the
same place as ocamlc
was found.
Executables can also be linked as object or shared object files. See linking modes for more information.
Starting from Dune 3.0, it’s possible to automatically generate empty interface files for executables. See executables_implicit_empty_intf.
<optional-fields>
are:
(public_name <public-name>)
specifies that the executable should be installed under this name. It’s the same as adding the following stanza to yourdune
file:(install (section bin) (files (<name>.exe as <public-name>)))
As a special case,
(public_name -)
is the same as if the field was absent.
Linking Modes¶
The modes
field allows selecting which linking modes will be used to link
executables. Each mode is a pair (<compilation-mode> <binary-kind>)
, where
<compilation-mode>
describes whether the bytecode 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 bytecode when native compilation isn’t
available.
<binary-kind>
is one of:
c
for producing OCaml bytecode embedded in a C fileexe
for normal executablesobject
for producing static object files that can be manually linked into C applicationsshared_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.js
for producing JavaScript from bytecode executables, see explicit_js_mode.plugin
for producing a plugin (.cmxs
if native or.cma
if bytecode).
For instance the following executables
stanza will produce bytecode
executables and native shared objects:
(executables
(names a b c)
(modes (byte exe) (native shared_object)))
Additionally, you can use the following shorthands:
c
for(byte c)
exe
for(best exe)
object
for(best object)
shared_object
for(best shared_object)
byte
for(byte exe)
native
for(native exe)
js
for(byte js)
plugin
for(best plugin)
For instance, the following modes
fields are all equivalent:
(modes (exe object shared_object))
(modes ((best exe)
(best object)
(best shared_object)))
Lastly, use the special mode byte_complete
for building a bytecode
executable as a native self-contained executable, i.e., an executable that
doesn’t require the ocamlrun
program to run and doesn’t require the C stubs
to be installed as shared object files.
The extensions for the various linking modes are chosen as follows:
%{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
.
Up to version 3.0 of the Dune language, when byte
is specified but none of
native
, exe
, or byte_complete
are specified, Dune implicitly adds a
linking mode that’s the same as byte_complete
, but it uses the extension
.exe
. .bc
files require additional files at runtime that aren’t
currently tracked by Dune, so they don’t run .bc
files during the build. Run
the .bc.exe
or .exe
ones instead, as these are self-contained.
Lastly, note that .bc
executables cannot contain C stubs. If your executable
contains C stubs you may want to use (modes exe)
.
js_of_ocaml¶
In library
and executables
stanzas, you can specify js_of_ocaml
options using (js_of_ocaml (<js_of_ocaml-options>))
.
<js_of_ocaml-options>
are all optional:
(flags <flags>)
to specify flags passed tojs_of_ocaml compile
. This field supports(:include ...)
forms(build_runtime_flags <flags>)
to specify flags passed tojs_of_ocaml build-runtime
. This field supports(:include ...)
forms(link_flags <flags>)
to specify flags passed tojs_of_ocaml link
. This field supports(:include ...)
forms(javascript_files (<files-list>))
to specifyjs_of_ocaml
JavaScript runtime files.
<flags>
is specified in the Ordered Set Language.
The default value for (flags ...)
depends on the selected build profile. The
build profile dev
(the default) will enable sourcemap and the pretty
JavaScript output.
See JavaScript Compilation With Js_of_ocaml for more information.
executables¶
There is a very subtle difference in the naming of these stanzas. One is
executables
, plural, and the other is executable
, singular. The
executables
stanza is very similar as the executable
stanza but can be
used to to describe several executables sharing the same configuration, so the
plural executables
stanza is used to describe more than one executable.
It shares the same fields as the executable
stanza, except that instead of
(name ...)
and (public_name ...)
you must use the plural versions as
well:
(names <names>)
where<names>
is a list of entry point names. Compare withexecutable
, where you only need to specify the modules containing the entry point of each executable.(public_names <names>)
describes under what name to install each executable. 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.
However, using executables
the executables defined in the stanza are
allowed to share modules.
Given modules Foo
, Bar
and Baz
the usage of executables
can
simplify the code:
(executables
(names foo bar))
Instead of the more complex
(library
(name baz)
(modules baz))
(executable
(name foo)
(modules foo)
(libraries baz))
(executable
(name bar)
(modules bar)
(libraries baz))
external_variant¶
This stanza was experimental and removed in Dune 2.6. See Variants.
foreign_library¶
The foreign_library
stanza describes archives of separately compiled foreign
object files that can be packaged with an OCaml library or linked into an OCaml
executable. See Foreign Sources, Archives, and Objects for further details and examples.
generate_sites_module¶
New in version 2.8.
Dune proposes some facilities for dealing with sites in a program.
The generate_sites_module
stanza will generate code for looking up the
correct locations of the sites’ directories and for loading plugins. It works
after installation with or without the relocation mode, inside Dune rules, and
when using Dune executables. For promotion, it works only if the generated
modules are solely in the executable (or library statically linked) promoted;
generated modules in plugins won’t work.
(generate_sites_module
(module <name>)
<facilities>)
The module’s code is generated in the directory with the given name. The code is populated according to the requested facilities.
The available <facilities>
are:
sourceroot
adds a valueval sourceroot: string option
in the generated module, which contains the value of%{workspace_root}
, if the code has been built locally. It could be used to keep the tool’s configuration file locally when executed withdune exec
or after promotion. The value isNone
once it has been installed.relocatable
adds a valueval relocatable: bool
in the generated module, which indicates if the binary has been installed in the relocatable mode.(sites <package>)
adds a valueval <site>: string list
for each<site>
of<package>
in the submodule Sites of the generated module. The identifier <site> isn’t capitalized.(plugins (<package> <site>) ...)
adds a submodule<site>
with the following signatureS
in the submodulePlugins
of the generated module . The identifier<site>
is capitalized.
module type S = sig
val paths: string list
(** return the locations of the directory containing the plugins *)
val list: unit -> string list
(** return the list of available plugins *)
val load_all: unit -> unit
(** load all the plugins and their dependencies *)
val load: string -> unit
(** load the specified plugin and its dependencies *)
end
The generated module is a dependency on the library dune-site
, and if the
facilities (plugins ...)
are used, it is a dependency on the library
dune-site.plugins
. Those dependencies are not automatically added to the
library or executable which use the module (cf. Plugins and Dynamic Loading of Packages).
ignored_subdirs¶
Deprecated since version 1.6.
One may also specify data only directories using the ignored_subdirs
stanza, meaning it’s the same as data_only_dirs
, but the syntax isn’t as
flexible and only accepts a list of directory names. It’s advised to switch to
the new data_only_dirs
stanza.
Example:
(ignored_subdirs (<sub-dir1> <sub-dir2> ...))
All of the specified <sub-dirn>
will be ignored by Dune. Note that users
should rely on the dirs
stanza along with the appropriate set operations
instead of this stanza. For example:
(dirs :standard \ <sub-dir1> <sub-dir2> ...)
include¶
The include
stanza allows including the contents of another file in the
current dune
file. Currently, the included file cannot be generated and must
be present in the source tree. This feature is intended for use in conjunction
with promotion, when parts of a dune
file are to be generated.
For instance:
(include dune.inc)
(rule (with-stdout-to dune.inc.gen (run ./gen-dune.exe)))
(rule
(alias runtest)
(action (diff dune.inc dune.inc.gen)))
With this dune
file, running Dune as follows will replace the dune.inc
file in the source tree by the generated one:
$ dune build @runtest --auto-promote
include_subdirs¶
The include_subdirs
stanza is used to control how Dune considers
subdirectories of the current directory. The syntax is as follows:
(include_subdirs <mode>)
Where <mode>
maybe be one of:
no
, the defaultunqualified
When the include_subdirs
stanza isn’t present or <mode>
is no
, Dune
considers subdirectories independent. When <mode>
is unqualified
, Dune
will assume that the current directory’s subdirectories are part of the same
group of directories. In particular, Dune will simultaneously scan all these
directories when looking for OCaml/Reason files. This allows you to split a
library between several directories. unqualified
means that modules in
subdirectories 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. We plan to add a qualified
mode in the future.
Note that subdirectories are included recursively; however, the recursion will
stop when encountering a subdirectory that contains another include_subdirs
stanza. Additionally, it’s not allowed for a subdirectory of a directory with
(include_subdirs <x>)
where <x>
is not no
to contain one of the
following stanzas:
library
executable(s)
test(s)
install¶
Dune supports installing packages on the system, i.e., copying freshly built
artifacts from the workspace to the system. The install
stanza takes three
pieces of information:
The list of files or directories to install
The package to attach these files. This field is optional if your project contains a single package.
The section in which the files will be installed
For instance:
(install
(files hello.txt)
(section share)
(package mypackage))
Indicate that the file hello.txt
in the current directory is to be installed
in <prefix>/share/mypackage
.
The following sections are available:
Section |
Target |
Remarks |
---|---|---|
|
|
|
|
|
|
|
|
executable bit is set |
|
|
executable bit is set |
|
|
executable bit is set |
|
|
executable bit is set |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
executable bit is set |
|
|
|
|
|
(see below) |
|
absolute destination |
(see below) |
|
|
(see below) |
Additional remarks:
For
man
, the exact destination is inferred from the file extension. For example,foo.1
is installed as<prefix>/man/man1/foo.1
.misc
only works when using opam. In that case, the user will be prompted before installation. This mechanism is deprecated.In the case of
(site)
, if the prefix isn’t the same as the one used when installing<package>
,<package>
won’t find the files.
Normally, Dune uses the file’s basename to determine the file’s name once
installed; however, you can change that by using the form (<filename> as
<destination>)
in the files
field. For instance, to install a file
mylib.el
as <prefix>/emacs/site-lisp/mylib.el
, you must write the
following:
(install
(section share_root)
(files (mylib.el as emacs/site-lisp/mylib.el)))
The mode of installed files is fully determined by the section they are
installed in. If the section above is documented as with the executable bit
set, they are installed with mode 0o755
(rwxr-xr-x
); otherwise they are
installed with mode 0o644
(rw-r--r--
).
Note that all files in the install stanza must be specified by relative paths only. It is an error to specify files by absolute paths.
Also note that as of dune-lang 3.11 (i.e., (lang dune 3.11)
in
dune-project
) it is deprecated to use the as
keyword to specify a
destination beginning with ..
. Dune intends for files associated with a
package to only be installed under specific directories in the file system
implied by the installation section (e.g., share
, bin
, doc
, etc.)
and the package name. Starting destination paths with ..
allows packages to
install files to arbitrary locations on the file system. In 3.11, this behaviour
is still supported (as some projects may depend on it) but will generate a
warning and will be removed in a future version of Dune.
Including Files in the Install Stanza¶
You can include external files from the files
and dirs
fields of the
install stanza:
(install
(files (include foo.sexp))
(section share))
Here the file foo.sexp
must contain a single S-expression list, whose
elements will be included in the list of files or directories to install. That
is, elements may be of the form:
<filename>
(<filename> as <destination>)
(include <filename>)
Included files may be generated by rules. Here is an example of a rule which
generates a file by listing all the files in a subdirectory resources
:
(rule
(deps (source_tree resources))
(action
(with-stdout-to foo.sexp
(system "echo '(' resources/* ')'"))))
Globs in the Install Stanza¶
You can use globs to specify files to install by using the terms (glob_files
<glob>)
and (glob_files_rec <glob>)
inside the files
field of the
install stanza (but not inside the dirs
field). See the glob
for details of the glob syntax. The (glob_files <glob>)
term will expand its
argument within a single directory, whereas the (glob_files_rec <glob>)
term
will recursively expand its argument within all subdirectories.
For example:
(install
(files
(glob_files style/*.css)
(glob_files_rec content/*.html))
(section share))
This example will install:
All files matching
*.css
in thestyle
directory.All files matching
*.html
in thecontent
directory, or any of its descendant subdirectories.
Note that the paths to files are preserved after installation. Suppose the
source directory contained the files style/foo.css
and
content/bar/baz.html
. The example above will place these files in
share/<package>/style/foo.css
and share/<package>/content/bar/baz.html
respectively where <package>
is the name of the package (ie.
dune-project
would contain (package (name <package>))
).
The with_prefix
keyword can be used to change the destination path of files
matched by a glob, similar to the as
keyword in the (files ...)
field.
with_prefix
changes the prefix of a path before the component matched by the
*
to some new value. For example:
(install
(files
(glob_files (style/*.css with_prefix web/stylesheets))
(glob_files_rec (content/*.html with_prefix web/documents)))
(section share))
Continuing the example above, this would result in the source file at
style/foo.css
being installed to share/<package>/web/stylesheets/foo.css
and content/bar/baz.html
being installed to
share/<package>/web/documents/bar/baz.html
. Note in the latter case
with_prefix
only replaced the content
component of the path and not the
bar
component since since it replaces the prefix of the glob - not the
prefix of paths matching the glob.
Installing Globs from Parent Directories¶
The default treatment of paths in globs creates a complication where referring
to globs in a parent directory such as (glob_files ../*.txt)
would attempt
to install the matched files outside the designated install directory. For
example writing:
(install
(files (glob_files ../*.txt))
(section share))
…would cause Dune to attempt to install the matching files to
share/<package>/../
, ie. share
where <package>
is the name of the
package (i.e., dune-project
would contain (package (name <package>))
).
This is probably not what the user intends, and installing files to relative
paths beginning with ..
is deprecated from version 3.11 of Dune and will
become an error in a future version.
The solution is to use with_prefix
to replace the ..
with some other
path. For example:
(install
(files (glob_files (../*.txt with_prefix .)))
(section share))
…would install the matched files to share/<package>/
instead.
Handling of the .exe Extension on Windows¶
Under Microsoft Windows, executables must be suffixed with .exe
. Dune tries
to ensure that executables are always installed with this extension on Windows.
More precisely, when installing a file via an (install ...)
stanza, Dune
implicitly adds the .exe
extension to the destination, if the source file
has extension .exe
or .bc
and if it’s not already present
Installing Source Directories¶
To install entire source directories, the source_tree
field can be used:
(install
(section doc)
(source_trees manual))
This example results in the contents of the manual
directory being installed
under <prefix>/doc/<package>/manual/
.
As with (files ...)
the destination can be changed with the as
keyword.
For example if you want to install all the files in the manual
directory
directly into <prefix>/doc/<package>/
you can write:
(install
(section doc)
(source_trees (manual as .)))
It’s also possible to specify multiple directories:
(install
(section doc)
(source_trees manual examples))
This would result in the local directories manual
and examples
being
installed to <prefix>/doc/<package>/manual/
and
<prefix>/doc/<package>/examples/
respectively.
Unlike with (files ...)
it is an error to begin the destination (the
right-hand side of as
) with ..
. (This is because support for installing
source directories was added to Dune after destinations beginning with ..
were deprecated.)
jbuild_version¶
Deprecated. This jbuild_version 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:
(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 it doesn’t need to start with
an uppercase letter.
For instance, the modules of a library named foo
will be available as
Foo.XXX
, outside of foo
itself; however, it is allowed to write an
explicit Foo
module, which will be the library interface. You are free to
expose only the modules you want.
Please note: 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 include_subdirs stanza.
<optional-fields>
are:
(public_name <name>)
- the name under which the library can be referred as a dependency when it’s not part of the current workspace, i.e., when it’s installed. Without a(public_name ...)
field, the library won’t be installed by Dune. The public name must start with the package name it’s part of and optionally followed by a dot, then anything else you want. The package name must also be one of the packages that Dune knows about, as determined by the logic described in Packages.(package <package>)
installs a private library under the specified package. Such a library is now usable by public libraries defined in the same project. The Findlib name for this library will be<package>.__private__.<name>
; however, the library’s interface will be hidden from consumers outside the project.(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 thedune
file. This includes ones 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 an uppercase letter. For instance, to exclude moduleFoo
, use(modules (:standard \ foo))
(libraries <library-dependencies>)
specifies the library’s dependencies. See Library Dependencies for more details.(wrapped <boolean>)
specifies whether the library modules should be available only through the top-level library module, or if they should all be exposed at the top level. The default istrue
, and it’s 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.(wrapped (transition <message>))
is the same as(wrapped true)
, except it will also generate unwrapped (not prefixed by the library name) modules to preserve compatibility. This is useful for libraries that would like to transition from(wrapped false)
to(wrapped true)
without breaking compatibility for users. The deprecation notices for the unwrapped modules will include<message>
.(preprocess <preprocess-spec>)
specifies how to preprocess files when needed. The default isno_preprocessing
, and other options are described in Preprocessing Specification.(preprocessor_deps (<deps-conf list>))
specifies extra preprocessor dependencies preprocessor, i.e., if the preprocessor reads a generated file. The specification of dependencies is described in Dependency Specification.(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. Use this to provide extra features without adding hard dependencies to your project(foreign_stubs <foreign-stubs-spec>)
specifies foreign source files, e.g., C or C++ stubs, to be compiled and packaged together with the library. See the section Foreign Sources, Archives, and Objects for more details. This field replaces the now-deleted fieldsc_names
,c_flags
,cxx_names
, andcxx_flags
.(foreign_archives <foreign-archives-list>)
specifies archives of foreign object files to be packaged with the library. See the section Foreign Archives for more details. This field replaces the now-deleted fieldself_build_stubs_archive
.(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. You should favor thepublic_headers
field starting from 3.8.(public_headers (<files>))
- if your library has public C header files that must be installed, you must list them in this field. This field accepts globs in the form of(glob_files_rec <glob>)
and(glob_files <glob>)
fields to specify multiple files.The advantage of this field over
install_c_headers
is that it preserves the directory structures of the headers relative to the library stanza. Additionally, it allows to specify the extensions of the header files, which allows alternative extensions such as.hh
or.hpp
.(modes <modes>)
is for 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
andbest
.best
isnative
orbyte
when native compilation isn’t available.(no_dynlink)
disables dynamic linking of the library. This is for advanced use only. By default, you shouldn’t set this option.(kind <kind>)
sets the type of library. The default isnormal
, but other available choices areppx_rewriter
andppx_deriver
. They must be set when the library is intended to be used as a PPX rewriter or a[@@deriving ...]
plugin. The reasonppx_rewriter
andppx_deriver
are split is historical, and hopefully we won’t need two options soon. Both PPX kinds support an optional field:(cookies <cookies>)
, where<cookies>
is a list of pairs(<name> <value>)
with<name>
being the cookie name and<value>
a string that supports Variables evaluated by each preprocessor invocation (note: libraries that share cookies with the same name should agree on their expanded value).(ppx_runtime_libraries (<library-names>))
is for when the library is appx 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. For instance, the case ofctypes
will only installctypes.foreign
if the dummyctypes-foreign
package is installed. You can specify such virtual dependencies here, but you don’t need to do so unless you use Dune to synthesize thedepends
anddepopts
sections of your opam file.js_of_ocaml
sets options for JavaScript compilation, see js_of_ocaml.For
flags
,ocamlc_flags
, andocamlopt_flags
, see OCaml Flags.(library_flags (<flags>))
is a list of flags passed toocamlc
andocamlopt
when building the library archive files. You can use this to specify-linkall
, for instance.<flags>
is a list of strings supporting Variables.(c_library_flags <flags>)
specifies the flags passed 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 write bindings for a C library namedbar
, you should typically write-lbar
here, or whatever flags are necessary to link against this library.(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 isn’t reasonably possible for Dune to check this is the case, Dune requires the user to explicitly list such modules to avoid surprises. Note that themodules_without_implementation
field isn’t merged inmodules
, which represents the total set of modules in a library. If a directory has more than one stanza, and thus amodules
field must be specified,<modules>
still needs to be added inmodules
.(private_modules <modules>)
specifies a list of modules that will be marked as private. Private modules are inaccessible from outside the libraries they are defined in. Note that theprivate_modules
field is not merged inmodules
, which represents the total set of modules in a library. If a directory has more than one stanza and thus amodules
field must be specified,<modules>
still need to be added inmodules
.(allow_overlapping_dependencies)
allows external dependencies to overlap with libraries that are present in the workspace.(enabled_if <blang expression>)
conditionally disables a library. A disabled library cannot be built and will not be installed. The condition is specified using the Boolean Language, and the field allows for the%{os_type}
variable, which is expanded to the type of OS being targeted by the current build. Its value is the same as the value of theos_type
parameter in the output ofocamlc -config
.(inline_tests)
enables inline tests for this library. They can be configured through options using(inline_tests <options>)
. See Inline Tests for a reference of corresponding options.(root_module <module>)
this field instructs Dune to generate a module that will contain module aliases for every library specified in dependencies. This is useful whenever a library is shadowed by a local module. The library may then still be accessible via this root module(ctypes <ctypes field>)
instructs Dune to use ctypes stubgen to process your type and function descriptions for binding system libraries, vendored libraries, or other foreign code. See Stub Generation with Dune Ctypes for a full reference. This field is available since the 3.0 version of the Dune language.(empty_module_interface_if_absent)
causes the generation of empty interfaces for every module that does not have an interface file already. Useful when modules are used solely for their side-effects. This field is available since the 3.0 version of the Dune language.
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 ...))
.
mdx¶
New in version 2.4.
MDX is a tool that helps you keep your markdown documentation up-to-date by
checking that its code examples are correct. When setting an MDX stanza, the MDX
checks are automatically attached to the runtest
alias of the stanza’s
directory.
See MDX’s repository for more details.
You can define an MDX stanza to specify which files you want checked.
Note that this feature is still experimental and needs to be enabled in your
dune-project
with the following using
stanza:
(using mdx 0.4)
Note
Version 0.2
of the stanza requires mdx 1.9.0
. Version 0.4
of the stanza requires mdx 2.3.0
.
The syntax is as follows:
(mdx <optional-fields>)
Where <optional-fields>
are:
(files <globs>)
are the files that you want MDX to check, described as a list of globs (see the Glob language specification ). It defaults to*.md *.mld
as of version0.4
of the stanza and*.md
before.(deps <deps-conf list>)
to specify the dependencies of your documentation code blocks. See Dependency Specification for more details.(preludes <files>)
are the prelude files you want to pass to MDX. See MDX’s documentation for more details on preludes.(libraries <libraries>)
are libraries that should be statically linked in the MDX test executable.(enabled_if <blang expression>)
is the same as the corresponding field of library.(package <package>)
specifies which package to attach this stanza to (similarly to when(package)
is attached to a(rule)
stanza). When-p
is passed,(mdx)
stanzas with another package will be ignored. Note that this feature is completely separate from(packages)
, which specifies some dependencies.(locks <lock-names>)
specifies that the action of running the tests holds the specified locks. See Locks for more details.
Upgrading from Version 0.1¶
The 0.2 version of the stanza requires at least MDX 1.9.0. If you encounter an error such as,
ocaml-mdx: unknown command `dune-gen'
, then you should upgrade MDX.The field
(packages <packages>)
is deprecated in version 0.2. You can use package items in the genericdeps
field instead:(deps (package <package>) ... (package <package>))
Use the new
libraries
field to directly link libraries in the test executable and remove the need for#require
directives in your documentation code blocks.
menhir¶
A menhir
stanza is available to support the Menhir parser generator.
To use Menhir in a Dune project, the language version should be selected in the
dune-project
file. For example:
(using menhir 2.0)
This will enable support for Menhir stanzas in the current project. If the language version is absent, Dune will automatically add this line with the latest Menhir version once a Menhir stanza is used anywhere.
The basic form for defining menhir-git parsers (analogous to ocamlyacc) is:
(menhir
(modules <parser1> <parser2> ...)
<optional-fields>)
<optional-fields>
are:
(merge_into <base_name>)
is used to define modular parsers. This correspond to the--base
command line option ofmenhir
. With this option, a single parser namedbase_name
is generated.(flags <option1> <option2> ...)
is used to pass extra flags to Menhir.(infer <bool>)
is used to enable Menhir with type inference. This option is enabled by default with Menhir language 2.0.
Menhir supports writing the grammar and automation to the .cmly
file.
Therefore, if this is flag is passed to Menhir, Dune will know to introduce a
.cmly
target for the module.
ocamllex¶
(ocamllex <names>)
is essentially a shorthand for:
(rule
(target <name>.ml)
(deps <name>.mll)
(action (chdir %{workspace_root}
(run %{bin:ocamllex} -q -o %{target} %{deps}))))
To use a different rule mode, use the long form:
(ocamllex
(modules <names>)
(mode <mode>))
ocamlyacc¶
(ocamlyacc <names>)
is essentially a shorthand for:
(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:
(ocamlyacc
(modules <names>)
(mode <mode>))
plugin¶
New in version 2.8.
Plugins are a way to load OCaml libraries at runtime. The plugin
stanza
allows you to declare the plugin’s name, which sites should be
present and which libraries it will load.
(plugin
(name <name>)
(libraries <libraries>)
(site (<package> <site name>))
(<optional-fields>))
<optional-fields>
are:
(package <package>)
if there is more than one package defined in the current scope, this specifies which package the plugin will install. A plugin can be installed by one package in the site of another package.(optional)
will not declare the plugin if the libraries are not available.
The loading of the plugin is done using the facilities generated by generate_sites_module.
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
User 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 (dirs …), 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 User 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.
subdir¶
The subdir
stanza can be used to evaluate stanzas in subdirectories. This is
useful for generated files or to override stanzas in vendored directories
without editing vendored dune
files.
In this example, a bar
target is created in the foo
directory, and a bar
target will be created in a/b/bar
:
(subdir foo (rule (with-stdout-to bar (echo baz))))
(subdir a/b (rule (with-stdout-to bar (echo baz))))
test¶
The test
stanza is the singular form of tests
. The only difference is
that it’s of the form:
(test
(name foo)
<optional fields>)
The name
field is singular, and the same optional fields are supported.
tests¶
The tests
stanza allows one to easily define multiple tests. For example, we
can define two tests at once with:
(tests
(names mytest expect_test)
<optional fields>)
This defines 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 supported are a subset of the alias and executables fields.
In particular, all fields except for public_names
are supported from the
executables stanza. Alias fields apart from name
are allowed.
The (enabled_if)
field has special semantics: when present, it only applies
to running the tests. The test executable is always built by default.
If you need to restrict building the test executable, use (build_if)
instead.
By default, the test binaries are run without options. The action
field can
override the test binary invocation, i.e., if you’re using Alcotest and wish to
see all the test failures on the standard output. When running Dune runtest
you can use the following stanza:
(tests
(names mytest)
(libraries alcotest mylib)
(action (run %{test} -e)))
Starting from Dune 2.9, it’s possible to automatically generate empty interface files for test executables. See executables_implicit_empty_intf.
toplevel¶
The toplevel
stanza allows one to define custom toplevels. Custom toplevels
automatically load a set of specified libraries and are runnable like normal
executables. Example:
(toplevel
(name tt)
(libraries str))
This will create a toplevel with the str
library loaded. We may build and
run this toplevel with:
$ dune exec ./tt.exe
(preprocess (pps ...))
is the same as the (preprocess (pps ...))
field
of library. Currently, action
and future_syntax
are not supported in
the toplevel.
vendored_dirs¶
New in version 1.11.
Dune supports vendoring other Dune-based projects natively, since simply copying a project into a subdirectory of your own project will work. Simply doing that has a few limitations though. You can workaround those by explicitly marking such directories as containing vendored code.
Example:
(vendored_dirs vendor)
Dune will not resolve aliases in vendored directories. By default, it won’t
build all installable targets, run the tests, format, or lint the code located
in such a directory while still building your project’s dependencies. Libraries
and executables in vendored directories will also be built with a -w -a
flag
to suppress all warnings and prevent pollution of your build output.
dune-workspace¶
By default, a workspace has only one build context named default
which
corresponds to the environment, in which dune
is run. You can define more
contexts by writing a dune-workspace
file.
You can point Dune to an explicit dune-workspace
file with the
--workspace
option. For instance, it’s good practice to write a
dune-workspace.dev
in your project with all the OCaml versions your projects
support, so developers can test that the code builds with all OCaml versions by
simply running:
$ dune build --workspace dune-workspace.dev @all @runtest
The dune-workspace
file uses the S-expression syntax. This is what a typical
dune-workspace
file looks like:
(lang dune 3.11)
(context (opam (switch 4.07.1)))
(context (opam (switch 4.08.1)))
(context (opam (switch 4.11.1)))
The rest of this section describe the stanzas available.
Note that an empty dune-workspace
file is interpreted the same as one
containing exactly:
(lang dune 3.2)
(context default)
This allows you to use an empty dune-workspace
file to mark the root of your
project.
env¶
The env
stanza can be used to set the base environment for all contexts in
this workspace. This environment has the lowest precedence of all other env
stanzas. The syntax for this stanza is the same as Dune’s env
stanza.
config
stanzas¶
Starting in Dune 3.0, any of the stanzas from the config file can be used
in the dune-workspace
file. In this case, the configuration stanza will only
affect the current workspace.
context¶
The (context ...)
stanza declares a build context. The argument can be
either default
or (default)
for the default build context, or it can be
the description of an opam switch, as follows:
(context (opam (switch <opam-switch-name>)
<optional-fields>))
<optional-fields>
are:
(name <name>)
is the subdirectory’s name for_build
, where this build’s context artifacts will be stored.(root <opam-root>)
is the opam root. By default, it will take the opam root defined by the environment in whichdune
is run, which is usually~/.opam
.(merlin)
instructs Dune to use this build context for Merlin.(profile <profile>)
sets a different profile for a build context. This has precedence over the command-line option--profile
.(env <env>)
sets the environment for a particular context. This is of higher precedence than the rootenv
stanza in the workspace file. This field has the same options as the env stanza.(toolchain <findlib_toolchain>)
sets afindlib
toolchain for the context.(host <host_context>)
chooses a different context to build binaries that are meant to be executed on the host machine, such as preprocessors.(paths (<var1> <val1>) .. (<varN> <valN>))
allows you to set the value of anyPATH
-like variables in this context. IfPATH
itself is modified in this way, its value will be used to resolve workspace binaries, including finding the compiler and related tools. These variables will also be passed as part of the environment to any program launched by Dune. For each variable, the value is specified using the Ordered Set Language. Relative paths are interpreted with respect to the workspace root. See Finding the Root.(fdo <target_exe>)
builds this context with feedback-direct optimizations. It requires OCamlFDO.<target_exe>
is a path-interpreted relative to the workspace root (see Finding the Root).<target_exe>
specifies which executable to optimize. Users should define a different context for each target executable built with FDO. The context name is derived automatically from the default name and<target-exe>
, unless explicitly specified using the(name ...)
field. For example, if<target_exe>
is src/foo.exe in a default context, then the name of the context is default-fdo-foo and the filename that contains execution counters is src/fdo.exe.fdo-profile. This feature is experimental and no backwards compatibility is implied.By default, Dune builds and installs dynamically-linked foreign archives (usually named
dll*.so
). It’s possible to disable this by setting by including(disable_dynamically_linked_foreign_archives true)
in the workspace file, so bytecode executables will be built with all foreign archives statically linked into the runtime system.
Both (default ...)
and (opam ...)
accept a targets
field in order to
setup cross compilation. See Cross-Compilation for more information.
Merlin reads compilation artifacts, and it can only read the compilation
artifacts of a single context. Usually, you should use the artifacts from the
default
context, and if you have the (context default)
stanza in your
dune-workspace
file, that is the one Dune will use.
For rare cases where this is not what you want, you can force Dune to use a
different build contexts for Merlin by adding the field (merlin)
to this
context.
profile¶
The build profile can be selected in the dune-workspace
file by write a
(profile ...)
stanza. For instance:
(profile release)
Note that the command line option --profile
has precedence over this stanza.
config¶
This file is used to set the global configuration of Dune which is applicable across projects and workspaces.
The configuration file is normally ~/.config/dune/config
on Unix systems and
%LOCALAPPDATA%/dune/config
on Windows. However, for most Dune commands it is
possible to specify an alternative configuration file with the --config-file
option. Command-line flags take precedence over the contents of the config
file. If --no-config
or -p
is passed, Dune will not read this file.
The config
file can contain the following stanzas:
action_stderr_on_success¶
Same as action_stdout_on_success, but applies to standard error instead of standard output.
action_stdout_on_success¶
Specifies how Dune should handle the standard output of actions when they succeed. This can be used to reduce the noise of large builds.
(action_stdout_on_success <setting>)
where <setting>
is one of:
print
prints the output on the terminal. This is the default.swallow
ignores the output and does not print it on the terminal.must-be-empty
enforces that the output should be empty. If it is not, Dune will fail.
cache¶
Specifies whether Dune is allowed to store and fetch build targets from the Dune cache.
(cache <setting>)
where <setting>
is one of:
enabled
enables Dune cache.disabled
disables Dune cache.
cache-check-probability¶
While the main purpose of Dune cache is to speed up build times, it can also be used to check build reproducibility. It is possible to enable a probabilistic check, in which Dune will re-execute randomly chosen build rules and compare their results with those stored in the cache. If the results differ, the rule is not reproducible, and Dune will print out a corresponding warning.
(cache-check-probability <number>)
where <number>
is a floating-point number between 0 and 1 (inclusive). 0
means never to check for reproducibility, and 1 means to always perform the
check.
cache-storage-mode¶
Specify the mechanism used by the Dune cache for storage.
(cache-storage-mode <setting>)
where <setting>
is one of:
auto
lets Dune decide the best mechanism to use.hardlink
uses hard links for entries in the cache. If the cache is stored in a different partition than the one where the build is taking place, then this mode will not work andcopy
should be used instead.copy
copies entries to the cache. This is less efficient than using hard links.
jobs¶
Maximum number of concurrent jobs Dune is allowed to have.
(jobs <setting>)
where <setting>
is one of:
auto
, auto-detect maximum number of cores. This is the default value.<number>
, a positive integer specifying the maximum number of jobs Dune may use simultaneously.
display¶
Specify the amount of Dune’s verbosity.
(display <setting>)
where <setting>
is one of:
progress
, Dune shows and updates a status line as build goals are being completed. This is the default value.verbose
prints the full command lines of programs being executed by Dune, with some colors to help differentiate programs.short
prints a line for each program executed with the binary name on the left and the targets of the action on the right.quiet
only display errors.
sandboxing_preference¶
The preferred sandboxing setting. Individual rules may specify different preferences. Dune will try to utilize a setting satisfying both conditions.
(sandboxing_preference <setting> <setting> ...)
where each <setting>
can be one of:
none
disables sandboxing.hardlink
uses hard links for sandboxing. This is the default under Linux.copy
copies files for sandboxing. This is the default under Windows.symlink
uses symbolic links for sandboxing.
terminal-persistence¶
Specifies how Dune handles the terminal when a rebuild is triggered in watch mode.
(terminal-persistence <setting>)
where <setting>
is one of:
preserve
does not clear the terminal screen beteween rebuilds.clear-on-rebuild
clears the terminal screen between rebuilds.clear-on-rebuild-and-flush-history
clears the terminal between rebuilds, and it also deletes everything in the scrollback buffer.