[config] Convert FCP env vars to Config options

Reviewed By: jvillard

Differential Revision: D4074683

fbshipit-source-id: a3b3703
master
Josh Berdine 8 years ago committed by Facebook Github Bot
parent 7ae58d78c3
commit eee940b2a1

@ -177,7 +177,11 @@ class BuckAnalyzer:
'is located') 'is located')
return os.EX_USAGE return os.EX_USAGE
env_vars = utils.read_env() env_vars = utils.read_env()
env_vars['FCP_RUN_SYNTAX_ONLY'] = '1' infer_args = env_vars['INFER_ARGS']
if infer_args != '':
infer_args += '^' # '^' must be CommandLineOption.env_var_sep
infer_args += '--fcp-syntax-only'
env_vars['INFER_ARGS'] = infer_args
env = utils.encode_env(env_vars) env = utils.encode_env(env_vars)
command = self.cmd command = self.cmd
command += ['-j', str(self.args.multicore)] command += ['-j', str(self.args.multicore)]

@ -51,7 +51,11 @@ class XcodebuildCapture:
def get_envvars(self): def get_envvars(self):
env_vars = utils.read_env() env_vars = utils.read_env()
env_vars['FCP_APPLE_CLANG'] = self.apple_clang_path infer_args = env_vars['INFER_ARGS']
if infer_args != '':
infer_args += '^' # '^' must be CommandLineOption.env_var_sep
infer_args += '--fcp-apple-clang^' + self.apple_clang_path
env_vars['INFER_ARGS'] = infer_args
return env_vars return env_vars
def capture(self): def capture(self):

@ -439,21 +439,22 @@ let decode_inferconfig_to_argv current_exe path =
IList.fold_left one_config_item [] json_config IList.fold_left one_config_item [] json_config
(** [sep_char] is used to separate elements of argv when encoded into environment variables *) (** separator of argv elements when encoded into environment variables *)
let sep_char = '^' let env_var_sep = '^'
let encode_argv_to_env argv = let encode_argv_to_env argv =
String.concat (String.make 1 sep_char) String.concat (String.make 1 env_var_sep)
(IList.filter (fun arg -> (IList.filter (fun arg ->
not (String.contains arg sep_char) not (String.contains arg env_var_sep)
|| ( || (
F.eprintf "Ignoring unsupported option containing '%c' character: %s@\n" sep_char arg ; F.eprintf "Ignoring unsupported option containing '%c' character: %s@\n"
env_var_sep arg ;
false false
) )
) argv) ) argv)
let decode_env_to_argv env = let decode_env_to_argv env =
Str.split (Str.regexp_string (String.make 1 sep_char)) env Str.split (Str.regexp_string (String.make 1 env_var_sep)) env
let prepend_to_argv args = let prepend_to_argv args =
let cl_args = match Array.to_list Sys.argv with _ :: tl -> tl | [] -> [] in let cl_args = match Array.to_list Sys.argv with _ :: tl -> tl | [] -> [] in
@ -467,7 +468,10 @@ let prefix_before_rest args =
prefix_before_rest_ [] args prefix_before_rest_ [] args
let parse ?(incomplete=false) ?(accept_unknown=false) ?config_file env_var current_exe exe_usage = (** environment variable use to pass arguments from parent to child processes *)
let args_env_var = "INFER_ARGS"
let parse ?(incomplete=false) ?(accept_unknown=false) ?config_file current_exe exe_usage =
let curr_speclist = ref [] let curr_speclist = ref []
and full_speclist = ref [] and full_speclist = ref []
in in
@ -561,7 +565,7 @@ let parse ?(incomplete=false) ?(accept_unknown=false) ?config_file env_var curre
; ;
full_speclist := add_or_suppress_help (normalize !full_desc_list) full_speclist := add_or_suppress_help (normalize !full_desc_list)
; ;
let env_args = decode_env_to_argv (try Unix.getenv env_var with Not_found -> "") in let env_args = decode_env_to_argv (try Unix.getenv args_env_var with Not_found -> "") in
(* begin transitional support for INFERCLANG_ARGS *) (* begin transitional support for INFERCLANG_ARGS *)
let c_args = let c_args =
Str.split (Str.regexp_string (String.make 1 ':')) Str.split (Str.regexp_string (String.make 1 ':'))
@ -601,6 +605,6 @@ let parse ?(incomplete=false) ?(accept_unknown=false) ?config_file env_var curre
in in
parse_loop (); parse_loop ();
if not incomplete then if not incomplete then
Unix.putenv env_var Unix.putenv args_env_var
(encode_argv_to_env (prefix_before_rest (IList.tl (Array.to_list !args_to_parse)))) ; (encode_argv_to_env (prefix_before_rest (IList.tl (Array.to_list !args_to_parse)))) ;
curr_usage curr_usage

@ -103,6 +103,12 @@ val mk_rest :
?exes:exe list -> string -> ?exes:exe list -> string ->
string list ref string list ref
(** environment variable use to pass arguments from parent to child processes *)
val args_env_var : string
(** separator of argv elements when encoded into environment variables *)
val env_var_sep : char
(** [parse env_var exe_usage exe] parses command line arguments as specified by preceding calls to (** [parse env_var exe_usage exe] parses command line arguments as specified by preceding calls to
the [mk_*] functions, and returns a function that prints the usage message and help text then the [mk_*] functions, and returns a function that prints the usage message and help text then
exits. [exe] is used to construct the help message appropriate for that executable. The decoded exits. [exe] is used to construct the help message appropriate for that executable. The decoded
@ -115,4 +121,4 @@ val mk_rest :
and [env_var] is not set. If [accept_unknown] is set, unknown options are treated the same as and [env_var] is not set. If [accept_unknown] is set, unknown options are treated the same as
anonymous arguments. *) anonymous arguments. *)
val parse : ?incomplete:bool -> ?accept_unknown:bool -> ?config_file:string -> val parse : ?incomplete:bool -> ?accept_unknown:bool -> ?config_file:string ->
string -> exe -> (exe -> Arg.usage_msg) -> (int -> 'a) exe -> (exe -> Arg.usage_msg) -> (int -> 'a)

@ -438,7 +438,7 @@ and project_root =
(* Parse the phase 1 options, ignoring the rest *) (* Parse the phase 1 options, ignoring the rest *)
let _ = CLOpt.parse ~incomplete:true "INFER_ARGS" current_exe (fun _ -> "") let _ = CLOpt.parse ~incomplete:true current_exe (fun _ -> "")
(* Define the values that depend on phase 1 options *) (* Define the values that depend on phase 1 options *)
@ -842,6 +842,14 @@ and failures_allowed =
CLOpt.mk_bool ~deprecated_no:["-no_failures_allowed"] ~long:"failures-allowed" ~default:true CLOpt.mk_bool ~deprecated_no:["-no_failures_allowed"] ~long:"failures-allowed" ~default:true
"Fail if at least one of the translations fails (clang only)" "Fail if at least one of the translations fails (clang only)"
and fcp_apple_clang =
CLOpt.mk_string_opt ~long:"fcp-apple-clang"
~meta:"path" "Specify the path to Apple Clang"
and fcp_syntax_only =
CLOpt.mk_bool ~long:"fcp-syntax-only"
"Skip creation of object files"
and filter_paths = and filter_paths =
CLOpt.mk_bool ~long:"filter-paths" ~default:true CLOpt.mk_bool ~long:"filter-paths" ~default:true
"Filters specified in .inferconfig" "Filters specified in .inferconfig"
@ -1399,8 +1407,7 @@ let post_parsing_initialization () =
let parse_args_and_return_usage_exit = let parse_args_and_return_usage_exit =
let usage_exit = let usage_exit =
CLOpt.parse ~accept_unknown:true ~config_file:inferconfig_path CLOpt.parse ~accept_unknown:true ~config_file:inferconfig_path current_exe exe_usage in
"INFER_ARGS" current_exe exe_usage in
post_parsing_initialization () ; post_parsing_initialization () ;
usage_exit usage_exit
@ -1486,6 +1493,8 @@ and eradicate_verbose = !eradicate_verbose
and err_file_cmdline = !err_file and err_file_cmdline = !err_file
and fail_on_bug = !fail_on_bug and fail_on_bug = !fail_on_bug
and failures_allowed = !failures_allowed and failures_allowed = !failures_allowed
and fcp_apple_clang = !fcp_apple_clang
and fcp_syntax_only = !fcp_syntax_only
and filter_paths = !filter_paths and filter_paths = !filter_paths
and filtering = !filtering and filtering = !filtering
and flavors = !flavors and flavors = !flavors

@ -194,6 +194,8 @@ val eradicate_verbose : bool
val err_file_cmdline : string val err_file_cmdline : string
val fail_on_bug : bool val fail_on_bug : bool
val failures_allowed : bool val failures_allowed : bool
val fcp_apple_clang : string option
val fcp_syntax_only : bool
val filter_paths : bool val filter_paths : bool
val filtering : bool val filtering : bool
val flavors : bool val flavors : bool

@ -8,6 +8,8 @@
*/ */
open! Utils; open! Utils;
let module CLOpt = CommandLineOption;
/** this fails the execution of clang if the frontend fails */ /** this fails the execution of clang if the frontend fails */
let report_frontend_failure = not Config.failures_allowed; let report_frontend_failure = not Config.failures_allowed;
@ -113,7 +115,7 @@ let run_plugin_and_frontend frontend clang_args => {
"^" "^"
( (
( (
try [Unix.getenv "INFER_ARGS"] { try [Unix.getenv CLOpt.args_env_var] {
| Not_found => [] | Not_found => []
} }
) @ [ ) @ [
@ -123,7 +125,8 @@ let run_plugin_and_frontend frontend clang_args => {
); );
Format.fprintf Format.fprintf
debug_script_fmt debug_script_fmt
"INFER_ARGS=\"%s\" %s@\n" "%s=\"%s\" %s@\n"
CLOpt.args_env_var
infer_clang_options infer_clang_options
(ClangCommand.with_exec Sys.executable_name clang_args |> ClangCommand.command_to_run); (ClangCommand.with_exec Sys.executable_name clang_args |> ClangCommand.command_to_run);
Format.fprintf Format.fprintf

@ -31,29 +31,13 @@ let fcp_dir =
/** path of the plugin to load in clang */ /** path of the plugin to load in clang */
let plugin_path = fcp_dir /\/ "libtooling" /\/ "build" /\/ "FacebookClangPlugin.dylib"; let plugin_path = fcp_dir /\/ "libtooling" /\/ "build" /\/ "FacebookClangPlugin.dylib";
let test_env_var var =>
switch (Sys.getenv var) {
| "1" => true
| _ => false
| exception Not_found => false
};
/** name of the plugin to use */ /** name of the plugin to use */
let plugin_name = "BiniouASTExporter"; let plugin_name = "BiniouASTExporter";
/** this skips the creation of .o files */
let syntax_only = test_env_var "FCP_RUN_SYNTAX_ONLY";
/** are we running as Apple's clang? */ /** are we running as Apple's clang? */
let has_apple_clang = let has_apple_clang = Config.fcp_apple_clang != None;
switch (Sys.getenv "FCP_APPLE_CLANG") {
| bin when bin != "" => true
| _ => false
| exception Not_found => false
};
/** whether to amend include search path with C++ model headers */ /** whether to amend include search path with C++ model headers */
@ -193,7 +177,7 @@ let with_plugin_args args => {
"-plugin-arg-" ^ plugin_name, "-plugin-arg-" ^ plugin_name,
"PREPEND_CURRENT_DIR=1" "PREPEND_CURRENT_DIR=1"
]; ];
let args_after = [] |> do_if syntax_only (cons "-fsyntax-only"); let args_after = [] |> do_if Config.fcp_syntax_only (cons "-fsyntax-only");
{...args, argv: IList.rev_append rev_args_before (args.argv @ args_after)} {...args, argv: IList.rev_append rev_args_before (args.argv @ args_after)}
}; };

@ -116,13 +116,13 @@ let exe args xx_suffix => {
/* xcodebuild projects may require the object files to be generated by the Apple compiler, eg to /* xcodebuild projects may require the object files to be generated by the Apple compiler, eg to
generate precompiled headers compatible with Apple's clang. */ generate precompiled headers compatible with Apple's clang. */
let should_run_original_command = let should_run_original_command =
switch (Sys.getenv "FCP_APPLE_CLANG") { switch Config.fcp_apple_clang {
| bin => | Some bin =>
let bin_xx = bin ^ xx_suffix; let bin_xx = bin ^ xx_suffix;
Logging.out "Will run Apple clang %s" bin_xx; Logging.out "Will run Apple clang %s" bin_xx;
args.(0) = bin_xx; args.(0) = bin_xx;
true true
| exception Not_found => false | None => false
}; };
IList.iter execute_clang_command commands; IList.iter execute_clang_command commands;
if (commands == [] || should_run_original_command) { if (commands == [] || should_run_original_command) {

@ -9,6 +9,9 @@
open! Utils open! Utils
module CLOpt = CommandLineOption
module F = Format
let capture_text = let capture_text =
if Config.analyzer = Some Config.Linters then "linting" if Config.analyzer = Some Config.Linters then "linting"
else "translating" else "translating"
@ -89,9 +92,22 @@ let run_compilation_file compilation_database file =
ClangQuotes.mk_arg_file ClangQuotes.mk_arg_file
"cdb_clang_args_" ClangQuotes.EscapedNoQuotes [compilation_data.args] in "cdb_clang_args_" ClangQuotes.EscapedNoQuotes [compilation_data.args] in
let args = Array.of_list [wrapper_cmd; "@" ^ arg_file] in let args = Array.of_list [wrapper_cmd; "@" ^ arg_file] in
let env = Array.append let env =
(Unix.environment()) let env0 = Unix.environment () in
(Array.of_list ["FCP_RUN_SYNTAX_ONLY=1"]) in let found = ref false in
Array.iteri (fun i key_val ->
match string_split_character key_val '=' with
| Some var, args when string_equal var CLOpt.args_env_var ->
found := true ;
env0.(i) <-
F.sprintf "%s=%s%c--fcp-syntax-only" CLOpt.args_env_var args CLOpt.env_var_sep
| _ ->
()
) env0 ;
if !found then
env0
else
Array.append env0 [|CLOpt.args_env_var ^ "=--fcp-syntax-only"|] in
(Some compilation_data.dir, wrapper_cmd, args, env) (Some compilation_data.dir, wrapper_cmd, args, env)
with Not_found -> with Not_found ->
Process.print_error_and_exit "Failed to find compilation data for %s \n%!" file Process.print_error_and_exit "Failed to find compilation data for %s \n%!" file

Loading…
Cancel
Save