Merge pull request #998 from rgrinberg/workspace-env
Add Ability to set Env through a workspace file
This commit is contained in:
commit
a842fdc2d7
|
@ -574,6 +574,7 @@ let installed_libraries =
|
|||
(Default { loc = Loc.of_pos __POS__
|
||||
; targets = [Native]
|
||||
; profile = Config.default_build_profile
|
||||
; env = None
|
||||
})
|
||||
~env
|
||||
>>= fun ctxs ->
|
||||
|
|
|
@ -26,6 +26,7 @@ type t =
|
|||
; for_host : t option
|
||||
; implicit : bool
|
||||
; build_dir : Path.t
|
||||
; env_node : Dune_env.Stanza.t option
|
||||
; path : Path.t list
|
||||
; toplevel_path : Path.t option
|
||||
; ocaml_bin : Path.t
|
||||
|
@ -130,7 +131,8 @@ let ocamlpath_sep =
|
|||
else
|
||||
Bin.path_sep
|
||||
|
||||
let create ~(kind : Kind.t) ~path ~env ~name ~merlin ~targets ~profile () =
|
||||
let create ~(kind : Kind.t) ~path ~env ~env_node ~name ~merlin ~targets
|
||||
~profile () =
|
||||
let opam_var_cache = Hashtbl.create 128 in
|
||||
(match kind with
|
||||
| Opam { root; _ } ->
|
||||
|
@ -332,6 +334,7 @@ let create ~(kind : Kind.t) ~path ~env ~name ~merlin ~targets ~profile () =
|
|||
; kind
|
||||
; profile
|
||||
; merlin
|
||||
; env_node
|
||||
; for_host = host
|
||||
; build_dir
|
||||
; path
|
||||
|
@ -407,10 +410,11 @@ let create ~(kind : Kind.t) ~path ~env ~name ~merlin ~targets ~profile () =
|
|||
|
||||
let opam_config_var t var = opam_config_var ~env:t.env ~cache:t.opam_var_cache var
|
||||
|
||||
let default ?(merlin=true) ~env ~targets () =
|
||||
create ~kind:Default ~path:Bin.path ~env ~name:"default" ~merlin ~targets ()
|
||||
let default ?(merlin=true) ~env_node ~env ~targets () =
|
||||
create ~kind:Default ~path:Bin.path ~env ~env_node ~name:"default"
|
||||
~merlin ~targets ()
|
||||
|
||||
let create_for_opam ?root ~env ~targets ~profile ~switch ~name
|
||||
let create_for_opam ?root ~env ~env_node ~targets ~profile ~switch ~name
|
||||
?(merlin=false) () =
|
||||
match Bin.opam with
|
||||
| None -> Utils.program_not_found "opam"
|
||||
|
@ -448,14 +452,16 @@ let create_for_opam ?root ~env ~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 ~name
|
||||
~merlin ()
|
||||
create ~kind:(Opam { root; switch }) ~profile ~targets ~path ~env ~env_node
|
||||
~name ~merlin ()
|
||||
|
||||
let create ?merlin ~env def =
|
||||
match (def : Workspace.Context.t) with
|
||||
| Default { targets; profile; _ } -> default ~env ~profile ~targets ?merlin ()
|
||||
| Opam { name; switch; root; targets; profile; _ } ->
|
||||
create_for_opam ?root ~env ~profile ~switch ~name ?merlin ~targets ()
|
||||
| Default { targets; profile; env = env_node ; loc = _ } ->
|
||||
default ~env ~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 ()
|
||||
|
||||
let which t s = which ~cache:t.which_cache ~path:t.path s
|
||||
|
||||
|
|
|
@ -50,6 +50,9 @@ type t =
|
|||
; (** Directory where artifact are stored, for instance "_build/default" *)
|
||||
build_dir : Path.t
|
||||
|
||||
; (** env node that this context was initialized with *)
|
||||
env_node : Dune_env.Stanza.t option
|
||||
|
||||
; (** [PATH] *)
|
||||
path : Path.t list
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
type stanza = Stanza.t = ..
|
||||
|
||||
module Stanza = struct
|
||||
open Stanza.Of_sexp
|
||||
|
||||
let field_oslu name = Ordered_set_lang.Unexpanded.field name
|
||||
|
||||
type config =
|
||||
{ flags : Ordered_set_lang.Unexpanded.t
|
||||
; ocamlc_flags : Ordered_set_lang.Unexpanded.t
|
||||
; ocamlopt_flags : Ordered_set_lang.Unexpanded.t
|
||||
}
|
||||
|
||||
type pattern =
|
||||
| Profile of string
|
||||
| Any
|
||||
|
||||
type t =
|
||||
{ loc : Loc.t
|
||||
; rules : (pattern * config) list
|
||||
}
|
||||
|
||||
let config =
|
||||
let%map flags = field_oslu "flags"
|
||||
and ocamlc_flags = field_oslu "ocamlc_flags"
|
||||
and ocamlopt_flags = field_oslu "ocamlopt_flags"
|
||||
in
|
||||
{ flags; ocamlc_flags; ocamlopt_flags }
|
||||
|
||||
let rule =
|
||||
enter
|
||||
(let%map pat =
|
||||
match_keyword [("_", return Any)]
|
||||
~fallback:(string >>| fun s -> Profile s)
|
||||
and configs = fields config
|
||||
in
|
||||
(pat, configs))
|
||||
|
||||
let t =
|
||||
let%map () = Syntax.since Stanza.syntax (1, 0)
|
||||
and loc = loc
|
||||
and rules = repeat rule
|
||||
in
|
||||
{ loc; rules }
|
||||
|
||||
end
|
||||
|
||||
type stanza +=
|
||||
| T of Stanza.t
|
|
@ -0,0 +1,25 @@
|
|||
open Import
|
||||
|
||||
type stanza = Stanza.t = ..
|
||||
|
||||
module Stanza : sig
|
||||
type config =
|
||||
{ flags : Ordered_set_lang.Unexpanded.t
|
||||
; ocamlc_flags : Ordered_set_lang.Unexpanded.t
|
||||
; ocamlopt_flags : Ordered_set_lang.Unexpanded.t
|
||||
}
|
||||
|
||||
type pattern =
|
||||
| Profile of string
|
||||
| Any
|
||||
|
||||
type t =
|
||||
{ loc : Loc.t
|
||||
; rules : (pattern * config) list
|
||||
}
|
||||
|
||||
val t : t Sexp.Of_sexp.t
|
||||
end
|
||||
|
||||
type stanza +=
|
||||
| T of Stanza.t
|
|
@ -1517,39 +1517,6 @@ module Documentation = struct
|
|||
)
|
||||
end
|
||||
|
||||
module Env = struct
|
||||
type config =
|
||||
{ flags : Ordered_set_lang.Unexpanded.t
|
||||
; ocamlc_flags : Ordered_set_lang.Unexpanded.t
|
||||
; ocamlopt_flags : Ordered_set_lang.Unexpanded.t
|
||||
}
|
||||
|
||||
type pattern =
|
||||
| Profile of string
|
||||
| Any
|
||||
|
||||
type t =
|
||||
{ loc : Loc.t
|
||||
; rules : (pattern * config) list
|
||||
}
|
||||
|
||||
let config =
|
||||
let%map flags = field_oslu "flags"
|
||||
and ocamlc_flags = field_oslu "ocamlc_flags"
|
||||
and ocamlopt_flags = field_oslu "ocamlopt_flags"
|
||||
in
|
||||
{ flags; ocamlc_flags; ocamlopt_flags }
|
||||
|
||||
let rule =
|
||||
enter
|
||||
(let%map pat =
|
||||
match_keyword [("_", return Any)]
|
||||
~fallback:(string >>| fun s -> Profile s)
|
||||
and configs = fields config
|
||||
in
|
||||
(pat, configs))
|
||||
end
|
||||
|
||||
type Stanza.t +=
|
||||
| Library of Library.t
|
||||
| Executables of Executables.t
|
||||
|
@ -1558,7 +1525,6 @@ type Stanza.t +=
|
|||
| Alias of Alias_conf.t
|
||||
| Copy_files of Copy_files.t
|
||||
| Documentation of Documentation.t
|
||||
| Env of Env.t
|
||||
| Tests of Tests.t
|
||||
|
||||
module Stanzas = struct
|
||||
|
@ -1627,10 +1593,8 @@ module Stanzas = struct
|
|||
and t = Tests.single in
|
||||
[Tests t])
|
||||
; "env",
|
||||
(let%map () = Syntax.since Stanza.syntax (1, 0)
|
||||
and loc = loc
|
||||
and rules = repeat Env.rule in
|
||||
[Env { loc; rules }])
|
||||
(let%map x = Dune_env.Stanza.t in
|
||||
[Dune_env.T x])
|
||||
]
|
||||
|
||||
let jbuild_parser =
|
||||
|
@ -1700,7 +1664,10 @@ module Stanzas = struct
|
|||
"\n--> included from %s"
|
||||
(line_loc x))))
|
||||
in
|
||||
match List.filter_map stanzas ~f:(function Env e -> Some e | _ -> None) with
|
||||
match
|
||||
List.filter_map stanzas
|
||||
~f:(function Dune_env.T e -> Some e | _ -> None)
|
||||
with
|
||||
| _ :: e :: _ ->
|
||||
Loc.fail e.loc "The 'env' stanza cannot appear more than once"
|
||||
| _ -> stanzas
|
||||
|
|
|
@ -351,23 +351,6 @@ module Documentation : sig
|
|||
}
|
||||
end
|
||||
|
||||
module Env : sig
|
||||
type config =
|
||||
{ flags : Ordered_set_lang.Unexpanded.t
|
||||
; ocamlc_flags : Ordered_set_lang.Unexpanded.t
|
||||
; ocamlopt_flags : Ordered_set_lang.Unexpanded.t
|
||||
}
|
||||
|
||||
type pattern =
|
||||
| Profile of string
|
||||
| Any
|
||||
|
||||
type t =
|
||||
{ loc : Loc.t
|
||||
; rules : (pattern * config) list
|
||||
}
|
||||
end
|
||||
|
||||
module Tests : sig
|
||||
type t =
|
||||
{ exes : Executables.t
|
||||
|
@ -385,7 +368,6 @@ type Stanza.t +=
|
|||
| Alias of Alias_conf.t
|
||||
| Copy_files of Copy_files.t
|
||||
| Documentation of Documentation.t
|
||||
| Env of Env.t
|
||||
| Tests of Tests.t
|
||||
|
||||
module Stanzas : sig
|
||||
|
|
|
@ -28,7 +28,7 @@ module Env_node = struct
|
|||
{ dir : Path.t
|
||||
; inherit_from : t Lazy.t option
|
||||
; scope : Scope.t
|
||||
; config : Env.t
|
||||
; config : Dune_env.Stanza.t
|
||||
; mutable ocaml_flags : Ocaml_flags.t option
|
||||
}
|
||||
end
|
||||
|
@ -419,6 +419,7 @@ end = struct
|
|||
|
||||
let rec get t ~dir =
|
||||
match Hashtbl.find t.env dir with
|
||||
| Some node -> node
|
||||
| None ->
|
||||
begin match Path.parent dir with
|
||||
| None -> raise_notrace Exit
|
||||
|
@ -427,7 +428,6 @@ end = struct
|
|||
Hashtbl.add t.env dir node;
|
||||
node
|
||||
end
|
||||
| Some node -> node
|
||||
|
||||
let get t ~dir =
|
||||
match get t ~dir with
|
||||
|
@ -448,7 +448,7 @@ end = struct
|
|||
in
|
||||
let flags =
|
||||
match List.find_map node.config.rules ~f:(fun (pat, cfg) ->
|
||||
match (pat : Env.pattern), profile t with
|
||||
match (pat : Dune_env.Stanza.pattern), profile t with
|
||||
| Any, _ -> Some cfg
|
||||
| Profile a, b -> Option.some_if (a = b) cfg)
|
||||
with
|
||||
|
@ -611,33 +611,40 @@ let create
|
|||
; env = Hashtbl.create 128
|
||||
}
|
||||
in
|
||||
let context_env_node = lazy (
|
||||
let config =
|
||||
match context.env_node with
|
||||
| Some s -> s
|
||||
| None -> { loc = Loc.none; rules = [] }
|
||||
in
|
||||
{ Env_node.
|
||||
dir = context.build_dir
|
||||
; inherit_from = None
|
||||
; scope = Scope.DB.find_by_dir scopes context.build_dir
|
||||
; config
|
||||
; ocaml_flags = None
|
||||
}
|
||||
) in
|
||||
List.iter stanzas
|
||||
~f:(fun { Dir_with_jbuild. ctx_dir; scope; stanzas; _ } ->
|
||||
List.iter stanzas ~f:(function
|
||||
| Env config ->
|
||||
| Dune_env.T config ->
|
||||
let inherit_from =
|
||||
if ctx_dir = Scope.root scope then
|
||||
None
|
||||
context_env_node
|
||||
else
|
||||
Some (lazy (Env.get t ~dir:(Path.parent_exn ctx_dir)))
|
||||
lazy (Env.get t ~dir:(Path.parent_exn ctx_dir))
|
||||
in
|
||||
Hashtbl.add t.env ctx_dir
|
||||
{ dir = ctx_dir
|
||||
; inherit_from = inherit_from
|
||||
; inherit_from = Some inherit_from
|
||||
; scope = scope
|
||||
; config = config
|
||||
; ocaml_flags = None
|
||||
}
|
||||
| _ -> ()));
|
||||
if not (Hashtbl.mem t.env context.build_dir) then
|
||||
Hashtbl.add t.env context.build_dir
|
||||
{ Env_node.
|
||||
dir = context.build_dir
|
||||
; inherit_from = None
|
||||
; scope = Scope.DB.find_by_dir scopes context.build_dir
|
||||
; config = { loc = Loc.none; rules = [] }
|
||||
; ocaml_flags = None
|
||||
};
|
||||
Hashtbl.add t.env context.build_dir (Lazy.force context_env_node);
|
||||
t
|
||||
module Libs = struct
|
||||
open Build.O
|
||||
|
|
|
@ -40,60 +40,66 @@ module Context = struct
|
|||
name)
|
||||
end
|
||||
|
||||
module Opam = struct
|
||||
type t =
|
||||
{ loc : Loc.t
|
||||
; name : string
|
||||
; profile : string
|
||||
; switch : string
|
||||
; root : string option
|
||||
; merlin : bool
|
||||
; targets : Target.t list
|
||||
}
|
||||
|
||||
let t ~profile ~x =
|
||||
field "switch" string >>= fun switch ->
|
||||
field "name" Name.t ~default:switch >>= fun name ->
|
||||
field "targets" (list Target.t) ~default:[Target.Native] >>= fun targets ->
|
||||
field_o "root" string >>= fun root ->
|
||||
field_b "merlin" >>= fun merlin ->
|
||||
field "profile" string ~default:profile >>= fun profile ->
|
||||
loc >>= fun loc ->
|
||||
return { loc
|
||||
; switch
|
||||
; name
|
||||
; root
|
||||
; merlin
|
||||
; targets = Target.add targets x
|
||||
; profile
|
||||
}
|
||||
end
|
||||
|
||||
module Default = struct
|
||||
module Common = struct
|
||||
type t =
|
||||
{ loc : Loc.t
|
||||
; profile : string
|
||||
; targets : Target.t list
|
||||
; env : Dune_env.Stanza.t option
|
||||
}
|
||||
|
||||
let t ~profile ~x =
|
||||
let t ~profile =
|
||||
field_o "env" Dune_env.Stanza.t >>= fun env ->
|
||||
field "targets" (list Target.t) ~default:[Target.Native]
|
||||
>>= fun targets ->
|
||||
field "profile" string ~default:profile
|
||||
>>= fun profile ->
|
||||
loc
|
||||
>>= fun loc ->
|
||||
return { loc
|
||||
; targets = Target.add targets x
|
||||
; profile
|
||||
loc >>= fun loc ->
|
||||
return
|
||||
{ targets
|
||||
; profile
|
||||
; loc
|
||||
; env
|
||||
}
|
||||
end
|
||||
|
||||
module Opam = struct
|
||||
type t =
|
||||
{ base : Common.t
|
||||
; name : string
|
||||
; switch : string
|
||||
; root : string option
|
||||
; merlin : bool
|
||||
}
|
||||
|
||||
let t ~profile ~x =
|
||||
Common.t ~profile >>= fun base ->
|
||||
field "switch" string >>= fun switch ->
|
||||
field "name" Name.t ~default:switch >>= fun name ->
|
||||
field_o "root" string >>= fun root ->
|
||||
field_b "merlin" >>= fun merlin ->
|
||||
let base = { base with targets = Target.add base.targets x } in
|
||||
return { base
|
||||
; switch
|
||||
; name
|
||||
; root
|
||||
; merlin
|
||||
}
|
||||
end
|
||||
|
||||
module Default = struct
|
||||
type t = Common.t
|
||||
|
||||
let t ~profile ~x =
|
||||
Common.t ~profile >>= fun t ->
|
||||
return { t with targets = Target.add t.targets x }
|
||||
end
|
||||
|
||||
type t = Default of Default.t | Opam of Opam.t
|
||||
|
||||
let loc = function
|
||||
| Default x -> x.loc
|
||||
| Opam x -> x.loc
|
||||
| Opam x -> x.base.loc
|
||||
|
||||
let t ~profile ~x =
|
||||
sum
|
||||
|
@ -121,7 +127,7 @@ module Context = struct
|
|||
|
||||
let targets = function
|
||||
| Default x -> x.targets
|
||||
| Opam x -> x.targets
|
||||
| Opam x -> x.base.targets
|
||||
|
||||
let all_names t =
|
||||
let n = name t in
|
||||
|
@ -135,6 +141,7 @@ module Context = struct
|
|||
; targets = [Option.value x ~default:Target.Native]
|
||||
; profile = Option.value profile
|
||||
~default:Config.default_build_profile
|
||||
; env = None
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -8,24 +8,26 @@ module Context : sig
|
|||
| Native
|
||||
| Named of string
|
||||
end
|
||||
module Opam : sig
|
||||
module Common : sig
|
||||
type t =
|
||||
{ loc : Loc.t
|
||||
; name : string
|
||||
; profile : string
|
||||
; targets : Target.t list
|
||||
; env : Dune_env.Stanza.t option
|
||||
}
|
||||
end
|
||||
module Opam : sig
|
||||
type t =
|
||||
{ base : Common.t
|
||||
; name : string
|
||||
; switch : string
|
||||
; root : string option
|
||||
; merlin : bool
|
||||
; targets : Target.t list
|
||||
}
|
||||
end
|
||||
|
||||
module Default : sig
|
||||
type t =
|
||||
{ loc : Loc.t
|
||||
; profile : string
|
||||
; targets : Target.t list
|
||||
}
|
||||
type t = Common.t
|
||||
end
|
||||
|
||||
type t = Default of Default.t | Opam of Opam.t
|
||||
|
|
|
@ -47,3 +47,13 @@ see how we can set a "native" target. Which is the default.
|
|||
Entering directory 'targets-native'
|
||||
Entering directory 'targets-native'
|
||||
message from targets-native test
|
||||
|
||||
Workspaces also allow you to set the env for a context:
|
||||
|
||||
$ dune printenv --root workspace-env --profile default
|
||||
Entering directory 'workspace-env'
|
||||
(
|
||||
(flags (-w -40 -machin))
|
||||
(ocamlc_flags (-g))
|
||||
(ocamlopt_flags (-g))
|
||||
)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
(lang dune 1.0)
|
|
@ -0,0 +1,7 @@
|
|||
(lang dune 1.0)
|
||||
|
||||
(context
|
||||
(default
|
||||
(env
|
||||
(default
|
||||
(flags (:standard -machin))))))
|
Loading…
Reference in New Issue