Merge pull request #956 from rgrinberg/lowercase-builtin-vars
Lowercase builtin vars
This commit is contained in:
commit
1b53107b66
|
@ -22,7 +22,7 @@ Stanzas
|
||||||
(rule
|
(rule
|
||||||
(targets foo.ml)
|
(targets foo.ml)
|
||||||
(deps generator/gen.exe)
|
(deps generator/gen.exe)
|
||||||
(action (run ${<} -o ${@})))
|
(action (run %{<} -o %{@})))
|
||||||
|
|
||||||
The following sections describe the available stanzas and their meaning.
|
The following sections describe the available stanzas and their meaning.
|
||||||
|
|
||||||
|
@ -336,16 +336,16 @@ compilation mode binary kind extensions
|
||||||
---------------- ------------- -----------------
|
---------------- ------------- -----------------
|
||||||
byte exe .bc and .bc.js
|
byte exe .bc and .bc.js
|
||||||
native/best exe .exe
|
native/best exe .exe
|
||||||
byte object .bc${ext_obj}
|
byte object .bc%{ext_obj}
|
||||||
native/best object .exe${ext_obj}
|
native/best object .exe%{ext_obj}
|
||||||
byte shared_object .bc${ext_dll}
|
byte shared_object .bc%{ext_dll}
|
||||||
native/best shared_object ${ext_dll}
|
native/best shared_object %{ext_dll}
|
||||||
================ ============= =================
|
================ ============= =================
|
||||||
|
|
||||||
Where ``${ext_obj}`` and ``${ext_dll}`` are the extensions for object
|
Where ``%{ext_obj}`` and ``%{ext_dll}`` are the extensions for object
|
||||||
and shared object files. Their value depends on the OS, for instance
|
and shared object files. Their value depends on the OS, for instance
|
||||||
on Unix ``${ext_obj}`` is usually ``.o`` and ``${ext_dll}`` is usually
|
on Unix ``%{ext_obj}`` is usually ``.o`` and ``%{ext_dll}`` is usually
|
||||||
``.so`` while on Windows ``${ext_obj}`` is ``.obj`` and ``${ext_dll}``
|
``.so`` while on Windows ``%{ext_obj}`` is ``.obj`` and ``%{ext_dll}``
|
||||||
is ``.dll``.
|
is ``.dll``.
|
||||||
|
|
||||||
Note that when ``(byte exe)`` is specified but neither ``(best exe)``
|
Note that when ``(byte exe)`` is specified but neither ``(best exe)``
|
||||||
|
@ -459,7 +459,7 @@ For instance:
|
||||||
(rule
|
(rule
|
||||||
(targets b
|
(targets b
|
||||||
(deps a
|
(deps a
|
||||||
(action (copy ${<} ${@})))))
|
(action (copy %{<} %{@})))))
|
||||||
|
|
||||||
In this example it is obvious by inspecting the action what the
|
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
|
dependencies and targets are. When this is the case you can use the
|
||||||
|
@ -483,7 +483,7 @@ stanza is rejected by dune:
|
||||||
|
|
||||||
.. code:: scheme
|
.. code:: scheme
|
||||||
|
|
||||||
(rule (copy a b.${read:file}))
|
(rule (copy a b.%{read:file}))
|
||||||
|
|
||||||
ocamllex
|
ocamllex
|
||||||
--------
|
--------
|
||||||
|
@ -495,7 +495,7 @@ ocamllex
|
||||||
(rule
|
(rule
|
||||||
(targets <name>.ml)
|
(targets <name>.ml)
|
||||||
(deps <name>.mll)
|
(deps <name>.mll)
|
||||||
(action (chdir ${ROOT} (run ${bin:ocamllex} -q -o ${<}))))
|
(action (chdir %{root} (run %{bin:ocamllex} -q -o %{<}))))
|
||||||
|
|
||||||
To use a different rule mode, use the long form:
|
To use a different rule mode, use the long form:
|
||||||
|
|
||||||
|
@ -515,7 +515,7 @@ ocamlyacc
|
||||||
(rule
|
(rule
|
||||||
(targets <name>.ml <name>.mli)
|
(targets <name>.ml <name>.mli)
|
||||||
(deps <name>.mly)
|
(deps <name>.mly)
|
||||||
(action (chdir ${ROOT} (run ${bin:ocamlyacc} ${<}))))
|
(action (chdir %{root} (run %{bin:ocamlyacc} %{<}))))
|
||||||
|
|
||||||
To use a different rule mode, use the long form:
|
To use a different rule mode, use the long form:
|
||||||
|
|
||||||
|
@ -573,7 +573,7 @@ The typical use of the ``alias`` stanza is to define tests:
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
(name runtest)
|
(name runtest)
|
||||||
(action (run ${exe:my-test-program.exe} blah)))
|
(action (run %{exe:my-test-program.exe} blah)))
|
||||||
|
|
||||||
See the section about :ref:`running-tests` for details.
|
See the section about :ref:`running-tests` for details.
|
||||||
|
|
||||||
|
@ -825,18 +825,18 @@ Variables are expanded after the set language is interpreted.
|
||||||
Variables expansion
|
Variables expansion
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Some fields can contains variables of the form ``$(var)`` or ``${var}`` that are
|
Some fields can contains variables of the form ``$(var)`` or ``%{var}`` that are
|
||||||
expanded by dune.
|
expanded by dune.
|
||||||
|
|
||||||
Dune supports the following variables:
|
Dune supports the following variables:
|
||||||
|
|
||||||
- ``ROOT`` is the relative path to the root of the build
|
- ``root`` is the relative path to the root of the build
|
||||||
context. Note that ``ROOT`` depends on the worksace
|
context. Note that ``root`` depends on the workspace
|
||||||
configuration. As such you shouldn't use ``ROOT`` to denote the
|
configuration. As such you shouldn't use ``root`` to denote the
|
||||||
root of your project. Use ``SCOPE_ROOT`` instead for this purpose
|
root of your project. Use ``project_root`` instead for this purpose
|
||||||
- ``SCOPE_ROOT`` is the root of the current scope. It is typically
|
- ``project_root`` is the root of the current scope. It is typically
|
||||||
the toplevel directory of your project and as long as you have at
|
the toplevel directory of your project and as long as you have at
|
||||||
least one ``<package>.opam`` file there, ``SCOPE_ROOT`` is
|
least one ``<package>.opam`` file there, ``project_root`` is
|
||||||
independent of the workspace configuration
|
independent of the workspace configuration
|
||||||
- ``CC`` is the C compiler command line (list made of the compiler
|
- ``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
|
name followed by its flags) that was used to compile OCaml in the
|
||||||
|
@ -844,13 +844,13 @@ Dune supports the following variables:
|
||||||
- ``CXX`` is the C++ compiler command line being used in the
|
- ``CXX`` is the C++ compiler command line being used in the
|
||||||
current build context
|
current build context
|
||||||
- ``ocaml_bin`` is the path where ``ocamlc`` lives
|
- ``ocaml_bin`` is the path where ``ocamlc`` lives
|
||||||
- ``OCAML`` is the ``ocaml`` binary
|
- ``ocaml`` is the ``ocaml`` binary
|
||||||
- ``OCAMLC`` is the ``ocamlc`` binary
|
- ``ocamlc`` is the ``ocamlc`` binary
|
||||||
- ``OCAMLOPT`` is the ``ocamlopt`` binary
|
- ``ocamlopt`` is the ``ocamlopt`` binary
|
||||||
- ``ocaml_version`` is the version of the compiler used in the
|
- ``ocaml_version`` is the version of the compiler used in the
|
||||||
current build context
|
current build context
|
||||||
- ``ocaml_where`` is the output of ``ocamlc -where``
|
- ``ocaml_where`` is the output of ``ocamlc -where``
|
||||||
- ``ARCH_SIXTYFOUR`` is ``true`` if using a compiler targeting a
|
- ``arch_sixtyfour`` is ``true`` if using a compiler targeting a
|
||||||
64 bit architecture and ``false`` otherwise
|
64 bit architecture and ``false`` otherwise
|
||||||
- ``null`` is ``/dev/null`` on Unix or ``nul`` on Windows
|
- ``null`` is ``/dev/null`` on Unix or ``nul`` on Windows
|
||||||
- ``ext_obj``, ``ext_asm``, ``ext_lib``, ``ext_dll`` and ``ext_exe``
|
- ``ext_obj``, ``ext_asm``, ``ext_lib``, ``ext_dll`` and ``ext_exe``
|
||||||
|
@ -878,8 +878,8 @@ In addition, ``(action ...)`` fields support the following special variables:
|
||||||
is installed by a package in the workspace (see `install`_ stanzas),
|
is installed by a package in the workspace (see `install`_ stanzas),
|
||||||
the locally built binary will be used, otherwise it will be searched
|
the locally built binary will be used, otherwise it will be searched
|
||||||
in the ``PATH`` of the current build context. Note that ``(run
|
in the ``PATH`` of the current build context. Note that ``(run
|
||||||
${bin:program} ...)`` and ``(run program ...)`` behave in the same
|
%{bin:program} ...)`` and ``(run program ...)`` behave in the same
|
||||||
way. ``${bin:...}`` is only necessary when you are using ``(bash
|
way. ``%{bin:...}`` is only necessary when you are using ``(bash
|
||||||
...)`` or ``(system ...)``
|
...)`` or ``(system ...)``
|
||||||
- ``lib:<public-library-name>:<file>`` expands to a path to file ``<file>`` of
|
- ``lib:<public-library-name>:<file>`` expands to a path to file ``<file>`` of
|
||||||
library ``<public-library-name>``. If ``<public-library-name>`` is available
|
library ``<public-library-name>``. If ``<public-library-name>`` is available
|
||||||
|
@ -906,10 +906,10 @@ In addition, ``(action ...)`` fields support the following special variables:
|
||||||
- ``read-strings:<path>`` expands to the list of lines in the given
|
- ``read-strings:<path>`` expands to the list of lines in the given
|
||||||
file, unescaped using OCaml lexical convention
|
file, unescaped using OCaml lexical convention
|
||||||
|
|
||||||
The ``${<kind>:...}`` forms are what allows you to write custom rules that work
|
The ``%{<kind>:...}`` forms are what allows you to write custom rules that work
|
||||||
transparently whether things are installed or not.
|
transparently whether things are installed or not.
|
||||||
|
|
||||||
Note that aliases are ignored by both ``${<}`` and ``${^}``.
|
Note that aliases are ignored by both ``%{<}`` and ``%{^}``.
|
||||||
|
|
||||||
The intent of this last form is to reliably read a list of strings
|
The intent of this last form is to reliably read a list of strings
|
||||||
generated by an OCaml program via:
|
generated by an OCaml program via:
|
||||||
|
@ -920,13 +920,13 @@ generated by an OCaml program via:
|
||||||
|
|
||||||
#. Expansion of lists
|
#. Expansion of lists
|
||||||
|
|
||||||
Forms that expands to list of items, such as ``${CC}``, ``${^}``,
|
Forms that expands to list of items, such as ``%{cc}``, ``%{^}``,
|
||||||
``${@}`` or ``${read-lines:...}``, are suitable to be used in, say,
|
``%{@}`` or ``%{read-lines:...}``, are suitable to be used in, say,
|
||||||
``(run <prog> <arguments>)``. For instance in:
|
``(run <prog> <arguments>)``. For instance in:
|
||||||
|
|
||||||
.. code:: scheme
|
.. code:: scheme
|
||||||
|
|
||||||
(run foo ${^})
|
(run foo %{^})
|
||||||
|
|
||||||
if there are two dependencies ``a`` and ``b``, the produced command
|
if there are two dependencies ``a`` and ``b``, the produced command
|
||||||
will be equivalent to the shell command:
|
will be equivalent to the shell command:
|
||||||
|
@ -940,7 +940,7 @@ you have to quote the variable as in:
|
||||||
|
|
||||||
.. code:: scheme
|
.. code:: scheme
|
||||||
|
|
||||||
(run foo "${^}")
|
(run foo "%{^}")
|
||||||
|
|
||||||
which is equivalent to the following shell command:
|
which is equivalent to the following shell command:
|
||||||
|
|
||||||
|
@ -949,7 +949,7 @@ which is equivalent to the following shell command:
|
||||||
$ foo "a b"
|
$ foo "a b"
|
||||||
|
|
||||||
(the items of the list are concatenated with space).
|
(the items of the list are concatenated with space).
|
||||||
Note that, since ``${^}`` is a list of items, the first one may be
|
Note that, since ``%{^}`` is a list of items, the first one may be
|
||||||
used as a program name, for instance:
|
used as a program name, for instance:
|
||||||
|
|
||||||
.. code:: scheme
|
.. code:: scheme
|
||||||
|
@ -957,7 +957,7 @@ used as a program name, for instance:
|
||||||
(rule
|
(rule
|
||||||
(targets result.txt)
|
(targets result.txt)
|
||||||
(deps foo.exe (glob_files *.txt))
|
(deps foo.exe (glob_files *.txt))
|
||||||
(action (run ${^})))
|
(action (run %{^})))
|
||||||
|
|
||||||
Here is another example:
|
Here is another example:
|
||||||
|
|
||||||
|
@ -966,7 +966,7 @@ Here is another example:
|
||||||
(rule
|
(rule
|
||||||
(targets foo.exe)
|
(targets foo.exe)
|
||||||
(deps foo.c)
|
(deps foo.c)
|
||||||
(action (run ${CC} -o ${@} ${<} -lfoolib)))
|
(action (run %{cc} -o %{@} %{<} -lfoolib)))
|
||||||
|
|
||||||
|
|
||||||
Library dependencies
|
Library dependencies
|
||||||
|
@ -1052,10 +1052,10 @@ you had setup a rule for every file of the form:
|
||||||
(rule
|
(rule
|
||||||
(targets file.pp.ml)
|
(targets file.pp.ml)
|
||||||
(deps file.ml)
|
(deps file.ml)
|
||||||
(action (with-stdout-to ${@} (chdir ${ROOT} <action>))))
|
(action (with-stdout-to %{@} (chdir %{root} <action>))))
|
||||||
|
|
||||||
The equivalent of a ``-pp <command>`` option passed to the OCaml compiler is
|
The equivalent of a ``-pp <command>`` option passed to the OCaml compiler is
|
||||||
``(system "<command> ${<}")``.
|
``(system "<command> %{<}")``.
|
||||||
|
|
||||||
Preprocessing with ppx rewriters
|
Preprocessing with ppx rewriters
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -1105,8 +1105,8 @@ For instance:
|
||||||
.. code:: scheme
|
.. code:: scheme
|
||||||
|
|
||||||
(preprocess (per_module
|
(preprocess (per_module
|
||||||
(((action (run ./pp.sh X=1 ${<})) (foo bar)))
|
(((action (run ./pp.sh X=1 %{<})) (foo bar)))
|
||||||
(((action (run ./pp.sh X=2 ${<})) (baz)))))
|
(((action (run ./pp.sh X=2 %{<})) (baz)))))
|
||||||
|
|
||||||
.. _deps-field:
|
.. _deps-field:
|
||||||
|
|
||||||
|
@ -1231,7 +1231,7 @@ 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
|
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
|
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
|
support `Variables expansion`_. Moreover, you don't need to specify dependencies
|
||||||
explicitly for the special ``${<kind>:...}`` forms, these are recognized and
|
explicitly for the special ``%{<kind>:...}`` forms, these are recognized and
|
||||||
automatically handled by dune.
|
automatically handled by dune.
|
||||||
|
|
||||||
The DSL is currently quite limited, so if you want to do something complicated
|
The DSL is currently quite limited, so if you want to do something complicated
|
||||||
|
@ -1289,15 +1289,15 @@ called ``copy-and-add-line-directive``. However, most of time one
|
||||||
wants this behavior rather than a bare copy, so it was renamed to
|
wants this behavior rather than a bare copy, so it was renamed to
|
||||||
something shorter.
|
something shorter.
|
||||||
|
|
||||||
Note: expansion of the special ``${<kind>:...}`` is done relative to the current
|
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
|
working directory of the part of the DSL being executed. So for instance if you
|
||||||
have this action in a ``src/foo/dune``:
|
have this action in a ``src/foo/dune``:
|
||||||
|
|
||||||
.. code:: scheme
|
.. code:: scheme
|
||||||
|
|
||||||
(action (chdir ../../.. (echo ${path:dune})))
|
(action (chdir ../../.. (echo %{path:dune})))
|
||||||
|
|
||||||
Then ``${path:dune}`` will expand to ``src/foo/dune``. When you run various
|
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.
|
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
|
As a result, if you execute the command from the original directory, it will
|
||||||
only see the basename.
|
only see the basename.
|
||||||
|
@ -1310,7 +1310,7 @@ To understand why this is important, let's consider this dune file living in
|
||||||
(rule
|
(rule
|
||||||
(targets blah.ml)
|
(targets blah.ml)
|
||||||
(deps blah.mll)
|
(deps blah.mll)
|
||||||
(action (run ocamllex -o ${@} ${<})))
|
(action (run ocamllex -o %{@} %{<})))
|
||||||
|
|
||||||
Here the command that will be executed is:
|
Here the command that will be executed is:
|
||||||
|
|
||||||
|
@ -1334,7 +1334,7 @@ of your project. What you should write instead is:
|
||||||
(rule
|
(rule
|
||||||
(targets blah.ml)
|
(targets blah.ml)
|
||||||
(deps blah.mll)
|
(deps blah.mll)
|
||||||
(action (chdir ${ROOT} (run ocamllex -o ${@} ${<}))))
|
(action (chdir %{root} (run ocamllex -o %{@} %{<}))))
|
||||||
|
|
||||||
Locks
|
Locks
|
||||||
-----
|
-----
|
||||||
|
@ -1357,13 +1357,13 @@ same lock:
|
||||||
(name runtest)
|
(name runtest)
|
||||||
(deps foo)
|
(deps foo)
|
||||||
(locks m)
|
(locks m)
|
||||||
(action (run test.exe ${<})))
|
(action (run test.exe %{<})))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
(name runtest)
|
(name runtest)
|
||||||
(deps bar)
|
(deps bar)
|
||||||
(locks m)
|
(locks m)
|
||||||
(action (run test.exe ${<})))
|
(action (run test.exe %{<})))
|
||||||
|
|
||||||
Dune will make sure that the executions of ``test.exe foo`` and
|
Dune will make sure that the executions of ``test.exe foo`` and
|
||||||
``test.exe bar`` are serialized.
|
``test.exe bar`` are serialized.
|
||||||
|
@ -1383,7 +1383,7 @@ simply use an absolute filename:
|
||||||
(name runtest)
|
(name runtest)
|
||||||
(deps foo)
|
(deps foo)
|
||||||
(locks /tcp-port/1042)
|
(locks /tcp-port/1042)
|
||||||
(action (run test.exe ${<})))
|
(action (run test.exe %{<})))
|
||||||
|
|
||||||
.. _ocaml-syntax:
|
.. _ocaml-syntax:
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,14 @@ Jbuild Dune
|
||||||
``${path:file}`` ``%{dep:file}``
|
``${path:file}`` ``%{dep:file}``
|
||||||
``${SCOPE_ROOT}`` ``%{project_root}``
|
``${SCOPE_ROOT}`` ``%{project_root}``
|
||||||
``${findlib:..}`` ``%{lib:..}``
|
``${findlib:..}`` ``%{lib:..}``
|
||||||
|
``${CPP}`` ``%{cpp}``
|
||||||
|
``${CC}`` ``%{cc}``
|
||||||
|
``${CXX}`` ``%{cxx}``
|
||||||
|
``${OCAML}`` ``%{ocaml}``
|
||||||
|
``${OCAMLC}`` ``%{ocamlc}``
|
||||||
|
``${OCAMLOPT}`` ``%{ocamlopt}``
|
||||||
|
``${ARCH_SIXTYFOUR}`` ``%{arch_sixtyfour}``
|
||||||
|
``${MAKE}`` ``%{make}``
|
||||||
======================== ============
|
======================== ============
|
||||||
|
|
||||||
Removed Variables
|
Removed Variables
|
||||||
|
|
|
@ -337,6 +337,9 @@ end
|
||||||
let prog_and_args_of_values p ~dir =
|
let prog_and_args_of_values p ~dir =
|
||||||
match p with
|
match p with
|
||||||
| [] -> (Unresolved.Program.Search "", [])
|
| [] -> (Unresolved.Program.Search "", [])
|
||||||
|
| Value.Dir p :: _ ->
|
||||||
|
die "%s is a directory and cannot be used as an executable"
|
||||||
|
(Path.to_string_maybe_quoted p)
|
||||||
| Value.Path p :: xs -> (This p, Value.L.to_strings ~dir xs)
|
| Value.Path p :: xs -> (This p, Value.L.to_strings ~dir xs)
|
||||||
| String s :: xs ->
|
| String s :: xs ->
|
||||||
(Unresolved.Program.of_string ~dir s, Value.L.to_strings ~dir xs)
|
(Unresolved.Program.of_string ~dir s, Value.L.to_strings ~dir xs)
|
||||||
|
|
|
@ -201,7 +201,7 @@ module Gen(P : Install_rules.Params) = struct
|
||||||
let copy_files_rules (def: Copy_files.t) ~src_dir ~dir ~scope =
|
let copy_files_rules (def: Copy_files.t) ~src_dir ~dir ~scope =
|
||||||
let loc = String_with_vars.loc def.glob in
|
let loc = String_with_vars.loc def.glob in
|
||||||
let glob_in_src =
|
let glob_in_src =
|
||||||
let src_glob = SC.expand_vars sctx ~dir def.glob ~scope in
|
let src_glob = SC.expand_vars_string sctx ~dir def.glob ~scope in
|
||||||
Path.relative src_dir src_glob ~error_loc:loc
|
Path.relative src_dir src_glob ~error_loc:loc
|
||||||
in
|
in
|
||||||
(* The following condition is required for merlin to work.
|
(* The following condition is required for merlin to work.
|
||||||
|
@ -1042,7 +1042,7 @@ module Gen(P : Install_rules.Params) = struct
|
||||||
| Copy_files { glob; _ } ->
|
| Copy_files { glob; _ } ->
|
||||||
let src_dir =
|
let src_dir =
|
||||||
let loc = String_with_vars.loc glob in
|
let loc = String_with_vars.loc glob in
|
||||||
let src_glob = SC.expand_vars sctx ~dir glob ~scope in
|
let src_glob = SC.expand_vars_string sctx ~dir glob ~scope in
|
||||||
Path.parent_exn (Path.relative src_dir src_glob ~error_loc:loc)
|
Path.parent_exn (Path.relative src_dir src_glob ~error_loc:loc)
|
||||||
in
|
in
|
||||||
Some
|
Some
|
||||||
|
|
|
@ -1238,7 +1238,7 @@ module Rule = struct
|
||||||
; action =
|
; action =
|
||||||
(loc,
|
(loc,
|
||||||
Chdir
|
Chdir
|
||||||
(S.virt_var __POS__ "ROOT",
|
(S.virt_var __POS__ "root",
|
||||||
Run (S.virt_text __POS__ "ocamllex",
|
Run (S.virt_text __POS__ "ocamllex",
|
||||||
[ S.virt_text __POS__ "-q"
|
[ S.virt_text __POS__ "-q"
|
||||||
; S.virt_text __POS__ "-o"
|
; S.virt_text __POS__ "-o"
|
||||||
|
@ -1259,7 +1259,7 @@ module Rule = struct
|
||||||
; action =
|
; action =
|
||||||
(loc,
|
(loc,
|
||||||
Chdir
|
Chdir
|
||||||
(S.virt_var __POS__ "ROOT",
|
(S.virt_var __POS__ "root",
|
||||||
Run (S.virt_text __POS__ "ocamlyacc",
|
Run (S.virt_text __POS__ "ocamlyacc",
|
||||||
[S.virt_var __POS__ "first-dep"])))
|
[S.virt_var __POS__ "first-dep"])))
|
||||||
; mode
|
; mode
|
||||||
|
|
|
@ -61,7 +61,7 @@ module Run (P : PARAMS) = struct
|
||||||
let sources ms =
|
let sources ms =
|
||||||
List.map ~f:source ms
|
List.map ~f:source ms
|
||||||
|
|
||||||
(* Expand special variables, such as ${ROOT}, in the stanza's flags. *)
|
(* Expand special variables, such as %{root}, in the stanza's flags. *)
|
||||||
|
|
||||||
let flags =
|
let flags =
|
||||||
SC.expand_and_eval_set
|
SC.expand_and_eval_set
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
open Import
|
||||||
|
|
||||||
|
module Var = struct
|
||||||
|
type t =
|
||||||
|
| Values of Value.t list
|
||||||
|
| Project_root
|
||||||
|
| First_dep
|
||||||
|
| Deps
|
||||||
|
| Targets
|
||||||
|
|
||||||
|
let to_value_no_deps_or_targets t ~scope =
|
||||||
|
match t with
|
||||||
|
| Values v -> Some v
|
||||||
|
| Project_root -> Some [Value.Dir (Scope.root scope)]
|
||||||
|
| First_dep
|
||||||
|
| Deps
|
||||||
|
| Targets -> None
|
||||||
|
end
|
||||||
|
|
||||||
|
module Macro = struct
|
||||||
|
type t =
|
||||||
|
| Exe
|
||||||
|
| Dep
|
||||||
|
| Bin
|
||||||
|
| Lib
|
||||||
|
| Libexec
|
||||||
|
| Lib_available
|
||||||
|
| Version
|
||||||
|
| Read
|
||||||
|
| Read_strings
|
||||||
|
| Read_lines
|
||||||
|
| Path_no_dep
|
||||||
|
end
|
||||||
|
|
||||||
|
type 'a t =
|
||||||
|
| No_info of 'a
|
||||||
|
| Since of 'a * Syntax.Version.t
|
||||||
|
| Deleted_in of 'a * Syntax.Version.t
|
||||||
|
| Renamed_in of Syntax.Version.t * string
|
||||||
|
|
||||||
|
module Map = struct
|
||||||
|
type nonrec 'a t = 'a t String.Map.t
|
||||||
|
|
||||||
|
let values v = No_info (Var.Values v)
|
||||||
|
let renamed_in ~new_name ~version = Renamed_in (version, new_name)
|
||||||
|
let deleted_in ~version kind = Deleted_in (kind, version)
|
||||||
|
let since ~version v = Since (v, version)
|
||||||
|
|
||||||
|
let static_vars =
|
||||||
|
[ "first-dep", since ~version:(1, 0) Var.First_dep
|
||||||
|
; "targets", since ~version:(1, 0) Var.Targets
|
||||||
|
; "deps", since ~version:(1, 0) Var.Deps
|
||||||
|
; "project_root", since ~version:(1, 0) Var.Project_root
|
||||||
|
|
||||||
|
; "<", renamed_in ~version:(1, 0) ~new_name:"first-dep"
|
||||||
|
; "@", renamed_in ~version:(1, 0) ~new_name:"targets"
|
||||||
|
; "^", renamed_in ~version:(1, 0) ~new_name:"deps"
|
||||||
|
; "SCOPE_ROOT", renamed_in ~version:(1, 0) ~new_name:"project_root"
|
||||||
|
]
|
||||||
|
|
||||||
|
let macros =
|
||||||
|
let macro kind = No_info kind in
|
||||||
|
let open Macro in
|
||||||
|
[ "exe", macro Exe
|
||||||
|
; "bin", macro Bin
|
||||||
|
; "lib", macro Lib
|
||||||
|
; "libexec", macro Libexec
|
||||||
|
; "lib-available", macro Lib_available
|
||||||
|
; "version", macro Version
|
||||||
|
; "read", macro Read
|
||||||
|
; "read-lines", macro Read_lines
|
||||||
|
; "read-strings", macro Read_strings
|
||||||
|
|
||||||
|
; "dep", since ~version:(1, 0) Dep
|
||||||
|
|
||||||
|
; "path", renamed_in ~version:(1, 0) ~new_name:"dep"
|
||||||
|
; "findlib", renamed_in ~version:(1, 0) ~new_name:"lib"
|
||||||
|
|
||||||
|
; "path-no-dep", deleted_in ~version:(1, 0) Path_no_dep
|
||||||
|
]
|
||||||
|
|> String.Map.of_list_exn
|
||||||
|
|
||||||
|
let create_vars ~(context : Context.t) ~cxx_flags =
|
||||||
|
let ocamlopt =
|
||||||
|
match context.ocamlopt with
|
||||||
|
| None -> Path.relative context.ocaml_bin "ocamlopt"
|
||||||
|
| Some p -> p
|
||||||
|
in
|
||||||
|
let string s = values [Value.String s] in
|
||||||
|
let path p = values [Value.Path p] in
|
||||||
|
let make =
|
||||||
|
match Bin.make with
|
||||||
|
| None -> string "make"
|
||||||
|
| Some p -> path p
|
||||||
|
in
|
||||||
|
let cflags = context.ocamlc_cflags in
|
||||||
|
let strings s = values (Value.L.strings s) in
|
||||||
|
let lowercased =
|
||||||
|
[ "cpp" , strings (context.c_compiler :: cflags @ ["-E"])
|
||||||
|
; "cc" , strings (context.c_compiler :: cflags)
|
||||||
|
; "cxx" , strings (context.c_compiler :: cxx_flags)
|
||||||
|
; "ocaml" , path context.ocaml
|
||||||
|
; "ocamlc" , path context.ocamlc
|
||||||
|
; "ocamlopt" , path ocamlopt
|
||||||
|
; "arch_sixtyfour" , string (string_of_bool context.arch_sixtyfour)
|
||||||
|
; "make" , make
|
||||||
|
; "root" , values [Value.Dir context.build_dir]
|
||||||
|
] in
|
||||||
|
let uppercased =
|
||||||
|
List.map lowercased ~f:(fun (k, _) ->
|
||||||
|
(String.uppercase k, renamed_in ~new_name:k ~version:(1, 0))) in
|
||||||
|
let vars =
|
||||||
|
[ "-verbose" , values []
|
||||||
|
; "pa_cpp" , strings (context.c_compiler :: cflags
|
||||||
|
@ ["-undef"; "-traditional";
|
||||||
|
"-x"; "c"; "-E"])
|
||||||
|
; "ocaml_bin" , path context.ocaml_bin
|
||||||
|
; "ocaml_version" , string context.version_string
|
||||||
|
; "ocaml_where" , string (Path.to_string context.stdlib_dir)
|
||||||
|
; "null" , string (Path.to_string Config.dev_null)
|
||||||
|
; "ext_obj" , string context.ext_obj
|
||||||
|
; "ext_asm" , string context.ext_asm
|
||||||
|
; "ext_lib" , string context.ext_lib
|
||||||
|
; "ext_dll" , string context.ext_dll
|
||||||
|
; "ext_exe" , string context.ext_exe
|
||||||
|
; "profile" , string context.profile
|
||||||
|
]
|
||||||
|
in
|
||||||
|
let ocaml_config =
|
||||||
|
List.map (Ocaml_config.to_list context.ocaml_config) ~f:(fun (k, v) ->
|
||||||
|
("ocaml-config:" ^ k,
|
||||||
|
match (v : Ocaml_config.Value.t) with
|
||||||
|
| Bool x -> string (string_of_bool x)
|
||||||
|
| Int x -> string (string_of_int x)
|
||||||
|
| String x -> string x
|
||||||
|
| Words x -> strings x
|
||||||
|
| Prog_and_args x -> strings (x.prog :: x.args)))
|
||||||
|
in
|
||||||
|
[ ocaml_config
|
||||||
|
; static_vars
|
||||||
|
; lowercased
|
||||||
|
; uppercased
|
||||||
|
; vars
|
||||||
|
]
|
||||||
|
|> List.concat
|
||||||
|
|> String.Map.of_list_exn
|
||||||
|
|
||||||
|
let static_vars = String.Map.of_list_exn static_vars
|
||||||
|
|
||||||
|
let rec expand t ~syntax_version ~var =
|
||||||
|
let name = String_with_vars.Var.name var in
|
||||||
|
Option.bind (String.Map.find t name) ~f:(fun v ->
|
||||||
|
let what var =
|
||||||
|
String_with_vars.Var.to_string (
|
||||||
|
if String_with_vars.Var.is_macro var then
|
||||||
|
String_with_vars.Var.with_payload var ~payload:(Some "..")
|
||||||
|
else
|
||||||
|
var)
|
||||||
|
in
|
||||||
|
match v with
|
||||||
|
| No_info v -> Some v
|
||||||
|
| Since (v, min_version) ->
|
||||||
|
if syntax_version >= min_version then
|
||||||
|
Some v
|
||||||
|
else
|
||||||
|
Syntax.Error.since (String_with_vars.Var.loc var)
|
||||||
|
Stanza.syntax min_version
|
||||||
|
~what:(what var)
|
||||||
|
| Renamed_in (in_version, new_name) -> begin
|
||||||
|
if syntax_version >= in_version then
|
||||||
|
Syntax.Error.renamed_in (String_with_vars.Var.loc var)
|
||||||
|
Stanza.syntax syntax_version
|
||||||
|
~what:(what var)
|
||||||
|
~to_:(what (String_with_vars.Var.with_name var ~name:new_name))
|
||||||
|
else
|
||||||
|
expand t ~syntax_version:in_version
|
||||||
|
~var:(String_with_vars.Var.with_name var ~name:new_name)
|
||||||
|
end
|
||||||
|
| Deleted_in (v, in_version) ->
|
||||||
|
if syntax_version < in_version then
|
||||||
|
Some v
|
||||||
|
else
|
||||||
|
Syntax.Error.deleted_in (String_with_vars.Var.loc var)
|
||||||
|
Stanza.syntax syntax_version ~what:(what var))
|
||||||
|
end
|
|
@ -0,0 +1,48 @@
|
||||||
|
module Var : sig
|
||||||
|
type t =
|
||||||
|
| Values of Value.t list
|
||||||
|
| Project_root
|
||||||
|
| First_dep
|
||||||
|
| Deps
|
||||||
|
| Targets
|
||||||
|
|
||||||
|
val to_value_no_deps_or_targets : t -> scope:Scope.t -> Value.t list option
|
||||||
|
end
|
||||||
|
|
||||||
|
module Macro : sig
|
||||||
|
type t =
|
||||||
|
| Exe
|
||||||
|
| Dep
|
||||||
|
| Bin
|
||||||
|
| Lib
|
||||||
|
| Libexec
|
||||||
|
| Lib_available
|
||||||
|
| Version
|
||||||
|
| Read
|
||||||
|
| Read_strings
|
||||||
|
| Read_lines
|
||||||
|
| Path_no_dep
|
||||||
|
end
|
||||||
|
|
||||||
|
type 'a t =
|
||||||
|
| No_info of 'a
|
||||||
|
| Since of 'a * Syntax.Version.t
|
||||||
|
| Deleted_in of 'a * Syntax.Version.t
|
||||||
|
| Renamed_in of Syntax.Version.t * string
|
||||||
|
|
||||||
|
module Map : sig
|
||||||
|
type 'a var
|
||||||
|
type 'a t
|
||||||
|
|
||||||
|
val create_vars : context:Context.t -> cxx_flags:string list -> Var.t t
|
||||||
|
|
||||||
|
val macros : Macro.t t
|
||||||
|
|
||||||
|
val static_vars : Var.t t
|
||||||
|
|
||||||
|
val expand
|
||||||
|
: 'a t
|
||||||
|
-> syntax_version:Syntax.Version.t
|
||||||
|
-> var:String_with_vars.Var.t
|
||||||
|
-> 'a option
|
||||||
|
end with type 'a var := 'a t
|
|
@ -398,7 +398,7 @@ let get_ppx_driver sctx ~loc ~scope ~dir_kind pps =
|
||||||
Ok (ppx_driver_exe sctx libs ~dir_kind, driver)
|
Ok (ppx_driver_exe sctx libs ~dir_kind, driver)
|
||||||
|
|
||||||
let target_var = String_with_vars.virt_var __POS__ "targets"
|
let target_var = String_with_vars.virt_var __POS__ "targets"
|
||||||
let root_var = String_with_vars.virt_var __POS__ "ROOT"
|
let root_var = String_with_vars.virt_var __POS__ "root"
|
||||||
|
|
||||||
let cookie_library_name lib_name =
|
let cookie_library_name lib_name =
|
||||||
match lib_name with
|
match lib_name with
|
||||||
|
|
|
@ -75,7 +75,7 @@ let report_with_backtrace exn =
|
||||||
Format.fprintf ppf "@{<error>Internal error, please report upstream \
|
Format.fprintf ppf "@{<error>Internal error, please report upstream \
|
||||||
including the contents of _build/log.@}\n\
|
including the contents of _build/log.@}\n\
|
||||||
Description:%a\n"
|
Description:%a\n"
|
||||||
(Usexp.pp Dune) sexp
|
Usexp.pp_quoted sexp
|
||||||
}
|
}
|
||||||
| Unix.Unix_error (err, func, fname) ->
|
| Unix.Unix_error (err, func, fname) ->
|
||||||
{ p with pp = fun ppf ->
|
{ p with pp = fun ppf ->
|
||||||
|
|
|
@ -37,6 +37,24 @@ module Make(H : Hashable.S) = struct
|
||||||
fold t ~init ~f:(fun ~key ~data acc -> f key data acc)
|
fold t ~init ~f:(fun ~key ~data acc -> f key data acc)
|
||||||
let fold t ~init ~f = foldi t ~init ~f:(fun _ x -> f x)
|
let fold t ~init ~f = foldi t ~init ~f:(fun _ x -> f x)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
let of_list l =
|
||||||
|
let h = create (List.length l) in
|
||||||
|
let rec loop = function
|
||||||
|
| [] -> Result.Ok h
|
||||||
|
| (k, v) :: xs ->
|
||||||
|
begin match find h k with
|
||||||
|
| None -> add h k v; loop xs
|
||||||
|
| Some v' -> Error (k, v', v)
|
||||||
|
end
|
||||||
|
in
|
||||||
|
loop l
|
||||||
|
|
||||||
|
let of_list_exn l =
|
||||||
|
match of_list l with
|
||||||
|
| Result.Ok h -> h
|
||||||
|
| Error (_, _, _) ->
|
||||||
|
Exn.code_error "Hashtbl.of_list_exn duplicate keys" []
|
||||||
end
|
end
|
||||||
|
|
||||||
open MoreLabels.Hashtbl
|
open MoreLabels.Hashtbl
|
||||||
|
|
|
@ -8,4 +8,6 @@ module type S = sig
|
||||||
|
|
||||||
val fold : 'a t -> init:'b -> f:('a -> 'b -> 'b) -> 'b
|
val fold : 'a t -> init:'b -> f:('a -> 'b -> 'b) -> 'b
|
||||||
val foldi : 'a t -> init:'b -> f:(key -> 'a -> 'b -> 'b) -> 'b
|
val foldi : 'a t -> init:'b -> f:(key -> 'a -> 'b -> 'b) -> 'b
|
||||||
|
|
||||||
|
val of_list_exn : (key * 'a) list -> 'a t
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,8 @@ let compare a b = Ordering.of_int (String.compare a b)
|
||||||
module T = struct
|
module T = struct
|
||||||
type t = StringLabels.t
|
type t = StringLabels.t
|
||||||
let compare = compare
|
let compare = compare
|
||||||
|
let equal (x : t) (y : t) = x = y
|
||||||
|
let hash (s : t) = Hashtbl.hash s
|
||||||
end
|
end
|
||||||
|
|
||||||
let capitalize = capitalize_ascii
|
let capitalize = capitalize_ascii
|
||||||
|
@ -201,6 +203,7 @@ let maybe_quoted s =
|
||||||
|
|
||||||
module Set = Set.Make(T)
|
module Set = Set.Make(T)
|
||||||
module Map = Map.Make(T)
|
module Map = Map.Make(T)
|
||||||
|
module Table = Hashtbl.Make(T)
|
||||||
|
|
||||||
let enumerate_gen s =
|
let enumerate_gen s =
|
||||||
let s = " " ^ s ^ " " in
|
let s = " " ^ s ^ " " in
|
||||||
|
|
|
@ -53,3 +53,4 @@ val enumerate_or : string list -> string
|
||||||
|
|
||||||
module Set : Set.S with type elt = t
|
module Set : Set.S with type elt = t
|
||||||
module Map : Map.S with type key = t
|
module Map : Map.S with type key = t
|
||||||
|
module Table : Hashtbl.S with type key = t
|
||||||
|
|
|
@ -196,18 +196,34 @@ module Var = struct
|
||||||
let loc (t : t) = t.loc
|
let loc (t : t) = t.loc
|
||||||
|
|
||||||
type kind =
|
type kind =
|
||||||
| Single of string
|
| Var of string
|
||||||
| Pair of string * string
|
| Macro of string * string
|
||||||
|
|
||||||
let destruct { loc = _ ; name; payload; syntax = _ } =
|
let destruct { loc = _ ; name; payload; syntax = _ } =
|
||||||
match payload with
|
match payload with
|
||||||
| None -> Single name
|
| None -> Var name
|
||||||
| Some p -> Pair (name, p)
|
| Some p -> Macro (name, p)
|
||||||
|
|
||||||
|
let name { name; _ } = name
|
||||||
|
|
||||||
let full_name t =
|
let full_name t =
|
||||||
match destruct t with
|
match destruct t with
|
||||||
| Single s -> s
|
| Var s -> s
|
||||||
| Pair (k, v) -> k ^ ":" ^ v
|
| Macro (k, v) -> k ^ ":" ^ v
|
||||||
|
|
||||||
|
let to_string = string_of_var
|
||||||
|
|
||||||
|
let pp fmt t = Format.pp_print_string fmt (to_string t)
|
||||||
|
|
||||||
|
let sexp_of_t t = Sexp.atom (to_string t)
|
||||||
|
|
||||||
|
let with_payload t ~payload =
|
||||||
|
{ t with payload }
|
||||||
|
|
||||||
|
let with_name t ~name =
|
||||||
|
{ t with name }
|
||||||
|
|
||||||
|
let is_macro t = Option.is_some t.payload
|
||||||
end
|
end
|
||||||
|
|
||||||
let partial_expand
|
let partial_expand
|
||||||
|
@ -262,8 +278,8 @@ let expand t ~mode ~dir ~f =
|
||||||
begin match var.syntax with
|
begin match var.syntax with
|
||||||
| Percent ->
|
| Percent ->
|
||||||
begin match Var.destruct var with
|
begin match Var.destruct var with
|
||||||
| Single v -> Loc.fail var.loc "unknown variable %S" v
|
| Var v -> Loc.fail var.loc "unknown variable %S" v
|
||||||
| Pair _ -> Loc.fail var.loc "unknown form %s" (string_of_var var)
|
| Macro _ -> Loc.fail var.loc "unknown form %s" (string_of_var var)
|
||||||
end
|
end
|
||||||
| Dollar_brace
|
| Dollar_brace
|
||||||
| Dollar_paren -> Some [Value.String (string_of_var var)]
|
| Dollar_paren -> Some [Value.String (string_of_var var)]
|
||||||
|
|
|
@ -49,14 +49,27 @@ end
|
||||||
module Var : sig
|
module Var : sig
|
||||||
type t
|
type t
|
||||||
|
|
||||||
|
val pp : t Fmt.t
|
||||||
|
|
||||||
|
val sexp_of_t : t -> Sexp.t
|
||||||
|
|
||||||
|
val name : t -> string
|
||||||
val loc : t -> Loc.t
|
val loc : t -> Loc.t
|
||||||
val full_name : t -> string
|
val full_name : t -> string
|
||||||
|
|
||||||
type kind =
|
type kind =
|
||||||
| Single of string
|
| Var of string
|
||||||
| Pair of string * string
|
| Macro of string * string
|
||||||
|
|
||||||
val destruct : t -> kind
|
val destruct : t -> kind
|
||||||
|
|
||||||
|
val to_string : t -> string
|
||||||
|
|
||||||
|
val with_name : t -> name:string -> t
|
||||||
|
|
||||||
|
val with_payload : t -> payload:string option -> t
|
||||||
|
|
||||||
|
val is_macro : t -> bool
|
||||||
end
|
end
|
||||||
|
|
||||||
val expand
|
val expand
|
||||||
|
|
|
@ -45,7 +45,8 @@ type t =
|
||||||
; artifacts : Artifacts.t
|
; artifacts : Artifacts.t
|
||||||
; stanzas_to_consider_for_install : Installable.t list
|
; stanzas_to_consider_for_install : Installable.t list
|
||||||
; cxx_flags : string list
|
; cxx_flags : string list
|
||||||
; vars : Value.t list String.Map.t
|
; vars : Pform.Var.t Pform.Map.t
|
||||||
|
; macros : Pform.Macro.t Pform.Map.t
|
||||||
; chdir : (Action.t, Action.t) Build.t
|
; chdir : (Action.t, Action.t) Build.t
|
||||||
; host : t option
|
; host : t option
|
||||||
; libs_by_package : (Package.t * Lib.Set.t) Package.Name.Map.t
|
; libs_by_package : (Package.t * Lib.Set.t) Package.Name.Map.t
|
||||||
|
@ -84,26 +85,34 @@ let installed_libs t = t.installed_libs
|
||||||
let find_scope_by_dir t dir = Scope.DB.find_by_dir t.scopes dir
|
let find_scope_by_dir t dir = Scope.DB.find_by_dir t.scopes dir
|
||||||
let find_scope_by_name t name = Scope.DB.find_by_name t.scopes name
|
let find_scope_by_name t name = Scope.DB.find_by_name t.scopes name
|
||||||
|
|
||||||
let expand_var_no_root t var = String.Map.find t.vars var
|
let expand_vars t ~syntax_version ~var =
|
||||||
|
if String_with_vars.Var.is_macro var then
|
||||||
|
Loc.fail (String_with_vars.Var.loc var)
|
||||||
|
"macros of the form %%{name:..} cannot be expanded here"
|
||||||
|
else
|
||||||
|
Pform.Map.expand t.vars ~syntax_version ~var
|
||||||
|
|
||||||
let (expand_vars, expand_vars_path) =
|
let expand_macro t ~syntax_version ~var =
|
||||||
|
if String_with_vars.Var.is_macro var then
|
||||||
|
Pform.Map.expand t.macros ~syntax_version ~var
|
||||||
|
else
|
||||||
|
Exn.code_error "expand_macro can't expand variables"
|
||||||
|
[ "var", String_with_vars.Var.sexp_of_t var ]
|
||||||
|
|
||||||
|
let (expand_vars_string, expand_vars_path) =
|
||||||
let expand t ~scope ~dir ?(extra_vars=String.Map.empty) s =
|
let expand t ~scope ~dir ?(extra_vars=String.Map.empty) s =
|
||||||
String_with_vars.expand ~mode:Single ~dir s ~f:(fun v syntax_version ->
|
String_with_vars.expand ~mode:Single ~dir s ~f:(fun var syntax_version ->
|
||||||
match String_with_vars.Var.full_name v with
|
match expand_vars t ~syntax_version ~var with
|
||||||
| "ROOT" -> Some [Value.Path t.context.build_dir]
|
| None ->
|
||||||
| "SCOPE_ROOT" ->
|
String.Map.find extra_vars (String_with_vars.Var.full_name var)
|
||||||
if syntax_version >= (1, 0) then
|
| Some v ->
|
||||||
Loc.fail (String_with_vars.Var.loc v)
|
begin match Pform.Var.to_value_no_deps_or_targets ~scope v with
|
||||||
"Variable %%{SCOPE_ROOT} has been renamed to %%{project_root} \
|
| Some _ as v -> v
|
||||||
in dune files"
|
| None ->
|
||||||
else
|
Loc.fail (String_with_vars.Var.loc var)
|
||||||
Some [Value.Path (Scope.root scope)]
|
"Variable %a is not allowed in this context"
|
||||||
| "project_root" when syntax_version >= (1, 0) ->
|
String_with_vars.Var.pp var
|
||||||
Some [Value.Path (Scope.root scope)]
|
end)
|
||||||
| var ->
|
|
||||||
(match expand_var_no_root t var with
|
|
||||||
| Some _ as x -> x
|
|
||||||
| None -> String.Map.find extra_vars var))
|
|
||||||
in
|
in
|
||||||
let expand_vars t ~scope ~dir ?extra_vars s =
|
let expand_vars t ~scope ~dir ?extra_vars s =
|
||||||
expand t ~scope ~dir ?extra_vars s
|
expand t ~scope ~dir ?extra_vars s
|
||||||
|
@ -117,7 +126,7 @@ let (expand_vars, expand_vars_path) =
|
||||||
|
|
||||||
let expand_and_eval_set t ~scope ~dir ?extra_vars set ~standard =
|
let expand_and_eval_set t ~scope ~dir ?extra_vars set ~standard =
|
||||||
let open Build.O in
|
let open Build.O in
|
||||||
let f = expand_vars t ~scope ~dir ?extra_vars in
|
let f = expand_vars_string t ~scope ~dir ?extra_vars in
|
||||||
let parse ~loc:_ s = s in
|
let parse ~loc:_ s = s in
|
||||||
let (syntax, files) = Ordered_set_lang.Unexpanded.files set ~f in
|
let (syntax, files) = Ordered_set_lang.Unexpanded.files set ~f in
|
||||||
match String.Set.to_list files with
|
match String.Set.to_list files with
|
||||||
|
@ -280,61 +289,7 @@ let create
|
||||||
List.filter context.ocamlc_cflags
|
List.filter context.ocamlc_cflags
|
||||||
~f:(fun s -> not (String.is_prefix s ~prefix:"-std="))
|
~f:(fun s -> not (String.is_prefix s ~prefix:"-std="))
|
||||||
in
|
in
|
||||||
let vars =
|
let vars = Pform.Map.create_vars ~context ~cxx_flags in
|
||||||
let ocamlopt =
|
|
||||||
match context.ocamlopt with
|
|
||||||
| None -> Path.relative context.ocaml_bin "ocamlopt"
|
|
||||||
| Some p -> p
|
|
||||||
in
|
|
||||||
let string s = [Value.String s] in
|
|
||||||
let path p = [Value.Path p] in
|
|
||||||
let make =
|
|
||||||
match Bin.make with
|
|
||||||
| None -> string "make"
|
|
||||||
| Some p -> path p
|
|
||||||
in
|
|
||||||
let cflags = context.ocamlc_cflags in
|
|
||||||
let strings = Value.L.strings in
|
|
||||||
let vars =
|
|
||||||
[ "-verbose" , []
|
|
||||||
; "CPP" , strings (context.c_compiler :: cflags @ ["-E"])
|
|
||||||
; "PA_CPP" , strings (context.c_compiler :: cflags
|
|
||||||
@ ["-undef"; "-traditional";
|
|
||||||
"-x"; "c"; "-E"])
|
|
||||||
; "CC" , strings (context.c_compiler :: cflags)
|
|
||||||
; "CXX" , strings (context.c_compiler :: cxx_flags)
|
|
||||||
; "ocaml_bin" , path context.ocaml_bin
|
|
||||||
; "OCAML" , path context.ocaml
|
|
||||||
; "OCAMLC" , path context.ocamlc
|
|
||||||
; "OCAMLOPT" , path ocamlopt
|
|
||||||
; "ocaml_version" , string context.version_string
|
|
||||||
; "ocaml_where" , string (Path.to_string context.stdlib_dir)
|
|
||||||
; "ARCH_SIXTYFOUR" , string (string_of_bool context.arch_sixtyfour)
|
|
||||||
; "MAKE" , make
|
|
||||||
; "null" , string (Path.to_string Config.dev_null)
|
|
||||||
; "ext_obj" , string context.ext_obj
|
|
||||||
; "ext_asm" , string context.ext_asm
|
|
||||||
; "ext_lib" , string context.ext_lib
|
|
||||||
; "ext_dll" , string context.ext_dll
|
|
||||||
; "ext_exe" , string context.ext_exe
|
|
||||||
; "profile" , string context.profile
|
|
||||||
]
|
|
||||||
in
|
|
||||||
let vars =
|
|
||||||
vars @
|
|
||||||
List.map (Ocaml_config.to_list context.ocaml_config) ~f:(fun (k, v) ->
|
|
||||||
("ocaml-config:" ^ k,
|
|
||||||
match (v : Ocaml_config.Value.t) with
|
|
||||||
| Bool x -> string (string_of_bool x)
|
|
||||||
| Int x -> string (string_of_int x)
|
|
||||||
| String x -> string x
|
|
||||||
| Words x -> strings x
|
|
||||||
| Prog_and_args x -> strings (x.prog :: x.args)))
|
|
||||||
in
|
|
||||||
match String.Map.of_list vars with
|
|
||||||
| Ok x -> x
|
|
||||||
| Error _ -> assert false
|
|
||||||
in
|
|
||||||
let t =
|
let t =
|
||||||
{ context
|
{ context
|
||||||
; host
|
; host
|
||||||
|
@ -349,6 +304,7 @@ let create
|
||||||
; artifacts
|
; artifacts
|
||||||
; cxx_flags
|
; cxx_flags
|
||||||
; vars
|
; vars
|
||||||
|
; macros = Pform.Map.macros
|
||||||
; chdir = Build.arr (fun (action : Action.t) ->
|
; chdir = Build.arr (fun (action : Action.t) ->
|
||||||
match action with
|
match action with
|
||||||
| Chdir _ -> action
|
| Chdir _ -> action
|
||||||
|
@ -528,7 +484,7 @@ module Deps = struct
|
||||||
Build.source_tree ~dir:path ~file_tree:t.file_tree
|
Build.source_tree ~dir:path ~file_tree:t.file_tree
|
||||||
>>^ Path.Set.to_list
|
>>^ Path.Set.to_list
|
||||||
| Package p ->
|
| Package p ->
|
||||||
let pkg = Package.Name.of_string (expand_vars t ~scope ~dir p) in
|
let pkg = Package.Name.of_string (expand_vars_string t ~scope ~dir p) in
|
||||||
Alias.dep (Alias.package_install ~context:t.context ~pkg)
|
Alias.dep (Alias.package_install ~context:t.context ~pkg)
|
||||||
>>^ fun () -> []
|
>>^ fun () -> []
|
||||||
| Universe ->
|
| Universe ->
|
||||||
|
@ -636,40 +592,20 @@ module Action = struct
|
||||||
; ddeps = String.Map.empty
|
; ddeps = String.Map.empty
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
let expand var syntax_version =
|
let expand_form s var syntax_version =
|
||||||
let loc = String_with_vars.Var.loc var in
|
let loc = String_with_vars.Var.loc var in
|
||||||
let key = String_with_vars.Var.full_name var in
|
let key = String_with_vars.Var.full_name var in
|
||||||
let path_with_dep s =
|
begin match expand_macro sctx ~syntax_version ~var with
|
||||||
Some (path_exp (Path.relative dir s) )
|
| Some Pform.Macro.Exe -> Some (path_exp (map_exe (Path.relative dir s)))
|
||||||
in
|
| Some Dep -> Some (path_exp (Path.relative dir s))
|
||||||
match String_with_vars.Var.destruct var with
|
| Some Bin -> begin
|
||||||
| Pair ("exe", s) -> Some (path_exp (map_exe (Path.relative dir s)))
|
|
||||||
| Pair ("path", s) when syntax_version < (1, 0) ->
|
|
||||||
path_with_dep s
|
|
||||||
| Pair ("dep", s) when syntax_version >= (1, 0) ->
|
|
||||||
path_with_dep s
|
|
||||||
| Pair ("dep", s) ->
|
|
||||||
Loc.fail
|
|
||||||
loc
|
|
||||||
"${dep:%s} is not supported in jbuild files.\n\
|
|
||||||
Hint: Did you mean ${path:%s} instead?"
|
|
||||||
s
|
|
||||||
s
|
|
||||||
| Pair ("bin", s) -> begin
|
|
||||||
let sctx = host sctx in
|
let sctx = host sctx in
|
||||||
match Artifacts.binary (artifacts sctx) s with
|
match Artifacts.binary (artifacts sctx) s with
|
||||||
| Ok path -> Some (path_exp path)
|
| Ok path -> Some (path_exp path)
|
||||||
| Error e ->
|
| Error e ->
|
||||||
add_fail acc ({ fail = fun () -> Action.Prog.Not_found.raise e })
|
add_fail acc ({ fail = fun () -> Action.Prog.Not_found.raise e })
|
||||||
end
|
end
|
||||||
| Pair ("findlib", s) when syntax_version >= (1, 0) ->
|
| Some Lib -> begin
|
||||||
Loc.fail
|
|
||||||
loc
|
|
||||||
"The findlib special variable is not supported in jbuild files, \
|
|
||||||
please use lib instead:\n%%{lib:%s} in dune files"
|
|
||||||
s
|
|
||||||
| Pair ("findlib", s)
|
|
||||||
| Pair ("lib", s) -> begin
|
|
||||||
let lib_dep, file = parse_lib_file ~loc s in
|
let lib_dep, file = parse_lib_file ~loc s in
|
||||||
add_lib_dep acc lib_dep dep_kind;
|
add_lib_dep acc lib_dep dep_kind;
|
||||||
match
|
match
|
||||||
|
@ -678,7 +614,7 @@ module Action = struct
|
||||||
| Ok path -> Some (path_exp path)
|
| Ok path -> Some (path_exp path)
|
||||||
| Error fail -> add_fail acc fail
|
| Error fail -> add_fail acc fail
|
||||||
end
|
end
|
||||||
| Pair ("libexec" , s) -> begin
|
| Some Libexec -> begin
|
||||||
let sctx = host sctx in
|
let sctx = host sctx in
|
||||||
let lib_dep, file = parse_lib_file ~loc s in
|
let lib_dep, file = parse_lib_file ~loc s in
|
||||||
add_lib_dep acc lib_dep dep_kind;
|
add_lib_dep acc lib_dep dep_kind;
|
||||||
|
@ -699,11 +635,13 @@ module Action = struct
|
||||||
add_ddep acc ~key dep
|
add_ddep acc ~key dep
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
| Pair ("lib-available", lib) ->
|
| Some Lib_available -> begin
|
||||||
add_lib_dep acc lib Optional;
|
let lib = s in
|
||||||
Some (str_exp (string_of_bool (
|
add_lib_dep acc lib Optional;
|
||||||
Lib.DB.available (Scope.libs scope) lib)))
|
Some (str_exp (string_of_bool (
|
||||||
| Pair ("version", s) -> begin
|
Lib.DB.available (Scope.libs scope) lib)))
|
||||||
|
end
|
||||||
|
| Some Version -> begin
|
||||||
match Package.Name.Map.find (Scope.project scope).packages
|
match Package.Name.Map.find (Scope.project scope).packages
|
||||||
(Package.Name.of_string s) with
|
(Package.Name.of_string s) with
|
||||||
| Some p ->
|
| Some p ->
|
||||||
|
@ -718,7 +656,7 @@ module Action = struct
|
||||||
Loc.fail loc "Package %S doesn't exist in the current project." s
|
Loc.fail loc "Package %S doesn't exist in the current project." s
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
| Pair ("read", s) -> begin
|
| Some Read -> begin
|
||||||
let path = Path.relative dir s in
|
let path = Path.relative dir s in
|
||||||
let data =
|
let data =
|
||||||
Build.contents path
|
Build.contents path
|
||||||
|
@ -726,7 +664,7 @@ module Action = struct
|
||||||
in
|
in
|
||||||
add_ddep acc ~key data
|
add_ddep acc ~key data
|
||||||
end
|
end
|
||||||
| Pair ("read-lines", s) -> begin
|
| Some Read_lines -> begin
|
||||||
let path = Path.relative dir s in
|
let path = Path.relative dir s in
|
||||||
let data =
|
let data =
|
||||||
Build.lines_of path
|
Build.lines_of path
|
||||||
|
@ -734,7 +672,7 @@ module Action = struct
|
||||||
in
|
in
|
||||||
add_ddep acc ~key data
|
add_ddep acc ~key data
|
||||||
end
|
end
|
||||||
| Pair ("read-strings", s) -> begin
|
| Some Read_strings -> begin
|
||||||
let path = Path.relative dir s in
|
let path = Path.relative dir s in
|
||||||
let data =
|
let data =
|
||||||
Build.strings path
|
Build.strings path
|
||||||
|
@ -742,62 +680,46 @@ module Action = struct
|
||||||
in
|
in
|
||||||
add_ddep acc ~key data
|
add_ddep acc ~key data
|
||||||
end
|
end
|
||||||
| _ ->
|
| Some Path_no_dep -> Some [Value.Dir (Path.relative dir s)]
|
||||||
match expand_var_no_root sctx key with
|
| None ->
|
||||||
| Some _ as x -> x
|
Loc.fail (String_with_vars.Var.loc var) "Unknown form: %a"
|
||||||
| None -> String.Map.find extra_vars key
|
String_with_vars.Var.pp var
|
||||||
|
end
|
||||||
in
|
in
|
||||||
let targets loc name =
|
let expand var syntax_version =
|
||||||
let var =
|
let loc = String_with_vars.Var.loc var in
|
||||||
match name with
|
let key = String_with_vars.Var.full_name var in
|
||||||
| "@" -> sprintf "${%s}" name
|
let res =
|
||||||
| "targets" -> sprintf "%%{%s}" name
|
match String_with_vars.Var.destruct var with
|
||||||
| _ -> assert false
|
| Macro (_, s) -> expand_form s var syntax_version
|
||||||
|
| Var var_name ->
|
||||||
|
begin match expand_vars sctx ~syntax_version ~var with
|
||||||
|
| None -> String.Map.find extra_vars key
|
||||||
|
| Some Targets ->
|
||||||
|
let var () =
|
||||||
|
match var_name with
|
||||||
|
| "@" -> sprintf "${%s}" var_name
|
||||||
|
| "targets" -> sprintf "%%{%s}" var_name
|
||||||
|
| _ -> assert false
|
||||||
|
in
|
||||||
|
begin match targets_written_by_user with
|
||||||
|
| Infer ->
|
||||||
|
Loc.fail loc "You cannot use %s with inferred rules." (var ())
|
||||||
|
| Alias ->
|
||||||
|
Loc.fail loc "You cannot use %s in aliases." (var ())
|
||||||
|
| Static l ->
|
||||||
|
Some (Value.L.dirs l) (* XXX hack to signal no dep *)
|
||||||
|
end
|
||||||
|
| Some v -> Pform.Var.to_value_no_deps_or_targets v ~scope
|
||||||
|
end
|
||||||
in
|
in
|
||||||
match targets_written_by_user with
|
Option.iter res ~f:(fun v ->
|
||||||
| Infer -> Loc.fail loc "You cannot use %s with inferred rules." var
|
acc.sdeps <- Path.Set.union
|
||||||
| Alias -> Loc.fail loc "You cannot use %s in aliases." var
|
(Path.Set.of_list (Value.L.deps_only v)) acc.sdeps
|
||||||
| Static l -> Some (Value.L.paths l)
|
);
|
||||||
in
|
res
|
||||||
let t =
|
|
||||||
U.partial_expand t ~dir ~map_exe ~f:(fun var syntax_version ->
|
|
||||||
let var_name = String_with_vars.Var.full_name var in
|
|
||||||
let loc = String_with_vars.Var.loc var in
|
|
||||||
match var_name with
|
|
||||||
| "ROOT" -> Some (path_exp sctx.context.build_dir)
|
|
||||||
| "SCOPE_ROOT" ->
|
|
||||||
if syntax_version >= (1, 0) then
|
|
||||||
Loc.fail loc
|
|
||||||
"Variable %%{SCOPE_ROOT} has been renamed to %%{project_root} \
|
|
||||||
in dune files"
|
|
||||||
else
|
|
||||||
Some (path_exp (Scope.root scope))
|
|
||||||
| "project_root" when syntax_version >= (1, 0) ->
|
|
||||||
Some (path_exp (Scope.root scope))
|
|
||||||
| "@" ->
|
|
||||||
if syntax_version < (1, 0) then
|
|
||||||
targets loc var_name
|
|
||||||
else
|
|
||||||
Loc.fail loc (* variable substitution to avoid ugly escaping *)
|
|
||||||
"Variable %s has been renamed to %%{targets} in dune files" "%{@}"
|
|
||||||
| "targets" when syntax_version >= (1, 0) -> targets loc var_name
|
|
||||||
| _ ->
|
|
||||||
match String_with_vars.Var.destruct var with
|
|
||||||
| Pair ("path-no-dep", s) ->
|
|
||||||
if syntax_version < (1, 0) then
|
|
||||||
Some (path_exp (Path.relative dir s))
|
|
||||||
else
|
|
||||||
Loc.fail
|
|
||||||
loc
|
|
||||||
"The ${path-no-dep:...} syntax has been removed from dune."
|
|
||||||
| _ ->
|
|
||||||
let exp = expand var syntax_version in
|
|
||||||
Option.iter exp ~f:(fun vs ->
|
|
||||||
acc.sdeps <- Path.Set.union (Path.Set.of_list
|
|
||||||
(Value.L.paths_only vs)) acc.sdeps;
|
|
||||||
);
|
|
||||||
exp)
|
|
||||||
in
|
in
|
||||||
|
let t = U.partial_expand t ~dir ~map_exe ~f:expand in
|
||||||
(t, acc)
|
(t, acc)
|
||||||
|
|
||||||
let expand_step2 ~dir ~dynamic_expansions ~deps_written_by_user ~map_exe t =
|
let expand_step2 ~dir ~dynamic_expansions ~deps_written_by_user ~map_exe t =
|
||||||
|
@ -807,32 +729,20 @@ module Action = struct
|
||||||
match String.Map.find dynamic_expansions key with
|
match String.Map.find dynamic_expansions key with
|
||||||
| Some _ as opt -> opt
|
| Some _ as opt -> opt
|
||||||
| None ->
|
| None ->
|
||||||
let first_dep () =
|
Pform.Map.expand Pform.Map.static_vars ~syntax_version ~var
|
||||||
Some (
|
|> Option.map ~f:(function
|
||||||
match deps_written_by_user with
|
| Pform.Var.Deps -> (Value.L.paths deps_written_by_user)
|
||||||
|
| First_dep ->
|
||||||
|
begin match deps_written_by_user with
|
||||||
| [] ->
|
| [] ->
|
||||||
Loc.warn loc "Variable '%s' used with no explicit \
|
Loc.warn loc "Variable '%s' used with no explicit \
|
||||||
dependencies@." key;
|
dependencies@." key;
|
||||||
[Value.String ""]
|
[Value.String ""]
|
||||||
| v :: _ -> [Path v]
|
| v :: _ -> [Path v]
|
||||||
)
|
end
|
||||||
in
|
| _ ->
|
||||||
match key with
|
Exn.code_error "Unexpected variable in step2"
|
||||||
| "<" ->
|
["var", String_with_vars.Var.sexp_of_t var]))
|
||||||
if syntax_version < (1, 0) then
|
|
||||||
first_dep ()
|
|
||||||
else
|
|
||||||
Loc.fail loc "Variable '<' is renamed to 'first-dep' in dune files"
|
|
||||||
| "first-dep" when syntax_version >= (1, 0) -> first_dep ()
|
|
||||||
| "^" ->
|
|
||||||
if syntax_version < (1, 0) then
|
|
||||||
Some (Value.L.paths deps_written_by_user)
|
|
||||||
else
|
|
||||||
Loc.fail loc
|
|
||||||
"Variable %%{^} has been renamed to %%{deps} in dune files"
|
|
||||||
| "deps" when syntax_version >= (1, 0) ->
|
|
||||||
Some (Value.L.paths deps_written_by_user)
|
|
||||||
| _ -> None)
|
|
||||||
|
|
||||||
let run sctx ~loc ?(extra_vars=String.Map.empty)
|
let run sctx ~loc ?(extra_vars=String.Map.empty)
|
||||||
t ~dir ~dep_kind ~targets:targets_written_by_user ~scope
|
t ~dir ~dep_kind ~targets:targets_written_by_user ~scope
|
||||||
|
|
|
@ -78,7 +78,7 @@ val dump_env : t -> dir:Path.t -> (unit, Sexp.t list) Build.t
|
||||||
val find_scope_by_dir : t -> Path.t -> Scope.t
|
val find_scope_by_dir : t -> Path.t -> Scope.t
|
||||||
val find_scope_by_name : t -> Dune_project.Name.t -> Scope.t
|
val find_scope_by_name : t -> Dune_project.Name.t -> Scope.t
|
||||||
|
|
||||||
val expand_vars
|
val expand_vars_string
|
||||||
: t
|
: t
|
||||||
-> scope:Scope.t
|
-> scope:Scope.t
|
||||||
-> dir:Path.t
|
-> dir:Path.t
|
||||||
|
|
|
@ -56,6 +56,21 @@ type t =
|
||||||
; supported_versions : Supported_versions.t
|
; supported_versions : Supported_versions.t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module Error = struct
|
||||||
|
let since loc t ver ~what =
|
||||||
|
Loc.fail loc "%s is only available since version %s of %s"
|
||||||
|
what (Version.to_string ver) t.desc
|
||||||
|
|
||||||
|
let renamed_in loc t ver ~what ~to_ =
|
||||||
|
Loc.fail loc "%s was renamed to '%s' in the %s version of %s"
|
||||||
|
what to_ (Version.to_string ver) t.desc
|
||||||
|
|
||||||
|
let deleted_in loc t ver ~what =
|
||||||
|
Loc.fail loc "%s was deleted in version %s of %s"
|
||||||
|
what (Version.to_string ver) t.desc
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
let create ~name ~desc supported_versions =
|
let create ~name ~desc supported_versions =
|
||||||
{ name
|
{ name
|
||||||
; desc
|
; desc
|
||||||
|
@ -112,9 +127,7 @@ let deleted_in t ver =
|
||||||
return ()
|
return ()
|
||||||
else begin
|
else begin
|
||||||
desc () >>= fun (loc, what) ->
|
desc () >>= fun (loc, what) ->
|
||||||
Loc.fail loc
|
Error.deleted_in loc t ver ~what
|
||||||
"%s was deleted in version %s of %s" what
|
|
||||||
(Version.to_string ver) t.desc
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let renamed_in t ver ~to_ =
|
let renamed_in t ver ~to_ =
|
||||||
|
@ -123,9 +136,7 @@ let renamed_in t ver ~to_ =
|
||||||
return ()
|
return ()
|
||||||
else begin
|
else begin
|
||||||
desc () >>= fun (loc, what) ->
|
desc () >>= fun (loc, what) ->
|
||||||
Loc.fail loc
|
Error.renamed_in loc t ver ~what ~to_
|
||||||
"%s was renamed to '%s' in the %s version of %s" what to_
|
|
||||||
(Version.to_string ver) t.desc
|
|
||||||
end
|
end
|
||||||
|
|
||||||
let since t ver =
|
let since t ver =
|
||||||
|
@ -134,7 +145,5 @@ let since t ver =
|
||||||
return ()
|
return ()
|
||||||
else begin
|
else begin
|
||||||
desc () >>= fun (loc, what) ->
|
desc () >>= fun (loc, what) ->
|
||||||
Loc.fail loc
|
Error.since loc t ver ~what
|
||||||
"%s is only available since version %s of %s" what
|
|
||||||
(Version.to_string ver) t.desc
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,6 +20,14 @@ end
|
||||||
|
|
||||||
type t
|
type t
|
||||||
|
|
||||||
|
module Error : sig
|
||||||
|
val since : Loc.t -> t -> Version.t -> what:string -> _
|
||||||
|
|
||||||
|
val renamed_in : Loc.t -> t -> Version.t -> what:string -> to_:string -> _
|
||||||
|
|
||||||
|
val deleted_in : Loc.t -> t -> Version.t -> what:string -> _
|
||||||
|
end
|
||||||
|
|
||||||
(** [create ~name ~desc supported_versions] defines a new
|
(** [create ~name ~desc supported_versions] defines a new
|
||||||
syntax. [supported_version] is the list of the last minor version
|
syntax. [supported_version] is the list of the last minor version
|
||||||
of each supported major version. [desc] is used to describe what
|
of each supported major version. [desc] is used to describe what
|
||||||
|
|
|
@ -41,6 +41,18 @@ let rec pp syntax ppf = function
|
||||||
Format.pp_close_box ppf ()
|
Format.pp_close_box ppf ()
|
||||||
| Template t -> Template.pp syntax ppf t
|
| Template t -> Template.pp syntax ppf t
|
||||||
|
|
||||||
|
let pp_quoted =
|
||||||
|
let rec loop = function
|
||||||
|
| Atom (A s) as t ->
|
||||||
|
if Atom.is_valid_dune s then
|
||||||
|
t
|
||||||
|
else
|
||||||
|
Quoted_string s
|
||||||
|
| List xs -> List (List.map ~f:loop xs)
|
||||||
|
| (Quoted_string _ | Template _) as t -> t
|
||||||
|
in
|
||||||
|
fun ppf t -> pp Dune ppf (loop t)
|
||||||
|
|
||||||
let pp_print_quoted_string ppf s =
|
let pp_print_quoted_string ppf s =
|
||||||
let syntax = Dune in
|
let syntax = Dune in
|
||||||
if String.contains s '\n' then begin
|
if String.contains s '\n' then begin
|
||||||
|
|
|
@ -76,6 +76,10 @@ val to_string : t -> syntax:syntax -> string
|
||||||
(** Serialize a S-expression using indentation to improve readability *)
|
(** Serialize a S-expression using indentation to improve readability *)
|
||||||
val pp : syntax -> Format.formatter -> t -> unit
|
val pp : syntax -> Format.formatter -> t -> unit
|
||||||
|
|
||||||
|
(** Serialization that never fails because it quotes atoms when necessary
|
||||||
|
TODO remove this once we have a proper sexp type *)
|
||||||
|
val pp_quoted : Format.formatter -> t -> unit
|
||||||
|
|
||||||
(** Same as [pp ~syntax:Dune], but split long strings. The formatter
|
(** Same as [pp ~syntax:Dune], but split long strings. The formatter
|
||||||
must have been prepared with [prepare_formatter]. *)
|
must have been prepared with [prepare_formatter]. *)
|
||||||
val pp_split_strings : Format.formatter -> t -> unit
|
val pp_split_strings : Format.formatter -> t -> unit
|
||||||
|
|
|
@ -2,6 +2,7 @@ open Stdune
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
| String of string
|
| String of string
|
||||||
|
| Dir of Path.t
|
||||||
| Path of Path.t
|
| Path of Path.t
|
||||||
|
|
||||||
let string_of_path ~dir p = Path.reach ~from:dir p
|
let string_of_path ~dir p = Path.reach ~from:dir p
|
||||||
|
@ -9,11 +10,13 @@ let string_of_path ~dir p = Path.reach ~from:dir p
|
||||||
let to_string t ~dir =
|
let to_string t ~dir =
|
||||||
match t with
|
match t with
|
||||||
| String s -> s
|
| String s -> s
|
||||||
|
| Dir p
|
||||||
| Path p -> string_of_path ~dir p
|
| Path p -> string_of_path ~dir p
|
||||||
|
|
||||||
let to_path ?error_loc t ~dir =
|
let to_path ?error_loc t ~dir =
|
||||||
match t with
|
match t with
|
||||||
| String s -> Path.relative ?error_loc dir s
|
| String s -> Path.relative ?error_loc dir s
|
||||||
|
| Dir p
|
||||||
| Path p -> p
|
| Path p -> p
|
||||||
|
|
||||||
module L = struct
|
module L = struct
|
||||||
|
@ -23,12 +26,15 @@ module L = struct
|
||||||
List.map ~f:(to_string ~dir) ts
|
List.map ~f:(to_string ~dir) ts
|
||||||
|> String.concat ~sep:" "
|
|> String.concat ~sep:" "
|
||||||
|
|
||||||
let paths_only =
|
let deps_only =
|
||||||
List.filter_map ~f:(function
|
List.filter_map ~f:(function
|
||||||
|
| Dir _
|
||||||
| String _ -> None
|
| String _ -> None
|
||||||
| Path p -> Some p)
|
| Path p -> Some p)
|
||||||
|
|
||||||
let strings = List.map ~f:(fun x -> String x)
|
let strings = List.map ~f:(fun x -> String x)
|
||||||
|
|
||||||
let paths = List.map ~f:(fun x -> Path x)
|
let paths = List.map ~f:(fun x -> Path x)
|
||||||
|
|
||||||
|
let dirs = List.map ~f:(fun x -> Dir x)
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,6 +2,7 @@ open Stdune
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
| String of string
|
| String of string
|
||||||
|
| Dir of Path.t
|
||||||
| Path of Path.t
|
| Path of Path.t
|
||||||
|
|
||||||
val to_string : t -> dir:Path.t -> string
|
val to_string : t -> dir:Path.t -> string
|
||||||
|
@ -13,7 +14,9 @@ module L : sig
|
||||||
|
|
||||||
val paths : Path.t list -> t list
|
val paths : Path.t list -> t list
|
||||||
|
|
||||||
val paths_only : t list -> Path.t list
|
val deps_only : t list -> Path.t list
|
||||||
|
|
||||||
|
val dirs : Path.t list -> t list
|
||||||
|
|
||||||
val concat : t list -> dir:Path.t -> string
|
val concat : t list -> dir:Path.t -> string
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,14 @@
|
||||||
test-cases/depend-on-the-universe
|
test-cases/depend-on-the-universe
|
||||||
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
||||||
|
|
||||||
|
(alias
|
||||||
|
(name dune-jbuild-var-case)
|
||||||
|
(deps (package dune) (source_tree test-cases/dune-jbuild-var-case))
|
||||||
|
(action
|
||||||
|
(chdir
|
||||||
|
test-cases/dune-jbuild-var-case
|
||||||
|
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
(name dune-ppx-driver-system)
|
(name dune-ppx-driver-system)
|
||||||
(deps (package dune) (source_tree test-cases/dune-ppx-driver-system))
|
(deps (package dune) (source_tree test-cases/dune-ppx-driver-system))
|
||||||
|
@ -362,6 +370,14 @@
|
||||||
test-cases/loop
|
test-cases/loop
|
||||||
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
||||||
|
|
||||||
|
(alias
|
||||||
|
(name macro-expand-error)
|
||||||
|
(deps (package dune) (source_tree test-cases/macro-expand-error))
|
||||||
|
(action
|
||||||
|
(chdir
|
||||||
|
test-cases/macro-expand-error
|
||||||
|
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
|
||||||
|
|
||||||
(alias
|
(alias
|
||||||
(name menhir)
|
(name menhir)
|
||||||
(deps (package dune) (source_tree test-cases/menhir))
|
(deps (package dune) (source_tree test-cases/menhir))
|
||||||
|
@ -641,6 +657,7 @@
|
||||||
(alias cross-compilation)
|
(alias cross-compilation)
|
||||||
(alias custom-build-dir)
|
(alias custom-build-dir)
|
||||||
(alias depend-on-the-universe)
|
(alias depend-on-the-universe)
|
||||||
|
(alias dune-jbuild-var-case)
|
||||||
(alias dune-ppx-driver-system)
|
(alias dune-ppx-driver-system)
|
||||||
(alias dune-project-edition)
|
(alias dune-project-edition)
|
||||||
(alias env)
|
(alias env)
|
||||||
|
@ -673,6 +690,7 @@
|
||||||
(alias lib-available)
|
(alias lib-available)
|
||||||
(alias link-deps)
|
(alias link-deps)
|
||||||
(alias loop)
|
(alias loop)
|
||||||
|
(alias macro-expand-error)
|
||||||
(alias menhir)
|
(alias menhir)
|
||||||
(alias merlin-tests)
|
(alias merlin-tests)
|
||||||
(alias meta-gen)
|
(alias meta-gen)
|
||||||
|
@ -718,6 +736,7 @@
|
||||||
(alias cross-compilation)
|
(alias cross-compilation)
|
||||||
(alias custom-build-dir)
|
(alias custom-build-dir)
|
||||||
(alias depend-on-the-universe)
|
(alias depend-on-the-universe)
|
||||||
|
(alias dune-jbuild-var-case)
|
||||||
(alias dune-ppx-driver-system)
|
(alias dune-ppx-driver-system)
|
||||||
(alias dune-project-edition)
|
(alias dune-project-edition)
|
||||||
(alias env)
|
(alias env)
|
||||||
|
@ -748,6 +767,7 @@
|
||||||
(alias lib-available)
|
(alias lib-available)
|
||||||
(alias link-deps)
|
(alias link-deps)
|
||||||
(alias loop)
|
(alias loop)
|
||||||
|
(alias macro-expand-error)
|
||||||
(alias merlin-tests)
|
(alias merlin-tests)
|
||||||
(alias meta-gen)
|
(alias meta-gen)
|
||||||
(alias misc)
|
(alias misc)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
(alias
|
(alias
|
||||||
(name x)
|
(name x)
|
||||||
(action (chdir %{ROOT} (echo "running in .\n"))))
|
(action (chdir %{root} (echo "running in .\n"))))
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
(alias
|
(alias
|
||||||
(name x)
|
(name x)
|
||||||
(action (chdir %{ROOT} (echo "running in bar\n"))))
|
(action (chdir %{root} (echo "running in bar\n"))))
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
(alias
|
(alias
|
||||||
(name x)
|
(name x)
|
||||||
(action (chdir %{ROOT} (echo "running in baz\n"))))
|
(action (chdir %{root} (echo "running in baz\n"))))
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
(alias
|
||||||
|
(name runtest)
|
||||||
|
(action (with-stdout-to %{null} (echo %{make}))))
|
|
@ -0,0 +1 @@
|
||||||
|
(lang dune 1.0)
|
|
@ -0,0 +1,3 @@
|
||||||
|
(alias
|
||||||
|
(name runtest)
|
||||||
|
(action (with-stdout-to %{null} (echo %{MAKE}))))
|
|
@ -0,0 +1 @@
|
||||||
|
(lang dune 1.0)
|
|
@ -0,0 +1,3 @@
|
||||||
|
(alias
|
||||||
|
((name runtest)
|
||||||
|
(action (with-stdout-to ${null} (echo ${make})))))
|
|
@ -0,0 +1,3 @@
|
||||||
|
(alias
|
||||||
|
((name runtest)
|
||||||
|
(action (with-stdout-to ${null} (echo ${MAKE})))))
|
|
@ -0,0 +1,18 @@
|
||||||
|
All builtin variables are lower cased in Dune:
|
||||||
|
|
||||||
|
$ dune runtest --root dune-lower
|
||||||
|
Entering directory 'dune-lower'
|
||||||
|
|
||||||
|
$ dune runtest --root dune-upper
|
||||||
|
Entering directory 'dune-upper'
|
||||||
|
File "dune", line 3, characters 41-46:
|
||||||
|
Error: %{MAKE} was renamed to '%{make}' in the 1.0 version of the dune language
|
||||||
|
[1]
|
||||||
|
|
||||||
|
jbuild files retain the the old names:
|
||||||
|
|
||||||
|
$ dune runtest --root jbuilder-upper
|
||||||
|
Entering directory 'jbuilder-upper'
|
||||||
|
|
||||||
|
$ dune runtest --root jbuilder-upper
|
||||||
|
Entering directory 'jbuilder-upper'
|
|
@ -3,8 +3,7 @@ We are dropping support for findlib in dune
|
||||||
$ dune build --root in-dune target.txt
|
$ dune build --root in-dune target.txt
|
||||||
Entering directory 'in-dune'
|
Entering directory 'in-dune'
|
||||||
File "dune", line 2, characters 25-37:
|
File "dune", line 2, characters 25-37:
|
||||||
Error: The findlib special variable is not supported in jbuild files, please use lib instead:
|
Error: %{findlib:..} was renamed to '%{lib:..}' in the 1.0 version of the dune language
|
||||||
%{lib:pkg} in dune files
|
|
||||||
[1]
|
[1]
|
||||||
|
|
||||||
But it must still be available in jbuild files
|
But it must still be available in jbuild files
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
(echo "\n")
|
(echo "\n")
|
||||||
(echo "let () = print_int 43;;")))
|
(echo "let () = print_int 43;;")))
|
||||||
(flags inline-test-runner %{library-name}
|
(flags inline-test-runner %{library-name}
|
||||||
-source-tree-root %{ROOT} -diff-cmd -)))
|
-source-tree-root %{root} -diff-cmd -)))
|
||||||
|
|
||||||
(library
|
(library
|
||||||
(name foo_tests)
|
(name foo_tests)
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
(inline-test-runner
|
(inline-test-runner
|
||||||
%{library-name}
|
%{library-name}
|
||||||
-source-tree-root
|
-source-tree-root
|
||||||
%{ROOT}
|
%{root}
|
||||||
-diff-cmd
|
-diff-cmd
|
||||||
-))
|
-))
|
||||||
(generate_runner
|
(generate_runner
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
(copy_files %{read:x}/*)
|
|
@ -0,0 +1,8 @@
|
||||||
|
we're getting an acceptable error message when adding a macro form in an
|
||||||
|
inappropariate place:
|
||||||
|
|
||||||
|
$ dune build
|
||||||
|
Info: creating file dune-project with this contents: (lang dune 1.0)
|
||||||
|
File "dune", line 1, characters 14-21:
|
||||||
|
Error: macros of the form %{name:..} cannot be expanded here
|
||||||
|
[1]
|
|
@ -8,7 +8,9 @@ In expands to a file name, and registers this as a dependency.
|
||||||
|
|
||||||
$ dune build --root dune @test-dep
|
$ dune build --root dune @test-dep
|
||||||
Entering directory 'dune'
|
Entering directory 'dune'
|
||||||
dynamic-contents
|
File "dune", line 13, characters 17-47:
|
||||||
|
Error: %{path:..} was renamed to '%{dep:..}' in the 1.0 version of the dune language
|
||||||
|
[1]
|
||||||
|
|
||||||
%{path-no-dep:string}
|
%{path-no-dep:string}
|
||||||
---------------------
|
---------------------
|
||||||
|
@ -18,7 +20,7 @@ This form does not exist, but displays an hint:
|
||||||
$ dune build --root dune-invalid @test-path-no-dep
|
$ dune build --root dune-invalid @test-path-no-dep
|
||||||
Entering directory 'dune-invalid'
|
Entering directory 'dune-invalid'
|
||||||
File "dune", line 7, characters 17-54:
|
File "dune", line 7, characters 17-54:
|
||||||
Error: The ${path-no-dep:...} syntax has been removed from dune.
|
Error: %{path-no-dep:..} was deleted in version 1.0 of the dune language
|
||||||
[1]
|
[1]
|
||||||
|
|
||||||
jbuild files
|
jbuild files
|
||||||
|
@ -51,6 +53,5 @@ This form does not exist, but displays an hint:
|
||||||
$ dune build --root jbuild-invalid @test-dep
|
$ dune build --root jbuild-invalid @test-dep
|
||||||
Entering directory 'jbuild-invalid'
|
Entering directory 'jbuild-invalid'
|
||||||
File "jbuild", line 5, characters 16-37:
|
File "jbuild", line 5, characters 16-37:
|
||||||
Error: ${dep:generated-file} is not supported in jbuild files.
|
Error: ${dep:..} is only available since version 1.0 of the dune language
|
||||||
Hint: Did you mean ${path:generated-file} instead?
|
|
||||||
[1]
|
[1]
|
||||||
|
|
Loading…
Reference in New Issue