From 64791d11367e6d15c3dd0b90c1d979bda9f02cb7 Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Wed, 29 Mar 2017 05:41:14 -0700 Subject: [PATCH] [driver] Bring clang capture from python to ocaml Reviewed By: jvillard Differential Revision: D4764817 fbshipit-source-id: 599577c --- infer/src/backend/infer.ml | 24 +++++++++++----- infer/src/integration/Clang.ml | 49 +++++++++++++++++++++++++++++++++ infer/src/integration/Clang.mli | 15 ++++++++++ 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 infer/src/integration/Clang.ml create mode 100644 infer/src/integration/Clang.mli diff --git a/infer/src/backend/infer.ml b/infer/src/backend/infer.ml index fb38458cb..304f2a630 100644 --- a/infer/src/backend/infer.ml +++ b/infer/src/backend/infer.ml @@ -42,7 +42,8 @@ let rec rmtree name = type build_system = - | BAnalyze | BAnt | BBuck | BGradle | BJava | BJavac | BMake | BMvn | BNdk | BXcode + | BAnalyze | BAnt | BBuck | BClang | BGradle | BJava | BJavac | BMake | BMvn + | BNdk | BXcode [@@deriving compare] let equal_build_system = [%compare.equal : build_system] @@ -53,10 +54,8 @@ let equal_build_system = [%compare.equal : build_system] let build_system_exe_assoc = [ BAnalyze, "analyze"; BAnt, "ant"; BBuck, "buck"; BGradle, "gradle"; BGradle, "gradlew"; BJava, "java"; BJavac, "javac"; - (* NOTE: "make/cc" is not a valid exe name and thus will never be matched, we only use it for - printing *) - BMake, "make/cc"; BMake, "cc"; BMake, "clang"; BMake, "clang++"; BMake, "cmake"; - BMake, "configure"; BMake, "g++"; BMake, "gcc"; BMake, "make"; BMake, "waf"; + BClang, "cc"; BClang, "clang"; BClang, "gcc"; BClang, "clang++"; BClang, "c++"; BClang, "g++"; + BMake, "make"; BMake, "configure"; BMake, "cmake"; BMake, "waf"; BMvn, "mvn"; BMvn, "mvnw"; BNdk, "ndk-build"; BXcode, "xcodebuild"; ] @@ -74,6 +73,7 @@ type driver_mode = | Analyze | BuckGenrule of string | BuckCompilationDB + | Clang of Clang.compiler * string * string list | ClangCompilationDB of [ `Escaped of string | `Raw of string ] list | Javac of Javac.compiler * string * string list | Maven of string * string list @@ -111,6 +111,9 @@ let pp_driver_mode fmt driver_mode = | Maven (prog, args) -> F.fprintf fmt "Maven driver mode:@\nprog = %s@\n" prog; List.iter ~f:(F.fprintf fmt "Arg: %s@\n") args + | Clang (_, prog, args) -> + F.fprintf fmt "Clang driver mode:@\nprog = %s@\n" prog; + List.iter ~f:(F.fprintf fmt "Arg: %s@\n") args let remove_results_dir () = rmtree Config.results_dir @@ -216,6 +219,9 @@ let capture = function | BuckGenrule path -> L.stdout "Capturing for Buck genrule compatibility...@\n"; JMain.from_arguments path + | Clang (compiler, prog, args) -> + L.stdout "Capturing in make/cc mode...@\n"; + Clang.capture compiler ~prog ~args | ClangCompilationDB db_files -> L.stdout "Capturing using compilation database...@\n"; capture_with_compilation_database db_files @@ -392,7 +398,7 @@ let assert_supported_build_system build_system = match build_system with | BAnt | BGradle | BJava | BJavac | BMvn -> string_of_build_system build_system |> assert_supported_mode `Java - | BMake | BNdk -> + | BClang | BMake | BNdk -> string_of_build_system build_system |> assert_supported_mode `Clang | BXcode -> @@ -423,6 +429,10 @@ let driver_mode_of_build_cmd build_cmd = Analyze | BBuck when Option.is_some Config.buck_compilation_database -> BuckCompilationDB + | BClang -> + Clang (Clang.Clang, prog, args) + | BMake -> + Clang (Clang.Make, prog, args) | BJava -> Javac (Javac.Java, prog, args) | BJavac -> @@ -431,7 +441,7 @@ let driver_mode_of_build_cmd build_cmd = Maven (prog, args) | BXcode when Config.xcpretty -> XcodeXcpretty - | BAnt | BBuck | BGradle | BMake | BNdk | BXcode as build_system -> + | BAnt | BBuck | BGradle | BNdk | BXcode as build_system -> PythonCapture (build_system, build_cmd) let get_driver_mode () = diff --git a/infer/src/integration/Clang.ml b/infer/src/integration/Clang.ml new file mode 100644 index 000000000..8a08b141e --- /dev/null +++ b/infer/src/integration/Clang.ml @@ -0,0 +1,49 @@ +(* + * 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 + +type compiler = + | Clang + | Make [@@deriving compare] + +let extended_env_to_string (env : Unix.env) = + match env with + | `Replace values + | `Extend values -> + let concat_elt (el1, el2) = String.concat ~sep:"=" [el1; el2] in + String.concat ~sep:"\n" (List.map ~f:concat_elt values) + | `Replace_raw values -> + String.concat ~sep:"\n" values + +let env_to_string ?exclude_var env = + let env_element_to_string elt acc = + match exclude_var with + | Some var when String.is_prefix ~prefix:var elt -> "" + | _ -> + String.concat [elt; acc] ~sep:"\n" in + Array.fold_right ~init:"" ~f:env_element_to_string env + + +(* TODO(t16929015): make the clang/clang++ integration just a function call. *) +let capture _ ~prog ~args = + 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 + Logging.out "Running command %s with env:\n%s %s\n@." + prog + (env_to_string ~exclude_var:path_var (Unix.environment ())) + (extended_env_to_string extended_env); + Unix.fork_exec ~prog:prog ~args:(prog::args) ~env:extended_env () + |> Unix.waitpid + |> function + | Ok () -> () + | Error _ as status -> + failwithf "*** ERROR: capture command failed:@*** %s@*** %s@" + (String.concat ~sep:" " (prog::args)) + (Unix.Exit_or_signal.to_string_hum status) diff --git a/infer/src/integration/Clang.mli b/infer/src/integration/Clang.mli new file mode 100644 index 000000000..269d29418 --- /dev/null +++ b/infer/src/integration/Clang.mli @@ -0,0 +1,15 @@ +(* + * 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 + +type compiler = + | Clang + | Make [@@deriving compare] + +val capture : compiler -> prog:string -> args:string list -> unit