[clang] Fail when compilations fails in the capture, linters mode

Reviewed By: jvillard

Differential Revision: D4237708

fbshipit-source-id: 0e4c210
master
Dulma Churchill 8 years ago committed by Facebook Github Bot
parent f6e8bf0f3f
commit ffd82c01a7

@ -600,7 +600,7 @@ and clang_compilation_db_files =
and clang_frontend_action = and clang_frontend_action =
CLOpt.mk_symbol_opt ~long:"clang-frontend-action" CLOpt.mk_symbol_opt ~long:"clang-frontend-action"
~exes:CLOpt.[Clang] ~exes:CLOpt.[Clang;Driver]
"Specify whether the clang frontend should capture or lint or both." "Specify whether the clang frontend should capture or lint or both."
~symbols:clang_frontend_action_symbols ~symbols:clang_frontend_action_symbols
@ -633,6 +633,12 @@ and continue =
"Continue the capture for the reactive analysis, increasing the changed files/procedures. (If \ "Continue the capture for the reactive analysis, increasing the changed files/procedures. (If \
a procedure was changed beforehand, keep the changed marking.)" a procedure was changed beforehand, keep the changed marking.)"
and linters_ignore_clang_failures =
CLOpt.mk_bool ~long:"linters-ignore-clang-failures"
~exes:CLOpt.[Driver]
~default:false
"Continue linting files even if some compilation fails."
and copy_propagation = and copy_propagation =
CLOpt.mk_bool ~deprecated:["copy-propagation"] ~long:"copy-propagation" CLOpt.mk_bool ~deprecated:["copy-propagation"] ~long:"copy-propagation"
"Perform copy-propagation on the IR" "Perform copy-propagation on the IR"
@ -1422,6 +1428,7 @@ and classpath = !classpath
and cluster_cmdline = !cluster and cluster_cmdline = !cluster
and compute_analytics = !compute_analytics and compute_analytics = !compute_analytics
and continue_capture = !continue and continue_capture = !continue
and linters_ignore_clang_failures = !linters_ignore_clang_failures
and copy_propagation = !copy_propagation and copy_propagation = !copy_propagation
and crashcontext = !crashcontext and crashcontext = !crashcontext
and create_harness = !android_harness and create_harness = !android_harness

@ -174,6 +174,7 @@ val clang_include_to_override : string option
val cluster_cmdline : string option val cluster_cmdline : string option
val compute_analytics : bool val compute_analytics : bool
val continue_capture : bool val continue_capture : bool
val linters_ignore_clang_failures : bool
val copy_propagation : bool val copy_propagation : bool
val crashcontext : bool val crashcontext : bool
val create_harness : bool val create_harness : bool

@ -38,11 +38,15 @@ let create_process_and_wait ~prog ~args =
(** Given a process id and a function that describes the command that the process id (** Given a process id and a function that describes the command that the process id
represents, prints a message explaining the command and its status, if in debug or stats mode. represents, prints a message explaining the command and its status, if in debug or stats mode.
It also prints a dot to show progress of jobs being finished. *) It also prints a dot to show progress of jobs being finished. *)
let print_status f pid status = let print_status ~fail_on_failed_job f pid status =
L.err "%a%s@." L.err "%a%s@."
(fun fmt pid -> F.pp_print_string fmt (f pid)) pid (fun fmt pid -> F.pp_print_string fmt (f pid)) pid
(Unix.Exit_or_signal.to_string_hum status) ; (Unix.Exit_or_signal.to_string_hum status) ;
L.stdout ".%!" L.stdout ".%!";
match status with
| Error err when fail_on_failed_job ->
exit (match err with `Exit_non_zero i -> i | `Signal _ -> 1)
| _ -> ()
let start_current_jobs_count () = ref 0 let start_current_jobs_count () = ref 0
@ -53,14 +57,14 @@ module PidMap = Caml.Map.Make (Pid)
(** [wait_for_son pid_child f jobs_count] wait for pid_child (** [wait_for_son pid_child f jobs_count] wait for pid_child
and all the other children and update the current jobs count. and all the other children and update the current jobs count.
Use f to print the job status *) Use f to print the job status *)
let rec wait_for_child f current_jobs_count jobs_map = let rec wait_for_child ~fail_on_failed_job f current_jobs_count jobs_map =
let pid, status = Unix.wait `Any in let pid, status = Unix.wait `Any in
Pervasives.decr current_jobs_count; Pervasives.decr current_jobs_count;
Pervasives.incr waited_for_jobs; Pervasives.incr waited_for_jobs;
print_status f pid status; print_status ~fail_on_failed_job f pid status;
jobs_map := PidMap.remove pid !jobs_map; jobs_map := PidMap.remove pid !jobs_map;
if not (PidMap.is_empty !jobs_map) then if not (PidMap.is_empty !jobs_map) then
wait_for_child f current_jobs_count jobs_map wait_for_child ~fail_on_failed_job f current_jobs_count jobs_map
let pid_to_program jobsMap pid = let pid_to_program jobsMap pid =
try try
@ -72,7 +76,7 @@ let pid_to_program jobsMap pid =
and starts a new batch and so on. [gen_prog] should return a tuple [(dir_opt, command, args, and starts a new batch and so on. [gen_prog] should return a tuple [(dir_opt, command, args,
env)] where [dir_opt] is an optional directory to chdir to before executing [command] with env)] where [dir_opt] is an optional directory to chdir to before executing [command] with
[args] in [env]. [prog_to_string] is used for printing information about the job's status. *) [args] in [env]. [prog_to_string] is used for printing information about the job's status. *)
let run_jobs_in_parallel jobs_stack gen_prog prog_to_string = let run_jobs_in_parallel ?(fail_on_failed_job=false) jobs_stack gen_prog prog_to_string =
let run_job () = let run_job () =
let jobs_map = ref PidMap.empty in let jobs_map = ref PidMap.empty in
let current_jobs_count = start_current_jobs_count () in let current_jobs_count = start_current_jobs_count () in
@ -89,7 +93,8 @@ let run_jobs_in_parallel jobs_stack gen_prog prog_to_string =
| `In_the_parent pid_child -> | `In_the_parent pid_child ->
jobs_map := PidMap.add pid_child (prog_to_string job_prog) !jobs_map; jobs_map := PidMap.add pid_child (prog_to_string job_prog) !jobs_map;
if Int.equal (Stack.length jobs_stack) 0 || !current_jobs_count >= Config.jobs then if Int.equal (Stack.length jobs_stack) 0 || !current_jobs_count >= Config.jobs then
wait_for_child (pid_to_program !jobs_map) current_jobs_count jobs_map wait_for_child ~fail_on_failed_job (pid_to_program !jobs_map) current_jobs_count
jobs_map
done in done in
run_job (); run_job ();
L.stdout ".@."; L.stdout ".@.";

@ -25,8 +25,8 @@ val print_error_and_exit :
env)] where [dir_opt] is an optional directory to chdir to before executing [command] with env)] where [dir_opt] is an optional directory to chdir to before executing [command] with
[args] in [env]. [prog_to_string] is used for printing information about the job's status. *) [args] in [env]. [prog_to_string] is used for printing information about the job's status. *)
val run_jobs_in_parallel : val run_jobs_in_parallel :
'a Stack.t -> ('a -> (string option * string * string list * Unix.env)) -> ('a -> string) ?fail_on_failed_job:bool -> 'a Stack.t ->
-> unit ('a -> (string option * string * string list * Unix.env)) -> ('a -> string) -> unit
(** Pipeline producer program into consumer program *) (** Pipeline producer program into consumer program *)
val pipeline : val pipeline :

@ -94,6 +94,11 @@ let clang_cc1_cmd_sanitizer cmd => {
/* compilation-database-buck integration produces path to `dep.tmp` file that doesn't exist. Create it */ /* compilation-database-buck integration produces path to `dep.tmp` file that doesn't exist. Create it */
Unix.mkdir_p (Filename.dirname arg); Unix.mkdir_p (Filename.dirname arg);
arg arg
} else if (
String.equal option "-dependency-file" && Option.is_some Config.use_compilation_database
/* In compilation database mode, dependency files are not assumed to exist */
) {
"/dev/null"
} else if ( } else if (
String.equal option "-isystem" String.equal option "-isystem"
) { ) {

@ -86,7 +86,14 @@ let run_compilation_database compilation_database should_capture_file =
let capture_text_upper = String.capitalize capture_text in let capture_text_upper = String.capitalize capture_text in
let job_to_string = let job_to_string =
fun file -> Format.asprintf "%s %a" capture_text_upper SourceFile.pp file in fun file -> Format.asprintf "%s %a" capture_text_upper SourceFile.pp file in
Process.run_jobs_in_parallel jobs_stack (run_compilation_file compilation_database) job_to_string let fail_on_failed_job =
if Config.linters_ignore_clang_failures then false
else
match Config.use_compilation_database with
| Some `NoDeps -> Config.clang_frontend_do_lint
| _ -> false in
Process.run_jobs_in_parallel ~fail_on_failed_job jobs_stack
(run_compilation_file compilation_database) job_to_string
(** Computes the compilation database files. *) (** Computes the compilation database files. *)
let get_compilation_database_files_buck () = let get_compilation_database_files_buck () =

Loading…
Cancel
Save