(* * Copyright (c) 2017 - present Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. *) open! IStd module F = Format module L = Logging type compiler = | Clang | Make [@@deriving compare] let rec pp_list pp fmt = function | [] -> () | x::[] -> pp fmt x | x::tl -> F.fprintf fmt "%a@\n%a" pp x (pp_list pp) tl let pp_env fmt env = pp_list (fun fmt s -> F.fprintf fmt "%s" s) fmt env let pp_extended_env fmt (env : Unix.env) = let pp_pair fmt (var, value) = F.fprintf fmt "%s=%s" var value in let pp_pair_list = pp_list pp_pair in match env with | `Replace values -> pp_pair_list fmt values | `Extend values -> let is_extended s = match String.lsplit2 s ~on:'=' with | Some (var, _) -> List.exists ~f:(fun (var', _) -> String.equal var var') values | None -> false in let env_not_extended = Unix.environment () |> Array.to_list |> List.filter ~f:(Fn.non is_extended) in F.fprintf fmt "%a@\n%a" pp_env env_not_extended pp_pair_list values | `Replace_raw values -> pp_env fmt values let capture compiler ~prog ~args = match compiler with | Clang -> ClangWrapper.exe ~prog ~args | Make -> let path_var = "PATH" in let new_path = Config.wrappers_dir ^ ":" ^ (Sys.getenv_exn path_var) in let extended_env = `Extend [path_var, new_path] in L.environment_info "Running command %s with env:@\n%a@\n@." prog pp_extended_env extended_env; Unix.fork_exec ~prog:prog ~argv:(prog::args) ~env:extended_env () |> Unix.waitpid |> function | Ok () -> () | Error _ as status -> failwithf "*** capture command failed:@\n*** %s@\n*** %s@." (String.concat ~sep:" " (prog::args)) (Unix.Exit_or_signal.to_string_hum status)