From 5f9c020570e318144f8dfe776a5e6769e1df720c Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Wed, 6 Sep 2017 05:48:06 -0700 Subject: [PATCH] [buck integration] Support passing targets by file to buck in both the compilation database integration and the flavors integration Reviewed By: jvillard Differential Revision: D5763855 fbshipit-source-id: 0e3e367 --- infer/src/integration/Buck.ml | 28 ++++++++++++++++++- infer/src/integration/Buck.mli | 7 +++++ .../integration/CaptureCompilationDatabase.ml | 14 ++++------ infer/src/integration/Driver.ml | 11 +++++++- .../build_systems/buck-clang-db/Makefile | 2 +- .../build_systems/buck-clang-db/issues.exp | 1 + .../tests/build_systems/buck_flavors/Makefile | 2 +- .../buck_flavors/buck_target.txt | 1 + .../build_systems/buck_flavors/issues.exp | 1 + .../tests/build_systems/buck_flavors/src/BUCK | 7 +++++ .../build_systems/buck_flavors/src/hello3.c | 15 ++++++++++ .../clang_compilation_database/BUCK | 7 +++++ .../buck_target_hello_test.txt | 1 + .../clang_compilation_database/hello_test.c | 15 ++++++++++ 14 files changed, 99 insertions(+), 13 deletions(-) create mode 100644 infer/tests/build_systems/buck_flavors/buck_target.txt create mode 100644 infer/tests/build_systems/buck_flavors/src/hello3.c create mode 100644 infer/tests/build_systems/codetoanalyze/clang_compilation_database/buck_target_hello_test.txt create mode 100644 infer/tests/build_systems/codetoanalyze/clang_compilation_database/hello_test.c diff --git a/infer/src/integration/Buck.ml b/infer/src/integration/Buck.ml index 85186e8a7..10b3d758c 100644 --- a/infer/src/integration/Buck.ml +++ b/infer/src/integration/Buck.ml @@ -82,7 +82,7 @@ let get_dependency_targets_and_add_flavors targets ~depth = ^ build_deps_string targets ^ ")\"" ) ] in let buck_query_cmd = String.concat buck_query ~sep:" " in - Logging.(debug Linters Medium) "*** Executing command:@\n*** %s@." buck_query_cmd ; + Logging.(debug Linters Quiet) "*** Executing command:@\n*** %s@." buck_query_cmd ; let output, exit_or_signal = Utils.with_process_in buck_query_cmd In_channel.input_lines in match exit_or_signal with | Error _ as status @@ -92,3 +92,29 @@ let get_dependency_targets_and_add_flavors targets ~depth = | Ok () -> List.map output ~f:(fun name -> string_of_target (add_flavor_to_target {name; flavors= Config.append_buck_flavors}) ) + +(** Given a list of arguments return the extended list of arguments where +the args in a file have been extracted *) +let inline_argument_files buck_args = + let expand_buck_arg buck_arg = + if String.is_prefix ~prefix:"@" buck_arg then + let file_name = String.chop_prefix_exn ~prefix:"@" buck_arg in + if Sys.file_exists file_name <> `Yes then [buck_arg] + (* Arguments that start with @ could mean something different than an arguments file in buck. *) + else + let expanded_args = + try Utils.with_file_in file_name ~f:In_channel.input_lines + with exn -> + Logging.die UserError "Could not read from file '%s': %a@." file_name Exn.pp exn + in + expanded_args + else [buck_arg] + in + List.concat_map ~f:expand_buck_arg buck_args + +let store_targets_in_file buck_targets = + let file = Filename.temp_file "buck_targets_" ".txt" in + let write_args outc = Out_channel.output_string outc (String.concat ~sep:"\n" buck_targets) in + Utils.with_file_out file ~f:write_args |> ignore ; + L.(debug Capture Quiet) "Buck targets options stored in file '%s'@\n" file ; + Printf.sprintf "@%s" file diff --git a/infer/src/integration/Buck.mli b/infer/src/integration/Buck.mli index d653a2b2e..c0f1f2031 100644 --- a/infer/src/integration/Buck.mli +++ b/infer/src/integration/Buck.mli @@ -26,3 +26,10 @@ val add_flavors_to_buck_command : string list -> string list val get_dependency_targets_and_add_flavors : string list -> depth:int option -> string list (** Runs buck query to get the dependency targets of the given targets [get_dependency_targets args] = targets with dependent targets, other args *) + +val inline_argument_files : string list -> string list +(** Given a list of arguments to buck, return the extended list of arguments where + the args in a file have been extracted *) + +val store_targets_in_file : string list -> string +(** Given a list of buck targets, stores them in a file and returns the file name *) diff --git a/infer/src/integration/CaptureCompilationDatabase.ml b/infer/src/integration/CaptureCompilationDatabase.ml index cbad46185..677dcab9f 100644 --- a/infer/src/integration/CaptureCompilationDatabase.ml +++ b/infer/src/integration/CaptureCompilationDatabase.ml @@ -64,16 +64,10 @@ let run_compilation_database compilation_database should_capture_file = Process.run_jobs_in_parallel ~fail_on_failed_job jobs_stack (run_compilation_file compilation_database) job_to_string -let buck_targets_in_file buck_targets = - let file = Filename.temp_file "buck_targets_" ".txt" in - let write_args outc = Out_channel.output_string outc (String.concat ~sep:"\n" buck_targets) in - Utils.with_file_out file ~f:write_args |> ignore ; - L.(debug Capture Quiet) "Buck targets options stored in file %s@\n" file ; - Printf.sprintf "@%s" file - (** Computes the compilation database files. *) let get_compilation_database_files_buck ~prog ~args = - let targets, no_targets = List.partition_tf ~f:Buck.is_target_string args in + let all_buck_args = Buck.inline_argument_files args in + let targets, no_targets = List.partition_tf ~f:Buck.is_target_string all_buck_args in let targets = match Config.buck_compilation_database with | Some Deps depth @@ -84,8 +78,10 @@ let get_compilation_database_files_buck ~prog ~args = match no_targets with | "build" :: _ -> ( - let targets_in_file = buck_targets_in_file targets in + let targets_in_file = Buck.store_targets_in_file targets in let build_args = no_targets @ ["--config"; "*//cxx.pch_enabled=false"; targets_in_file] in + Logging.(debug Linters Quiet) + "Processed buck command is : 'buck %s'@\n" (String.concat ~sep:" " build_args) ; Process.create_process_and_wait ~prog ~args:build_args ; let buck_targets_shell = [prog; "targets"; "--show-output"; targets_in_file] |> Utils.shell_escape_command diff --git a/infer/src/integration/Driver.ml b/infer/src/integration/Driver.ml index 1cded1314..8708a6ce5 100644 --- a/infer/src/integration/Driver.ml +++ b/infer/src/integration/Driver.ml @@ -330,7 +330,16 @@ let capture ~changed_files = function (Option.to_list (Sys.getenv CLOpt.args_env_var) @ ["--buck"]) in Unix.putenv ~key:CLOpt.args_env_var ~data:infer_args_with_buck ; - Buck.add_flavors_to_buck_command build_cmd + let all_buck_args = Buck.inline_argument_files build_cmd in + let targets, no_targets = + List.partition_tf ~f:Buck.is_target_string all_buck_args + in + let targets_with_flavor = Buck.add_flavors_to_buck_command targets in + let targets_in_file = Buck.store_targets_in_file targets_with_flavor in + let updated_buck_cmd = no_targets @ [targets_in_file] in + Logging.(debug Capture Quiet) + "Processed buck command '%s'@\n" (String.concat ~sep:" " updated_buck_cmd) ; + updated_buck_cmd else build_cmd ) ) in run_command ~prog:infer_py ~args diff --git a/infer/tests/build_systems/buck-clang-db/Makefile b/infer/tests/build_systems/buck-clang-db/Makefile index 2e974a7f0..e38b909ed 100644 --- a/infer/tests/build_systems/buck-clang-db/Makefile +++ b/infer/tests/build_systems/buck-clang-db/Makefile @@ -24,4 +24,4 @@ infer-out/report.json: $(CLANG_DEPS) $(SOURCES) NO_BUCKD=1 \ $(INFER_BIN) -a $(ANALYZER) --stats $(INFER_OPTIONS) -o $(CURDIR)/$(@D) \ --buck-compilation-database no-deps \ - -- $(BUCK) build --no-cache '//clang_compilation_database:Hel lo#x86_64') + -- $(BUCK) build --no-cache '//clang_compilation_database:Hel lo#x86_64' @clang_compilation_database/buck_target_hello_test.txt) diff --git a/infer/tests/build_systems/buck-clang-db/issues.exp b/infer/tests/build_systems/buck-clang-db/issues.exp index 8bc94e6ac..edd471525 100644 --- a/infer/tests/build_systems/buck-clang-db/issues.exp +++ b/infer/tests/build_systems/buck-clang-db/issues.exp @@ -1,4 +1,5 @@ clang_compilation_database/hello.cpp, test0, 2, NULL_DEREFERENCE, [start of procedure test0()] clang_compilation_database/hello.cpp, test1, 2, NULL_DEREFERENCE, [start of procedure test1(),start of procedure deref1()] clang_compilation_database/hello.cpp, test2, 2, NULL_DEREFERENCE, [start of procedure test2(),start of procedure deref2()] +clang_compilation_database/hello_test.c, hello_test, 2, NULL_DEREFERENCE, [start of procedure hello_test()] clang_compilation_database/lib3.h, test, 1, NULL_DEREFERENCE, [start of procedure test(),start of procedure deref3()] diff --git a/infer/tests/build_systems/buck_flavors/Makefile b/infer/tests/build_systems/buck_flavors/Makefile index 1927a7575..416adc885 100644 --- a/infer/tests/build_systems/buck_flavors/Makefile +++ b/infer/tests/build_systems/buck_flavors/Makefile @@ -9,7 +9,7 @@ TESTS_DIR = ../.. ROOT_DIR = $(TESTS_DIR)/../.. ANALYZER = infer -BUCK_TARGET = //src:hello +BUCK_TARGET = //src:hello @buck_target.txt SOURCES = $(wildcard src/hello.c) OBJECTS = buck-out/gen/src/hello\#compile-hello.c.o1f717d69,default/hello.c.o INFER_OPTIONS = --report-custom-error --developer-mode --project-root $(TESTS_DIR) --no-keep-going diff --git a/infer/tests/build_systems/buck_flavors/buck_target.txt b/infer/tests/build_systems/buck_flavors/buck_target.txt new file mode 100644 index 000000000..ce6b87f8e --- /dev/null +++ b/infer/tests/build_systems/buck_flavors/buck_target.txt @@ -0,0 +1 @@ +//src:hello3 diff --git a/infer/tests/build_systems/buck_flavors/issues.exp b/infer/tests/build_systems/buck_flavors/issues.exp index 5b0c5bc28..29a2fd6a6 100644 --- a/infer/tests/build_systems/buck_flavors/issues.exp +++ b/infer/tests/build_systems/buck_flavors/issues.exp @@ -1,2 +1,3 @@ src/hello.c, test, 2, NULL_DEREFERENCE, [start of procedure test()] src/hello2.c, test2, 2, NULL_DEREFERENCE, [start of procedure test2()] +src/hello3.c, test3, 2, NULL_DEREFERENCE, [start of procedure test3()] diff --git a/infer/tests/build_systems/buck_flavors/src/BUCK b/infer/tests/build_systems/buck_flavors/src/BUCK index ee8db4c9a..3c6ddad73 100644 --- a/infer/tests/build_systems/buck_flavors/src/BUCK +++ b/infer/tests/build_systems/buck_flavors/src/BUCK @@ -4,3 +4,10 @@ cxx_library( 'hello.c', 'hello2.c', ], ) + +cxx_library( + name = 'hello3', + srcs = [ + 'hello3.c', + ], +) diff --git a/infer/tests/build_systems/buck_flavors/src/hello3.c b/infer/tests/build_systems/buck_flavors/src/hello3.c new file mode 100644 index 000000000..a2441062a --- /dev/null +++ b/infer/tests/build_systems/buck_flavors/src/hello3.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#include + +void test3() { + int* s = NULL; + *s = 42; +} diff --git a/infer/tests/build_systems/codetoanalyze/clang_compilation_database/BUCK b/infer/tests/build_systems/codetoanalyze/clang_compilation_database/BUCK index 3efe60d30..4ea9406f0 100644 --- a/infer/tests/build_systems/codetoanalyze/clang_compilation_database/BUCK +++ b/infer/tests/build_systems/codetoanalyze/clang_compilation_database/BUCK @@ -7,3 +7,10 @@ cxx_library( '-std=c++11', ], ) + +cxx_library( + name = 'hello_test', + srcs = [ + 'hello_test.c', + ], +) diff --git a/infer/tests/build_systems/codetoanalyze/clang_compilation_database/buck_target_hello_test.txt b/infer/tests/build_systems/codetoanalyze/clang_compilation_database/buck_target_hello_test.txt new file mode 100644 index 000000000..954069fad --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/clang_compilation_database/buck_target_hello_test.txt @@ -0,0 +1 @@ +//clang_compilation_database:hello_test diff --git a/infer/tests/build_systems/codetoanalyze/clang_compilation_database/hello_test.c b/infer/tests/build_systems/codetoanalyze/clang_compilation_database/hello_test.c new file mode 100644 index 000000000..2b53c7444 --- /dev/null +++ b/infer/tests/build_systems/codetoanalyze/clang_compilation_database/hello_test.c @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2015 - 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. + */ + +#include + +void hello_test() { + int* s = NULL; + *s = 42; +}