Merge branch 'master' into jsoo-cctx
This commit is contained in:
commit
5c93619b47
|
@ -5,6 +5,10 @@ next
|
|||
passing in `--root` in conjunction with `--workspace` or `--config` would not
|
||||
work correctly (#997, @rgrinberg)
|
||||
|
||||
- Add support for customizing env nodes in workspace files. The `env` stanza is
|
||||
now allowed in toplevel position in the workspace file, or for individual
|
||||
contexts. This feature requires `(dune lang 1.1)` (#1038, @rgrinberg)
|
||||
|
||||
1.0.1 (19/07/2018)
|
||||
------------------
|
||||
|
||||
|
|
|
@ -488,7 +488,7 @@ stanza is rejected by dune:
|
|||
ocamllex
|
||||
--------
|
||||
|
||||
``(ocamllex (<names>))`` is essentially a shorthand for:
|
||||
``(ocamllex <names>)`` is essentially a shorthand for:
|
||||
|
||||
.. code:: scheme
|
||||
|
||||
|
@ -503,13 +503,13 @@ To use a different rule mode, use the long form:
|
|||
.. code:: scheme
|
||||
|
||||
(ocamllex
|
||||
(modules (<names>))
|
||||
(modules <names>)
|
||||
(mode <mode>))
|
||||
|
||||
ocamlyacc
|
||||
---------
|
||||
|
||||
``(ocamlyacc (<names>))`` is essentially a shorthand for:
|
||||
``(ocamlyacc <names>)`` is essentially a shorthand for:
|
||||
|
||||
.. code:: scheme
|
||||
|
||||
|
@ -524,7 +524,7 @@ To use a different rule mode, use the long form:
|
|||
.. code:: scheme
|
||||
|
||||
(ocamlyacc
|
||||
(modules (<names>))
|
||||
(modules <names>)
|
||||
(mode <mode>))
|
||||
|
||||
menhir
|
||||
|
@ -1231,22 +1231,8 @@ follows:
|
|||
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 to ``js_of_ocaml``. This field
|
||||
supports ``(:include ...)`` forms
|
||||
|
||||
- ``(javascript_files (<files-list>))`` to specify ``js_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.
|
||||
A :ref:`dune-jsoo-field` exists in executable and libraries stanzas that allows
|
||||
one to customize options relevant to jsoo.
|
||||
|
||||
.. _user-actions:
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ Welcome to dune's documentation!
|
|||
advanced-topics
|
||||
configurator
|
||||
menhir
|
||||
jsoo
|
||||
faq
|
||||
known-issues
|
||||
migration
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
***********
|
||||
js_of_ocaml
|
||||
***********
|
||||
|
||||
js_of_ocaml_ is a compiler from OCaml to JavaScript. The compiler works by
|
||||
translating OCaml bytecode to JS files. From here on, we'll abbreviate
|
||||
js_of_ocaml to jsoo. The compiler can be installed with opam:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ opam install js_of_ocaml-compiler
|
||||
|
||||
Compiling to JS
|
||||
===============
|
||||
|
||||
Dune has full support building jsoo libraries and executables transparently.
|
||||
There's no need to customize or enable anything to compile ocaml
|
||||
libraries/executables to JS.
|
||||
|
||||
To build a JS executable, just define an executable as you would normally.
|
||||
Consider this example:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
echo 'print_endline "hello from js"' > foo.ml
|
||||
|
||||
With the following dune file:
|
||||
|
||||
.. code:: scheme
|
||||
|
||||
(executable (name foo))
|
||||
|
||||
And then request the ``.js`` target:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ dune build ./foo.bc.js
|
||||
$ node _build/default/foo.bc.js
|
||||
hello from js
|
||||
|
||||
Similar targets are created for libraries, but we recommend sticking to the
|
||||
executable targets.
|
||||
|
||||
.. _dune-jsoo-field:
|
||||
|
||||
``js_of_ocaml`` field
|
||||
=====================
|
||||
|
||||
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 to ``js_of_ocaml``. This field
|
||||
supports ``(:include ...)`` forms
|
||||
|
||||
- ``(javascript_files (<files-list>))`` to specify ``js_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.
|
||||
|
||||
Separate Compilation
|
||||
====================
|
||||
|
||||
Dune supports two modes of compilation
|
||||
|
||||
- Direct compilation of a bytecode program to JavaScript. This mode allows
|
||||
js_of_ocaml to perform whole program deadcode elimination and whole program
|
||||
inlining.
|
||||
|
||||
- Separate compilation, where compilation units are compiled to JavaScript
|
||||
separately and then linked together. This mode is useful during development as
|
||||
it builds more quickly.
|
||||
|
||||
The separate compilation mode will be selected when the build profile is
|
||||
``dev``, which is the default. There is currently no other way to control this
|
||||
behaviour.
|
||||
|
||||
.. _js_of_ocaml: http://ocsigen.org/js_of_ocaml/
|
|
@ -136,7 +136,7 @@ Add this field to your ``library`` or ``executable`` stanzas:
|
|||
|
||||
.. code:: scheme
|
||||
|
||||
(preprocess (action (run %{bin:cppo} -V OCAML:%{ocaml_version} %{first-dep})))
|
||||
(preprocess (action (run %{bin:cppo} -V OCAML:%{ocaml_version} %{input-file})))
|
||||
|
||||
Additionally, if you are include a ``config.h`` file, you need to
|
||||
declare the dependency to this file via:
|
||||
|
@ -154,7 +154,7 @@ Write this in your ``dune`` file:
|
|||
|
||||
(rule
|
||||
(targets foo.ml)
|
||||
(deps foo.cppo.ml <other files that foo.ml includes>)
|
||||
(deps (:first-dep foo.cppo.ml) <other files that foo.ml includes>)
|
||||
(action (run %{bin:cppo} %{first-dep} -o %{targets})))
|
||||
|
||||
Defining a library with C stubs
|
||||
|
@ -192,8 +192,8 @@ compilation and link flags. Write this ``dune`` file:
|
|||
|
||||
(rule
|
||||
(targets c_flags.sexp c_library_flags.sexp)
|
||||
(deps config/discover.exe)
|
||||
(action (run %{first-dep} -ocamlc %{OCAMLC})))
|
||||
(deps (:discover config/discover.exe))
|
||||
(action (run %{discover} -ocamlc %{OCAMLC})))
|
||||
|
||||
Then create a ``config`` subdirectory and write this ``dune`` file:
|
||||
|
||||
|
@ -240,8 +240,8 @@ To generate a file ``foo.ml`` using a program from another directory:
|
|||
|
||||
(rule
|
||||
(targets foo.ml)
|
||||
(deps ../generator/gen.exe)
|
||||
(action (run %{first-dep} -o %{targets})))
|
||||
(deps (:gen ../generator/gen.exe))
|
||||
(action (run %{gen} -o %{targets})))
|
||||
|
||||
Defining tests
|
||||
==============
|
||||
|
@ -252,8 +252,8 @@ Write this in your ``dune`` file:
|
|||
|
||||
(alias
|
||||
(name runtest)
|
||||
(deps my-test-program.exe)
|
||||
(action (run %{first-dep})))
|
||||
(deps (:my-prog my-test-program.exe))
|
||||
(action (run %{my-prog})))
|
||||
|
||||
And run the tests with:
|
||||
|
||||
|
|
|
@ -379,6 +379,13 @@ The build profile can be selected in the ``dune-workspace`` file by write a
|
|||
|
||||
Note that the command line option ``--profile`` has precedence over this stanza.
|
||||
|
||||
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 dune's :ref:`dune-env` stanza.
|
||||
|
||||
context
|
||||
~~~~~~~
|
||||
|
||||
|
@ -407,6 +414,10 @@ context or can be the description of an opam switch, as follows:
|
|||
context. This has precedence over the command line option
|
||||
``--profile``
|
||||
|
||||
- ``(env <env>)`` to set the environment for a particular context. This is of
|
||||
higher precedence than the toplevel ``env`` stanza in the workspace file. This
|
||||
field the same options as the :ref:`dune-env` stanza.
|
||||
|
||||
Both ``(default ...)`` and ``(opam ...)`` accept a ``targets`` field in order to
|
||||
setup cross compilation. See :ref:`advanced-cross-compilation` for more
|
||||
information.
|
||||
|
@ -420,29 +431,6 @@ 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.
|
||||
|
||||
Building JavaScript with js_of_ocaml
|
||||
====================================
|
||||
|
||||
Dune knows how to generate a JavaScript version of an executable
|
||||
(``<name>.bc.js``) using the js_of_ocaml compiler (the ``js_of_ocaml-compiler``
|
||||
opam package must be installed).
|
||||
|
||||
It supports two modes of compilation:
|
||||
|
||||
- Direct compilation of a bytecode program to JavaScript. This mode allows
|
||||
js_of_ocaml to perform whole program deadcode elimination and whole program
|
||||
inlining.
|
||||
- Separate compilation, where compilation units are compiled to JavaScript
|
||||
separately and then linked together. This mode is useful during development as
|
||||
it builds more quickly.
|
||||
|
||||
The separate compilation mode will be selected when the build profile is
|
||||
``dev``, which is the default. There is currently no other way to control this
|
||||
behaviour.
|
||||
|
||||
See the section about :ref:`dune-jsoo` for passing custom flags to the
|
||||
js_of_ocaml compiler
|
||||
|
||||
Distributing Projects
|
||||
=====================
|
||||
|
||||
|
|
|
@ -18,6 +18,13 @@ module Kind = struct
|
|||
])
|
||||
end
|
||||
|
||||
module Env_nodes = struct
|
||||
type t =
|
||||
{ context: Dune_env.Stanza.t option
|
||||
; workspace: Dune_env.Stanza.t option
|
||||
}
|
||||
end
|
||||
|
||||
type t =
|
||||
{ name : string
|
||||
; kind : Kind.t
|
||||
|
@ -26,7 +33,7 @@ type t =
|
|||
; for_host : t option
|
||||
; implicit : bool
|
||||
; build_dir : Path.t
|
||||
; env_node : Dune_env.Stanza.t option
|
||||
; env_nodes : Env_nodes.t
|
||||
; path : Path.t list
|
||||
; toplevel_path : Path.t option
|
||||
; ocaml_bin : Path.t
|
||||
|
@ -131,7 +138,7 @@ let ocamlpath_sep =
|
|||
else
|
||||
Bin.path_sep
|
||||
|
||||
let create ~(kind : Kind.t) ~path ~env ~env_node ~name ~merlin ~targets
|
||||
let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets
|
||||
~profile () =
|
||||
let opam_var_cache = Hashtbl.create 128 in
|
||||
(match kind with
|
||||
|
@ -334,7 +341,7 @@ let create ~(kind : Kind.t) ~path ~env ~env_node ~name ~merlin ~targets
|
|||
; kind
|
||||
; profile
|
||||
; merlin
|
||||
; env_node
|
||||
; env_nodes
|
||||
; for_host = host
|
||||
; build_dir
|
||||
; path
|
||||
|
@ -410,11 +417,11 @@ let create ~(kind : Kind.t) ~path ~env ~env_node ~name ~merlin ~targets
|
|||
|
||||
let opam_config_var t var = opam_config_var ~env:t.env ~cache:t.opam_var_cache var
|
||||
|
||||
let default ?(merlin=true) ~env_node ~env ~targets () =
|
||||
create ~kind:Default ~path:Bin.path ~env ~env_node ~name:"default"
|
||||
let default ?(merlin=true) ~env_nodes ~env ~targets () =
|
||||
create ~kind:Default ~path:Bin.path ~env ~env_nodes ~name:"default"
|
||||
~merlin ~targets ()
|
||||
|
||||
let create_for_opam ?root ~env ~env_node ~targets ~profile ~switch ~name
|
||||
let create_for_opam ?root ~env ~env_nodes ~targets ~profile ~switch ~name
|
||||
?(merlin=false) () =
|
||||
match Bin.opam with
|
||||
| None -> Utils.program_not_found "opam"
|
||||
|
@ -452,16 +459,23 @@ let create_for_opam ?root ~env ~env_node ~targets ~profile ~switch ~name
|
|||
| Some s -> Bin.parse_path s
|
||||
in
|
||||
let env = Env.extend env ~vars in
|
||||
create ~kind:(Opam { root; switch }) ~profile ~targets ~path ~env ~env_node
|
||||
create ~kind:(Opam { root; switch }) ~profile ~targets ~path ~env ~env_nodes
|
||||
~name ~merlin ()
|
||||
|
||||
let create ?merlin ~env def =
|
||||
let create ?merlin ?workspace_env ~env def =
|
||||
let env_nodes context =
|
||||
{ Env_nodes.
|
||||
context
|
||||
; workspace = workspace_env
|
||||
}
|
||||
in
|
||||
match (def : Workspace.Context.t) with
|
||||
| Default { targets; profile; env = env_node ; loc = _ } ->
|
||||
default ~env ~env_node ~profile ~targets ?merlin ()
|
||||
default ~env ~env_nodes:(env_nodes env_node) ~profile ~targets ?merlin ()
|
||||
| Opam { base = { targets ; profile ; env = env_node ; loc = _ }
|
||||
; name; switch; root; merlin = _ } ->
|
||||
create_for_opam ?root ~env_node ~env ~profile ~switch ~name ?merlin ~targets ()
|
||||
create_for_opam ?root ~env_nodes:(env_nodes env_node) ~env ~profile
|
||||
~switch ~name ?merlin ~targets ()
|
||||
|
||||
let which t s = which ~cache:t.which_cache ~path:t.path s
|
||||
|
||||
|
|
|
@ -30,6 +30,13 @@ module Kind : sig
|
|||
type t = Default | Opam of Opam.t
|
||||
end
|
||||
|
||||
module Env_nodes : sig
|
||||
type t =
|
||||
{ context: Dune_env.Stanza.t option
|
||||
; workspace: Dune_env.Stanza.t option
|
||||
}
|
||||
end
|
||||
|
||||
type t =
|
||||
{ name : string
|
||||
; kind : Kind.t
|
||||
|
@ -51,7 +58,7 @@ type t =
|
|||
build_dir : Path.t
|
||||
|
||||
; (** env node that this context was initialized with *)
|
||||
env_node : Dune_env.Stanza.t option
|
||||
env_nodes : Env_nodes.t
|
||||
|
||||
; (** [PATH] *)
|
||||
path : Path.t list
|
||||
|
@ -125,6 +132,7 @@ val compare : t -> t -> Ordering.t
|
|||
|
||||
val create
|
||||
: ?merlin:bool
|
||||
-> ?workspace_env:Dune_env.Stanza.t
|
||||
-> env:Env.t
|
||||
-> Workspace.Context.t
|
||||
-> t list Fiber.t
|
||||
|
|
|
@ -73,7 +73,8 @@ let setup ?(log=Log.no_log)
|
|||
|
||||
Fiber.parallel_map workspace.contexts ~f:(fun ctx_def ->
|
||||
let name = Workspace.Context.name ctx_def in
|
||||
Context.create ctx_def ~env ~merlin:(workspace.merlin_context = Some name))
|
||||
Context.create ?workspace_env:workspace.env
|
||||
ctx_def ~env ~merlin:(workspace.merlin_context = Some name))
|
||||
>>= fun contexts ->
|
||||
let contexts = List.concat contexts in
|
||||
List.iter contexts ~f:(fun (ctx : Context.t) ->
|
||||
|
|
|
@ -612,18 +612,24 @@ let create
|
|||
}
|
||||
in
|
||||
let context_env_node = lazy (
|
||||
let config =
|
||||
match context.env_node with
|
||||
| Some s -> s
|
||||
| None -> { loc = Loc.none; rules = [] }
|
||||
in
|
||||
let make ~inherit_from ~config =
|
||||
{ Env_node.
|
||||
dir = context.build_dir
|
||||
; inherit_from = None
|
||||
; scope = Scope.DB.find_by_dir scopes context.build_dir
|
||||
; config
|
||||
; ocaml_flags = None
|
||||
; inherit_from
|
||||
; config
|
||||
}
|
||||
in
|
||||
match context.env_nodes with
|
||||
| { context = None; workspace = None } ->
|
||||
make ~config:{ loc = Loc.none; rules = [] } ~inherit_from:None
|
||||
| { context = Some config; workspace = None }
|
||||
| { context = None; workspace = Some config } ->
|
||||
make ~config ~inherit_from:None
|
||||
| { context = Some context ; workspace = Some workspace } ->
|
||||
make ~config:context
|
||||
~inherit_from:(Some (lazy (make ~inherit_from:None ~config:workspace)))
|
||||
) in
|
||||
List.iter stanzas
|
||||
~f:(fun { Dir_with_jbuild. ctx_dir; scope; stanzas; _ } ->
|
||||
|
|
|
@ -5,6 +5,11 @@ open Stanza.Of_sexp
|
|||
for simplicity *)
|
||||
let syntax = Stanza.syntax
|
||||
|
||||
let env_field =
|
||||
field_o "env"
|
||||
(Syntax.since syntax (1, 1) >>= fun () ->
|
||||
Dune_env.Stanza.t)
|
||||
|
||||
module Context = struct
|
||||
module Target = struct
|
||||
type t =
|
||||
|
@ -49,7 +54,7 @@ module Context = struct
|
|||
}
|
||||
|
||||
let t ~profile =
|
||||
field_o "env" Dune_env.Stanza.t >>= fun env ->
|
||||
env_field >>= fun env ->
|
||||
field "targets" (list Target.t) ~default:[Target.Native]
|
||||
>>= fun targets ->
|
||||
field "profile" string ~default:profile
|
||||
|
@ -148,22 +153,25 @@ end
|
|||
type t =
|
||||
{ merlin_context : string option
|
||||
; contexts : Context.t list
|
||||
; env : Dune_env.Stanza.t option
|
||||
}
|
||||
|
||||
include Versioned_file.Make(struct type t = unit end)
|
||||
let () = Lang.register syntax ()
|
||||
|
||||
let t ?x ?profile:cmdline_profile () =
|
||||
env_field >>= fun env ->
|
||||
field "profile" string ~default:Config.default_build_profile
|
||||
>>= fun profile ->
|
||||
let profile = Option.value cmdline_profile ~default:profile in
|
||||
multi_field "context" (Context.t ~profile ~x)
|
||||
>>= fun contexts ->
|
||||
let defined_names = ref String.Set.empty in
|
||||
let { merlin_context; contexts } =
|
||||
let { merlin_context; contexts; env } =
|
||||
let init =
|
||||
{ merlin_context = None
|
||||
; contexts = []
|
||||
; env
|
||||
}
|
||||
in
|
||||
List.fold_left contexts ~init ~f:(fun t ctx ->
|
||||
|
@ -178,7 +186,7 @@ let t ?x ?profile:cmdline_profile () =
|
|||
Loc.fail (Context.loc ctx)
|
||||
"you can only have one context for merlin"
|
||||
| Opam { merlin = true; _ }, None ->
|
||||
{ merlin_context = Some name; contexts = ctx :: t.contexts }
|
||||
{ merlin_context = Some name; contexts = ctx :: t.contexts; env = None }
|
||||
| _ ->
|
||||
{ t with contexts = ctx :: t.contexts })
|
||||
in
|
||||
|
@ -200,6 +208,7 @@ let t ?x ?profile:cmdline_profile () =
|
|||
return
|
||||
{ merlin_context
|
||||
; contexts = List.rev contexts
|
||||
; env
|
||||
}
|
||||
|
||||
let t ?x ?profile () = fields (t ?x ?profile ())
|
||||
|
@ -207,6 +216,7 @@ let t ?x ?profile () = fields (t ?x ?profile ())
|
|||
let default ?x ?profile () =
|
||||
{ merlin_context = Some "default"
|
||||
; contexts = [Context.default ?x ?profile ()]
|
||||
; env = None
|
||||
}
|
||||
|
||||
let load ?x ?profile p =
|
||||
|
|
|
@ -38,6 +38,7 @@ end
|
|||
type t =
|
||||
{ merlin_context : string option
|
||||
; contexts : Context.t list
|
||||
; env : Dune_env.Stanza.t option
|
||||
}
|
||||
|
||||
val load : ?x:string -> ?profile:string -> Path.t -> t
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
$ cat dune-project
|
||||
cat: dune-project: No such file or directory
|
||||
[1]
|
||||
$ [ -e dune-project ] || echo File does not exist
|
||||
File does not exist
|
||||
$ mkdir src
|
||||
$ echo '(alias (name runtest) (action (progn)))' > src/dune
|
||||
$ dune build
|
||||
|
|
|
@ -53,6 +53,6 @@ Workspaces also allow you to set the env for a context:
|
|||
Entering directory 'workspace-env'
|
||||
(
|
||||
(flags (-w -40 -machin))
|
||||
(ocamlc_flags (-g))
|
||||
(ocamlc_flags (-g -verbose))
|
||||
(ocamlopt_flags (-g))
|
||||
)
|
||||
|
|
|
@ -1 +1 @@
|
|||
(lang dune 1.0)
|
||||
(lang dune 1.1)
|
|
@ -1,4 +1,8 @@
|
|||
(lang dune 1.0)
|
||||
(lang dune 1.1)
|
||||
|
||||
(env
|
||||
(default
|
||||
(ocamlc_flags (:standard -verbose))))
|
||||
|
||||
(context
|
||||
(default
|
||||
|
|
Loading…
Reference in New Issue