Skip to content
Browse files

Support for local env variables when building a package

  • Loading branch information...
1 parent c21d461 commit 1a8edd16368466add8b0258dd3c92c0090ca44cb @samoht samoht committed Jul 17, 2012
Showing with 73 additions and 34 deletions.
  1. +27 −18 src/client.ml
  2. +8 −12 src/file.ml
  3. +3 −0 src/file.mli
  4. +13 −0 src/file_format.ml
  5. +8 −0 src/file_format.mli
  6. +8 −1 src/run.ml
  7. +3 −0 src/run.mli
  8. +3 −3 src/utils.ml
View
45 src/client.ml
@@ -429,7 +429,13 @@ let create_default_compiler_description t =
[ mk "base-unix"; mk "base-bigarray"; mk "base-threads" ]
else
[])
- [ ("CAML_LD_LIBRARY_PATH", "+=", Dirname.to_string (Path.C.stublibs t.compiler))] in
+ [ ("CAML_LD_LIBRARY_PATH", "+=",
+ (Dirname.to_string (Path.C.stublibs t.compiler))
+ ^ ":" ^
+ (match Run.ocamlc_where () with
+ | Some d -> Stdlib_filename.concat d "stublibs"
+ | None -> assert false))
+ ] in
let comp = Path.G.compiler t.global ocaml_version in
File.Comp.write comp f
@@ -815,40 +821,44 @@ let get_archive t nv =
type env = {
add_to_env : (string * string) list;
add_to_path: dirname;
- old_env : (string * string) list;
new_env : (string * string) list;
}
let expand_env t env =
List.map (fun (ident, symbol, string) ->
let string = substitute_string t string in
- let clean_env () = try Utils.reset_env_value (Sys.getenv ident) with _ -> [] in
+ let read_env () =
+ let prefix = Dirname.to_string (Path.C.root t.compiler) in
+ try Utils.reset_env_value ~prefix (Sys.getenv ident)
+ with _ -> [] in
match symbol with
| "=" -> (ident, string)
- | "+=" -> (ident, String.concat ":" (string :: clean_env ()))
- | "=+" -> (ident, String.concat ":" (clean_env () @ [string]))
+ | "+=" -> (ident, String.concat ":" (string :: read_env ()))
+ | "=+" -> (ident, String.concat ":" (read_env () @ [string]))
| _ -> failwith (Printf.sprintf "expand_env: %s is an unknown symbol" symbol)
) env
-(* XXX: We should get the ones defined in the dependents packages as well *)
+let update_env t env e =
+ let expanded = expand_env t e in
+ { env with
+ add_to_env = expanded @ env.add_to_env;
+ new_env = expanded @ env.new_env }
+
let get_env t =
let ocaml_version = current_ocaml_version t in
let comp_f = Path.G.compiler t.global ocaml_version in
let comp = File.Comp.read comp_f in
let add_to_path = Path.C.bin t.compiler in
let new_path = "PATH", "+=", Dirname.to_string add_to_path in
+
let add_to_env = File.Comp.env comp in
let new_env = new_path :: add_to_env in
- let old_path = "PATH", "=", try Sys.getenv "PATH" with _ -> "" in
- let old_env = old_path :: List.map (fun (k,_,_) -> k, "=", try Sys.getenv k with _ -> "") add_to_env in
-
let add_to_env = expand_env t add_to_env in
- let old_env = expand_env t old_env in
let new_env = expand_env t new_env in
- { add_to_env; add_to_path; old_env; new_env }
+ { add_to_env; add_to_path; new_env }
let print_env env =
List.iter (fun (k,v) ->
@@ -858,11 +868,11 @@ let print_env env =
let pinned_path t nv =
let name = NV.name nv in
if N.Map.mem name t.pinned then
- match N.Map.find name t.pinned with
- | Path p -> Some p
- | _ -> None
+ match N.Map.find name t.pinned with
+ | Path p -> Some p
+ | _ -> None
else
- None
+ None
let rec proceed_tochange t nv_old nv =
(* First, uninstall any previous version *)
@@ -892,13 +902,12 @@ let rec proceed_tochange t nv_old nv =
List.iter (substitute_file t) (File.OPAM.substs opam);
(* Get the env variables set up in the compiler description file *)
- let env = get_env t in
+ let env0 = get_env t in
+ let env = update_env t env0 (File.OPAM.build_env opam) in
(* Generate an environnement file *)
let env_f = Path.C.build_env t.compiler nv in
File.Env.write env_f env.new_env;
- let old_env_f = Path.C.build_old_env t.compiler nv in
- File.Env.write old_env_f env.old_env;
(* Call the build script and copy the output files *)
let commands = List.map (List.map (substitute_string t))
View
20 src/file.ml
@@ -341,6 +341,7 @@ module OPAM = struct
version : V.t;
maintainer : string;
substs : basename list;
+ build_env : (string * string * string) list;
build : string list list;
remove : string list list;
depends : cnf_formula;
@@ -357,6 +358,7 @@ module OPAM = struct
version = V.of_string "<none>";
maintainer = "<none>";
substs = [];
+ build_env = [];
build = [];
remove = [];
depends = [];
@@ -377,6 +379,7 @@ module OPAM = struct
let s_maintainer = "maintainer"
let s_substs = "substs"
let s_build = "build"
+ let s_build_env = "build-env"
let s_remove = "remove"
let s_depends = "depends"
let s_depopts = "depopts"
@@ -408,6 +411,7 @@ module OPAM = struct
s_libraries;
s_syntax;
s_ocaml_version;
+ s_build_env;
]
let valid_fields =
@@ -429,6 +433,7 @@ module OPAM = struct
let libraries t = t.libraries
let syntax t = t.syntax
let ocaml_version t = t.ocaml_version
+ let build_env t = t.build_env
let with_depends t depends = { t with depends }
let with_build t build = { t with build }
@@ -470,6 +475,7 @@ module OPAM = struct
Variable (s_version, String (V.to_string t.version));
Variable (s_maintainer, String t.maintainer);
Variable (s_substs, make_list (Basename.to_string |> make_string) t.substs);
+ Variable (s_build_env, make_list make_env_variable t.build_env);
Variable (s_build, make_list (make_list make_string) t.build);
Variable (s_remove, make_list (make_list make_string) t.remove);
Variable (s_depends, make_cnf_formula t.depends);
@@ -511,6 +517,7 @@ module OPAM = struct
let maintainer = assoc s s_maintainer parse_string in
let substs =
assoc_list s s_substs (parse_list (parse_string |> Basename.of_string)) in
+ let build_env = assoc_list s s_build_env (parse_list parse_env_variable) in
let build =
assoc_default Globals.default_build_command s s_build parse_commands in
let remove = assoc_list s s_remove parse_commands in
@@ -527,7 +534,7 @@ module OPAM = struct
) s in
{ name; version; maintainer; substs; build; remove;
depends; depopts; conflicts; libraries; syntax; others;
- ocaml_version; }
+ ocaml_version; build_env }
end
module Dot_install_raw = struct
@@ -912,15 +919,6 @@ module Comp = struct
("camlp4" , parse_camlp4);
("string-list", parse_string_list |> fun x -> Some (Cmd x));
] in
- let parse_env_variable v =
- let l = parse_sequence [
- ("ident" , parse_ident);
- ("symbol", parse_symbol);
- ("string", parse_string)
- ] v in
- match l with
- | [ident; symbol; string] -> (ident, symbol, string)
- | _ -> assert false in
let opam_version =
assoc s s_opam_version (parse_string |> OPAM_V.of_string) in
let name = assoc s s_name (parse_string |> OCaml_V.of_string) in
@@ -958,8 +956,6 @@ module Comp = struct
let make_ppflag = function
| Cmd l -> make_list make_string l
| Camlp4 l -> List (Symbol "CAMLP4" :: List.map make_string l) in
- let make_env_variable (ident, symbol, string) =
- List [make_ident ident; make_symbol symbol; make_string string] in
Syntax.to_string filename {
filename = Filename.to_string filename;
contents = [
View
3 src/file.mli
@@ -95,6 +95,9 @@ module OPAM: sig
(** File substitutions *)
val substs: t -> basename list
+ (** List of environment variables to set-up for the build *)
+ val build_env: t -> (string * string * string) list
+
(** List of command to run for building the package *)
val build: t -> string list list
View
13 src/file_format.ml
@@ -351,3 +351,16 @@ let make_constraint (r, v) =
Symbol (string_of_relop r);
String (Types.OCaml_V.to_string v);
]
+
+let parse_env_variable v =
+ let l = parse_sequence [
+ ("ident" , parse_ident);
+ ("symbol", parse_symbol);
+ ("string", parse_string);
+ ] v in
+ match l with
+ | [ident; symbol; string] -> (ident, symbol, string)
+ | _ -> assert false
+
+let make_env_variable (ident, symbol, string) =
+ List [make_ident ident; make_symbol symbol; make_string string]
View
8 src/file_format.mli
@@ -221,3 +221,11 @@ val parse_constraint: value -> ocaml_constraint
(** Build a simple constraint *)
val make_constraint: ocaml_constraint -> value
+
+(** {2 Environment variables} *)
+
+(** Parsing *)
+val parse_env_variable: value -> (string * string * string)
+
+(** Making *)
+val make_env_variable: (string * string * string) -> value
View
9 src/run.ml
@@ -192,7 +192,7 @@ let replace_path bins =
| Some (k,v) -> k,v
| None -> assert false in
if k = "PATH" then
- let v = Utils.reset_env_value v in
+ let v = Utils.split v ':' in
let bins = List.filter Sys.file_exists bins in
let new_path = String.concat ":" (bins @ v) in
env.(i) <- "PATH=" ^ new_path;
@@ -359,6 +359,13 @@ let ocaml_version () =
with _ ->
None
+let ocamlc_where () =
+ try
+ let s = read_command_output [ "ocamlc"; "-where" ] in
+ Some (Utils.string_strip (List.hd s))
+ with _ ->
+ None
+
(* Only used by the compiler switch stuff *)
let download src dst =
let cmd = match Globals.os with
View
3 src/run.mli
@@ -63,6 +63,9 @@ val rec_files: string -> string list
compiler is present in the path, then it returns [None]. *)
val ocaml_version: unit -> string option
+(** Return the path where ocamlc library is installed *)
+val ocamlc_where: unit -> string option
+
(** [files dir] returns the directories in the directory [dir] *)
val directories: string -> string list
View
6 src/utils.ml
@@ -81,7 +81,7 @@ let rcut_at = cut_at_aux String.rindex
let split s c =
Pcre.split (Pcre.regexp (String.make 1 c)) s
-(* Remove from a ':' separated list of string the one which are prefix of Globals.root_path *)
-let reset_env_value v =
+(* Remove from a ':' separated list of string the one with the given prefix *)
+let reset_env_value ~prefix v =
let v = split v ':' in
- List.filter (fun v -> not (starts_with ~prefix:!Globals.root_path v)) v
+ List.filter (fun v -> not (starts_with ~prefix v)) v

0 comments on commit 1a8edd1

Please sign in to comment.
Something went wrong with that request. Please try again.