diff --git a/master_changes.md b/master_changes.md index 3d0e532c730..67911dcbe0e 100644 --- a/master_changes.md +++ b/master_changes.md @@ -165,6 +165,7 @@ users) * Add `with-tools` variable for recommended tools [#5016 @rjbou] * Add `x-locked` extension fields for overlay internal use, it stores if the files originate from a locked file, if so its extension [#5080 @rjbou] * Set `depext-bypass` parsing with depth 1, no needed brakcet if single package [#5154 @rjbou] + * [BUG] Variables are now expanded in build-env (as for setenv) [#5351 @dra27] ## External dependencies * Set `DEBIAN_FRONTEND=noninteractive` for unsafe-yes confirmation level [#4735 @dra27 - partially fix #4731] [2.1.0~rc2 #4739] diff --git a/src/client/opamAction.ml b/src/client/opamAction.ml index 871921eec2a..063f2ebfe2c 100644 --- a/src/client/opamAction.ml +++ b/src/client/opamAction.ml @@ -520,6 +520,9 @@ let prepare_package_source st nv dir = let compilation_env t opam = let open OpamParserTypes in + let build_env = + List.map (OpamEnv.env_expansion ~opam t) (OpamFile.OPAM.build_env opam) + in let scrub = OpamClientConfig.(!r.scrubbed_environment_variables) in OpamEnv.get_full ~scrub ~set_opamroot:true ~set_opamswitch:true ~force_path:true t ~updates:([ @@ -534,7 +537,7 @@ let compilation_env t opam = Some "build environment definition"; "OPAMCLI", Eq, "2.0", Some "opam CLI version"; ] @ - OpamFile.OPAM.build_env opam) + build_env) let installed_opam_opt st nv = OpamStd.Option.Op.( diff --git a/src/state/opamEnv.ml b/src/state/opamEnv.ml index 40b31e16fb1..b4adaf04266 100644 --- a/src/state/opamEnv.ml +++ b/src/state/opamEnv.ml @@ -185,18 +185,22 @@ let add (env: env) (updates: env_update list) = in env @ expand updates +let env_expansion ?opam st (name, op, str, cmt) = + let fenv v = + try OpamPackageVar.resolve st ?opam v + with Not_found -> + log "Undefined variable: %s" (OpamVariable.Full.to_string v); + None + in + let s = OpamFilter.expand_string ~default:(fun _ -> "") fenv str in + name, op, s, cmt + let compute_updates ?(force_path=false) st = (* Todo: put these back into their packages! let perl5 = OpamPackage.Name.of_string "perl5" in let add_to_perl5lib = OpamPath.Switch.lib t.root t.switch t.switch_config perl5 in let new_perl5lib = "PERL5LIB", "+=", OpamFilename.Dir.to_string add_to_perl5lib in *) - let fenv ?opam v = - try OpamPackageVar.resolve st ?opam v - with Not_found -> - log "Undefined variable: %s" (OpamVariable.Full.to_string v); - None - in let bindir = OpamPath.Switch.bin st.switch_global.root st.switch st.switch_config in @@ -218,21 +222,17 @@ let compute_updates ?(force_path=false) st = st.switch_global.root st.switch st.switch_config), Some "Current opam switch man dir"] in - let env_expansion ?opam (name,op,str,cmt) = - let s = OpamFilter.expand_string ~default:(fun _ -> "") (fenv ?opam) str in - name, op, s, cmt - in let switch_env = ("OPAM_SWITCH_PREFIX", Eq, OpamFilename.Dir.to_string (OpamPath.Switch.root st.switch_global.root st.switch), Some "Prefix of the current opam switch") :: - List.map env_expansion st.switch_config.OpamFile.Switch_config.env + List.map (env_expansion st) st.switch_config.OpamFile.Switch_config.env in let pkg_env = (* XXX: Does this need a (costly) topological sort? *) OpamPackage.Set.fold (fun nv acc -> match OpamPackage.Map.find_opt nv st.opams with - | Some opam -> List.map (env_expansion ~opam) (OpamFile.OPAM.env opam) @ acc + | Some opam -> List.map (env_expansion ~opam st) (OpamFile.OPAM.env opam) @ acc | None -> acc) st.installed [] in diff --git a/src/state/opamEnv.mli b/src/state/opamEnv.mli index e497166ec0e..3e9c9e021d7 100644 --- a/src/state/opamEnv.mli +++ b/src/state/opamEnv.mli @@ -94,6 +94,9 @@ val path: force_path:bool -> dirname -> switch -> string val full_with_path: force_path:bool -> ?updates:env_update list -> dirname -> switch -> env +(** Performs variable expansion on the strings in an environment update *) +val env_expansion: ?opam:OpamFile.OPAM.t -> 'a switch_state -> env_update -> env_update + (** {2 Shell and initialisation support} *) (** Sets the opam configuration in the user shell, after detailing the process