This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
241
unikernel/duniverse/dune_/doc/concepts/variables.rst
Normal file
241
unikernel/duniverse/dune_/doc/concepts/variables.rst
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
Variables
|
||||
=========
|
||||
|
||||
.. TODO(diataxis)
|
||||
- reference: variables
|
||||
- explanation: rule loading
|
||||
|
||||
Some fields can contains variables that are expanded by Dune.
|
||||
The syntax of variables is as follows:
|
||||
|
||||
.. code::
|
||||
|
||||
%{var}
|
||||
|
||||
or, for more complex forms that take an argument:
|
||||
|
||||
.. code::
|
||||
|
||||
%{fun:arg}
|
||||
|
||||
In order to write a plain ``%{``, you need to write ``\%{`` in a
|
||||
string.
|
||||
|
||||
Dune supports the following variables:
|
||||
|
||||
- ``project_root`` is the root of the current project. It is typically the root
|
||||
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`` isn't 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 will be used to compile foreign code. For
|
||||
more details about its content, please see :doc:`/reference/foreign-flags`.
|
||||
- ``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 that targets 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 extensions used for various artifacts.
|
||||
- ``ext_plugin`` is ``.cmxs`` if ``natdynlink`` is supported and
|
||||
``.cma`` otherwise.
|
||||
- ``ocaml-config:v`` is 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 OCaml versions
|
||||
need to be registered in Dune before they can be used.
|
||||
- ``profile`` is the profile selected via ``--profile``.
|
||||
- ``context_name`` is the name of the context (``default``, or defined in the
|
||||
workspace file)
|
||||
- ``os_type`` is the type of the OS the build is targeting. This is
|
||||
the same as ``ocaml-config:os_type``.
|
||||
- ``architecture`` is the type of the architecture the build is targeting. This
|
||||
is the same as ``ocaml-config:architecture``.
|
||||
- ``model`` is the type of the CPU the build is targeting. This is
|
||||
the same as ``ocaml-config:model``.
|
||||
- ``system`` is the name of the OS the build is targeting. This is the same as
|
||||
``ocaml-config:system``.
|
||||
- ``ignoring_promoted_rules`` is ``true`` if
|
||||
``--ignore-promoted-rules`` was passed on the command line and
|
||||
``false`` otherwise.
|
||||
- ``<ext>:<path>`` where ``<ext>`` is one of ``cmo``, ``cmi``, ``cma``,
|
||||
``cmx``, or ``cmxa``. See :ref:`variables-for-artifacts`.
|
||||
- ``env:<var>=<default`` expands to the value of the environment
|
||||
variable ``<var>``, or ``<default>`` if it does not exist.
|
||||
For example, ``%{env:BIN=/usr/bin}``.
|
||||
Available since Dune 1.4.0.
|
||||
- There are some Coq-specific variables detailed in :ref:`coq-variables`.
|
||||
|
||||
In addition, ``(action ...)`` fields support the following special variables:
|
||||
|
||||
- ``target`` expands to the one target.
|
||||
- ``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 ``<path>`` to ``program``. If ``program``
|
||||
is installed by a workspace package (see :doc:`/reference/dune/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 ...)``.
|
||||
- ``bin-available:<program>`` expands to ``true`` or ``false``, depending
|
||||
on whether ``<program>`` is available or not.
|
||||
- ``file-available:<path>`` expands to ``true`` or ``false``, depending on
|
||||
whether the file at ``<path>`` is available in the current workspace.
|
||||
- ``lib:<public-library-name>:<file>`` expands to the file's installation path
|
||||
``<file>`` in the 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 :term:`installed world` will be
|
||||
used.
|
||||
- ``lib-private:<library-name>:<file>`` expands to the file's build path
|
||||
``<file>`` in the library ``<library-name>``. Both public and private library
|
||||
names are allowed as long as they refer to libraries within the same project.
|
||||
- ``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.
|
||||
- ``libexec-private:<library-name>:<file>`` is the same as ``lib-private:...``
|
||||
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 if at least
|
||||
one of the following conditions holds:
|
||||
|
||||
- It's part the :term:`installed world`.
|
||||
- It's available locally and is not optional.
|
||||
- It's available locally, and all its library dependencies are
|
||||
available.
|
||||
|
||||
- ``version:<package>`` expands to the version of the given
|
||||
package. Packages defined in the current scope have priority over the
|
||||
public packages. Public packages that don't install any libraries
|
||||
will not be detected. How Dune determines the version
|
||||
of a package is described :doc:`here <../advanced/package-version>`.
|
||||
- ``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
|
||||
|
||||
#. Dealing with circular dependencies introduced by variables
|
||||
|
||||
If you ever see Dune reporting a dependency cycle that involves a
|
||||
variable such as `%{read:<path>}`, try to move `<path>` to a different
|
||||
directory.
|
||||
|
||||
The reason you might see such dependency cycle is because Dune is
|
||||
trying to evaluate the `%{read:<path>}` too early. For instance, let's
|
||||
consider the following example:
|
||||
|
||||
.. code:: dune
|
||||
|
||||
(rule
|
||||
(targets x)
|
||||
(enabled_if %{read:y})
|
||||
(action ...))
|
||||
|
||||
(rule
|
||||
(with-stdout-to y (...)))
|
||||
|
||||
When Dune loads and interprets this file, it decides whether the
|
||||
first rule is enabled by evaluating ``%{read:y}``. To
|
||||
evaluate ``%{read:y}``, it must build ``y``. To build ``y``, it must
|
||||
figure out the build rule that produces ``y``, and in order to do that, it must
|
||||
first load and evaluate the above ``dune`` file. You can see how this
|
||||
creates a cycle.
|
||||
|
||||
Some cycles might be more complex. In any case, when you see such an
|
||||
error, the easiest thing to do is move the file that's being read
|
||||
to a different directory, preferably a standalone one. You can use the
|
||||
:doc:`/reference/dune/subdir` stanza to keep the logic self-contained in
|
||||
the same ``dune`` file:
|
||||
|
||||
.. code:: dune
|
||||
|
||||
(rule
|
||||
(targets x)
|
||||
(enabled_if %{read:dir-for-y/y})
|
||||
(action ...))
|
||||
|
||||
(subdir
|
||||
dir-for-y
|
||||
(rule
|
||||
(with-stdout-to y (...))))
|
||||
|
||||
Expansion of Lists
|
||||
------------------
|
||||
|
||||
Forms that expand to a list of items, such as ``%{cc}``, ``%{deps}``,
|
||||
``%{targets}``, or ``%{read-lines:...}``, are suitable to be used in
|
||||
``(run <prog> <arguments>)``. For instance in:
|
||||
|
||||
.. code:: dune
|
||||
|
||||
(run foo %{deps})
|
||||
|
||||
If there are two dependencies, ``a`` and ``b``, the produced command
|
||||
will be equivalent to the shell command:
|
||||
|
||||
.. code:: console
|
||||
|
||||
$ foo "a" "b"
|
||||
|
||||
If you want both dependencies to be passed as a single argument,
|
||||
you must quote the variable:
|
||||
|
||||
.. code:: dune
|
||||
|
||||
(run foo "%{deps}")
|
||||
|
||||
which is equivalent to the following shell command:
|
||||
|
||||
.. code:: console
|
||||
|
||||
$ foo "a b"
|
||||
|
||||
(The items of the list are concatenated with space.)
|
||||
Please note: since ``%{deps}`` is a list of items, the first one may be
|
||||
used as a program name. For instance:
|
||||
|
||||
.. code:: dune
|
||||
|
||||
(rule
|
||||
(targets result.txt)
|
||||
(deps foo.exe (glob_files *.txt))
|
||||
(action (run %{deps})))
|
||||
|
||||
Here is another example:
|
||||
|
||||
.. code:: dune
|
||||
|
||||
(rule
|
||||
(target foo.exe)
|
||||
(deps foo.c)
|
||||
(action (run %{cc} -o %{target} %{deps} -lfoolib)))
|
||||
Loading…
Add table
Add a link
Reference in a new issue