Merge pull request #1038 from rgrinberg/workspace-env-2

Env stanza in workspace files part #2
This commit is contained in:
Rudi Grinberg 2018-07-30 17:07:54 +02:00 committed by GitHub
commit baa5b773b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 88 additions and 29 deletions

View File

@ -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)
------------------

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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) ->

View File

@ -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 = [] }
let make ~inherit_from ~config =
{ Env_node.
dir = context.build_dir
; scope = Scope.DB.find_by_dir scopes context.build_dir
; ocaml_flags = None
; inherit_from
; config
}
in
{ Env_node.
dir = context.build_dir
; inherit_from = None
; scope = Scope.DB.find_by_dir scopes context.build_dir
; config
; ocaml_flags = None
}
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; _ } ->

View File

@ -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 =

View File

@ -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

View File

@ -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))
)

View File

@ -1 +1 @@
(lang dune 1.0)
(lang dune 1.1)

View File

@ -1,4 +1,8 @@
(lang dune 1.0)
(lang dune 1.1)
(env
(default
(ocamlc_flags (:standard -verbose))))
(context
(default