diff --git a/infer/lib/python/infer.py b/infer/lib/python/infer.py index f38da14a6..8569912af 100755 --- a/infer/lib/python/infer.py +++ b/infer/lib/python/infer.py @@ -45,6 +45,7 @@ MODULE_TO_COMMAND = { 'xcodebuild': ['xcodebuild'], 'mvn': ['mvn'], 'ndk-build': ['ndk-build'], + 'clang-compilation-database': ['clang-compilation-database'], } diff --git a/infer/lib/python/inferlib/capture/clang-compilation-database.py b/infer/lib/python/inferlib/capture/clang-compilation-database.py new file mode 100644 index 000000000..6f5cdbbb2 --- /dev/null +++ b/infer/lib/python/inferlib/capture/clang-compilation-database.py @@ -0,0 +1,38 @@ +import util + +# Copyright (c) 2016 - 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. + +from inferlib import config, utils +import subprocess + +MODULE_NAME = 'clang-compilation-database' +MODULE_DESCRIPTION = '''Run analysis of code built with the compilation database proided: +clang-compilation-database db.json''' + +# This creates an empty argparser for the module, which provides only +# description/usage information and no arguments. +create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME) + + +def gen_instance(*args): + return ClangCompilationDatabase(*args) + + +class ClangCompilationDatabase: + def __init__(self, args, cmd): + self.args = args + self.cmd = cmd + + def capture(self): + args = self.cmd + cmd = [utils.get_cmd_in_bin_dir('InferBuckCompilationDatabase')] + if self.args.project_root: + cmd += ['--project-root', self.args.project_root] + cmd += ['--clang-compilation-database', args[1]] + print(cmd) + return subprocess.check_call(cmd) diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index a327583c8..bea1acfa9 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -674,6 +674,11 @@ and check_duplicate_symbols = ~exes:CLOpt.[Analyze] "Check if a symbol with the same name is defined in more than one file." +and clang_compilation_database = + CLOpt.mk_string_opt ~long:"clang-compilation-database" + ~exes:CLOpt.[BuckCompilationDatabase] ~meta:"file" + "Specify a json file containing a clang compilation database to be used for the analysis" + and clang_frontend_action = CLOpt.mk_symbol_opt ~long:"clang-frontend-action" ~exes:CLOpt.[Clang] @@ -1418,6 +1423,7 @@ and checkers = !checkers (** should the checkers be run? *) and checkers_enabled = not (!eradicate || !crashcontext || !quandary) and clang_biniou_file = !clang_biniou_file +and clang_compilation_database = !clang_compilation_database and clang_frontend_do_capture, clang_frontend_do_lint = match !clang_frontend_action with | Some `Lint -> false, true (* no capture, lint *) diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index eefb09bfe..c9cf1c3bb 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -172,6 +172,7 @@ val check_duplicate_symbols : bool val checkers : bool val checkers_enabled : bool val clang_biniou_file : string option +val clang_compilation_database : string option val clang_frontend_action_string : string val clang_frontend_do_capture : bool val clang_frontend_do_lint : bool diff --git a/infer/src/integration/BuckCompilationDatabase.ml b/infer/src/integration/BuckCompilationDatabase.ml index 56bd64102..59f8c45d0 100644 --- a/infer/src/integration/BuckCompilationDatabase.ml +++ b/infer/src/integration/BuckCompilationDatabase.ml @@ -119,10 +119,13 @@ let run_compilation_database compilation_database = let job_to_string = fun file -> capture_text_upper ^ " " ^ file in Process.run_jobs_in_parallel jobs_stack (run_compilation_file compilation_database) job_to_string +let should_add_file_to_cdb changed_files file_path = + match Config.changed_files_index with + | Some _ -> DB.SourceFileSet.mem (DB.source_file_from_string file_path) changed_files + | None -> true -(** Computes the compilation database: a map from a file path to info to compile the file, i.e. - the dir where the compilation should be executed and the arguments to clang.*) -let get_compilation_database changed_files = +(** Computes the compilation database files. *) +let get_compilation_database_files () = let cmd = IList.rev_append Config.rest (IList.rev Config.buck_build_args) in match cmd with | buck :: build :: args -> @@ -143,15 +146,7 @@ let get_compilation_database changed_files = (fun target file -> StringMap.add target file compilation_database_files) in (* Map from targets to json output *) let compilation_database_files = IList.fold_left scan_output StringMap.empty lines in - let compilation_database = CompilationDatabase.empty () in - let should_add_file file_path = - match Config.changed_files_index with - | Some _ -> DB.SourceFileSet.mem (DB.source_file_from_string file_path) changed_files - | None -> true in - StringMap.iter - (fun _ file -> CompilationDatabase.decode_json_file compilation_database should_add_file file) - compilation_database_files; - compilation_database + IList.map (snd) (StringMap.bindings compilation_database_files) with Unix.Unix_error (err, _, _) -> Process.print_error_and_exit "Cannot execute %s\n%!" @@ -162,6 +157,19 @@ let get_compilation_database changed_files = let () = let changed_files = read_files_to_compile () in - let compilation_database = get_compilation_database changed_files in + let db_json_files = + match Config.clang_compilation_database with + | Some file -> [file] + | None -> + if Option.is_some Config.use_compilation_database then + get_compilation_database_files () + else failwith( + "Either the option clang_compilation_database or the option \ + use_compilation_database should be passed to this module ") in + let compilation_database = CompilationDatabase.empty () in + IList.iter + (CompilationDatabase.decode_json_file + compilation_database (should_add_file_to_cdb changed_files)) db_json_files; + create_dir (Config.results_dir // Config.clang_build_output_dir_name); run_compilation_database compilation_database