diff --git a/infer/lib/python/inferlib/capture/ndk-build.py b/infer/lib/python/inferlib/capture/ndk-build.py deleted file mode 100644 index df3be9f4d..000000000 --- a/infer/lib/python/inferlib/capture/ndk-build.py +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This source code is licensed under the MIT license found in the -# LICENSE file in the root directory of this source tree. - -import logging -import os -import subprocess -import traceback - -import util -from inferlib import config, utils - -MODULE_NAME = 'ndk-build/clang' -MODULE_DESCRIPTION = '''Run analysis of code built with ndk-build - - Analysis examples: - infer -- ndk-build''' -LANG = ['clang'] - -ALIASED_COMMANDS = ['clang', 'clang++', 'cc', 'gcc', 'g++'] - -def gen_instance(*args): - return NdkBuildCapture(*args) - - -create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME) - - -class NdkBuildCapture(): - def __init__(self, args, cmd): - cmd = [ - cmd[0], - 'NDK_TOOLCHAIN_VERSION=clang', - 'TARGET_CC=clang', - 'TARGET_CXX=clang', - 'TARGET_LD=ld', - ] + cmd[1:] - self.args = args - self.cmd = cmd - command_name = os.path.basename(cmd[0]) - if command_name in ALIASED_COMMANDS: - # remove absolute paths for these commands as we want to - # substitue our own wrappers instead using a PATH trick - cmd[0] = command_name - - def get_envvars(self): - env_vars = utils.read_env() - wrappers_path = config.WRAPPERS_DIRECTORY - # INFER_RESULTS_DIR and INFER_OLD_PATH are used by javac wrapper only - env_vars['INFER_OLD_PATH'] = env_vars['PATH'] - env_vars['PATH'] = '{wrappers}{sep}{path}'.format( - wrappers=wrappers_path, - sep=os.pathsep, - path=env_vars['PATH'], - ) - env_vars['INFER_RESULTS_DIR'] = self.args.infer_out - return env_vars - - def capture(self): - try: - env = utils.encode_env(self.get_envvars()) - cmd = map(utils.encode, self.cmd) - logging.info('Running command %s with env:\n%s' % (cmd, env)) - subprocess.check_call(cmd, env=env) - return os.EX_OK - except subprocess.CalledProcessError as exc: - if self.args.debug: - traceback.print_exc() - return exc.returncode diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 9164388e4..17e31a83e 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -59,6 +59,8 @@ val buck_infer_deps_file_name : string val captured_dir_name : string +val clang_exe_aliases : string list + val clang_initializer_prefix : string val clang_inner_destructor_prefix : string diff --git a/infer/src/integration/Driver.ml b/infer/src/integration/Driver.ml index 296e16173..5733bfafb 100644 --- a/infer/src/integration/Driver.ml +++ b/infer/src/integration/Driver.ml @@ -17,13 +17,14 @@ module F = Format type mode = | Analyze | BuckClangFlavor of string list + | BuckCompilationDB of BuckMode.clang_compilation_db_deps * string * string list | BuckGenrule of string | BuckGenruleMaster of string list - | BuckCompilationDB of BuckMode.clang_compilation_db_deps * string * string list | 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 + | NdkBuild of string list | PythonCapture of Config.build_system * string list | XcodeXcpretty of string * string list @@ -53,6 +54,8 @@ let pp_mode fmt = function F.fprintf fmt "Javac driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args | Maven (prog, args) -> F.fprintf fmt "Maven driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args + | NdkBuild args -> + F.fprintf fmt "NdkBuild driver mode: args = %a" Pp.cli_args args | Clang (_, prog, args) -> F.fprintf fmt "Clang driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args @@ -295,6 +298,8 @@ let capture ~changed_files = function | Maven (prog, args) -> L.progress "Capturing in maven mode...@." ; Maven.capture ~prog ~args + | NdkBuild build_cmd -> + NdkBuild.capture ~build_cmd | PythonCapture (build_system, build_cmd) -> python_capture build_system build_cmd | XcodeXcpretty (prog, args) -> @@ -545,7 +550,9 @@ let mode_of_build_command build_cmd (buck_mode : BuckMode.t option) = XcodeXcpretty (prog, args) | BBuck, Some ClangFlavors -> BuckClangFlavor build_cmd - | ((BAnt | BGradle | BNdk | BXcode) as build_system), _ -> + | BNdk, _ -> + NdkBuild build_cmd + | ((BAnt | BGradle | BXcode) as build_system), _ -> PythonCapture (build_system, build_cmd) ) diff --git a/infer/src/integration/Driver.mli b/infer/src/integration/Driver.mli index 5527f158f..ef9319bcd 100644 --- a/infer/src/integration/Driver.mli +++ b/infer/src/integration/Driver.mli @@ -14,13 +14,14 @@ open! IStd type mode = | Analyze | BuckClangFlavor of string list + | BuckCompilationDB of BuckMode.clang_compilation_db_deps * string * string list | BuckGenrule of string | BuckGenruleMaster of string list - | BuckCompilationDB of BuckMode.clang_compilation_db_deps * string * string list | 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 + | NdkBuild of string list | PythonCapture of Config.build_system * string list | XcodeXcpretty of string * string list diff --git a/infer/src/integration/NdkBuild.ml b/infer/src/integration/NdkBuild.ml new file mode 100644 index 000000000..ae491f2e6 --- /dev/null +++ b/infer/src/integration/NdkBuild.ml @@ -0,0 +1,47 @@ +(* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) +open! IStd +module L = Logging + +let capture ~build_cmd = + let raw_prog, ndk_args = (List.hd_exn build_cmd, List.tl_exn build_cmd) in + (* env vars *) + let path_opt = Sys.getenv "PATH" in + let new_env = + [ ("INFER_OLD_PATH", Option.value path_opt ~default:"") + ; ("PATH", Option.fold path_opt ~init:Config.wrappers_dir ~f:(Printf.sprintf "%s:%s")) + ; ("INFER_RESULTS_DIR", Config.results_dir) ] + in + (* args *) + let raw_prog_name = Filename.basename raw_prog in + let prog = + if List.exists Config.clang_exe_aliases ~f:(String.equal raw_prog_name) then raw_prog_name + else raw_prog + in + let args = + "NDK_TOOLCHAIN_VERSION=clang" :: "TARGET_CC=clang" :: "TARGET_CXX=clang" :: "TARGET_LD=ld" + :: ndk_args + in + (* run ndk_build *) + L.(debug Capture Verbose) + "Running command %s %s with env %s@." prog (String.concat ~sep:" " args) + (List.to_string ~f:(fun (a, b) -> a ^ "=" ^ b) new_env) ; + let {Unix.Process_info.stdin; stdout; stderr; pid} = + Unix.create_process_env ~prog ~args ~env:(`Extend new_env) () + in + let ndk_stderr = Unix.in_channel_of_descr stderr in + Utils.with_channel_in ndk_stderr ~f:(L.progress "NDKBUILD: %s@.") ; + Unix.close stdin ; + Unix.close stdout ; + In_channel.close ndk_stderr ; + match Unix.waitpid pid with + | Ok () -> + () + | Error _ as err -> + L.die ExternalError "ndkbuild capture failed to execute: %s" + (Unix.Exit_or_signal.to_string_hum err) + () diff --git a/infer/src/integration/NdkBuild.mli b/infer/src/integration/NdkBuild.mli new file mode 100644 index 000000000..53d5d6b97 --- /dev/null +++ b/infer/src/integration/NdkBuild.mli @@ -0,0 +1,10 @@ +(* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + *) + +open! IStd + +val capture : build_cmd:string list -> unit