[xcodebuild] replace python integration with ocaml

Reviewed By: ngorogiannis

Differential Revision: D20416859

fbshipit-source-id: abac2c6b4
master
Martin Trojer 5 years ago committed by Facebook GitHub Bot
parent 3ceb2efe9e
commit baaf81b554

@ -1,78 +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 = __name__
MODULE_DESCRIPTION = '''Run analysis of code built with a command like:
xcodebuild [options]
Analysis examples:
infer -- xcodebuild -target HelloWorldApp -sdk iphonesimulator
infer -- xcodebuild -workspace HelloWorld.xcworkspace -scheme HelloWorld'''
LANG = ['clang']
CLANG_WRAPPER = os.path.join(config.WRAPPERS_DIRECTORY, 'clang')
CLANGPLUSPLUS_WRAPPER = os.path.join(config.WRAPPERS_DIRECTORY, 'clang++')
def gen_instance(*args):
return XcodebuildCapture(*args)
create_argparser = util.base_argparser(MODULE_DESCRIPTION, MODULE_NAME)
class XcodebuildCapture:
def __init__(self, args, cmd):
self.args = args
self.apple_clang_path = \
subprocess.check_output(['xcrun', '--find', 'clang']).strip()
xcode_version = util.run_cmd_ignore_fail(['xcodebuild', '-version'])
apple_clang_version = util.run_cmd_ignore_fail([self.apple_clang_path,
'--version'])
logging.info('Xcode version:\n%s', xcode_version)
logging.info('clang version:\n%s', apple_clang_version)
self.cmd = cmd
def get_envvars(self):
env_vars = utils.read_env()
infer_args = env_vars['INFER_ARGS']
if infer_args != '':
infer_args += '^' # '^' must be CommandLineOption.env_var_sep
infer_args += '--fcp-apple-clang^' + self.apple_clang_path
env_vars['INFER_ARGS'] = infer_args
return env_vars
def capture(self):
# these settings will instruct xcodebuild on which clang to use
self.cmd += ['CC={wrapper}'.format(wrapper=CLANG_WRAPPER)]
self.cmd += [
'CPLUSPLUS={wrapper}'.format(wrapper=CLANGPLUSPLUS_WRAPPER)]
# skip the ProcessPCH phase to fix the "newer/older" incompatibility
# error for the pch files generated by apple's clang and
# the open-source one
self.cmd += ['GCC_PRECOMPILE_PREFIX_HEADER=NO']
try:
env = utils.encode_env(self.get_envvars())
cmd = map(utils.encode, self.cmd)
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

@ -35,6 +35,23 @@ let create_process_and_wait ~prog ~args =
(Unix.Exit_or_signal.to_string_hum status)
let create_process_and_wait_with_output ~prog ~args =
let {Unix.Process_info.stdin; stdout; stderr; pid} = Unix.create_process ~prog ~args in
let stderr_chan = Unix.in_channel_of_descr stderr in
let stdout_chan = Unix.in_channel_of_descr stdout in
Unix.close stdin ;
match Unix.waitpid pid with
| Ok () ->
let out = In_channel.input_all stdout_chan in
let err = In_channel.input_all stderr_chan in
In_channel.close stdout_chan ; In_channel.close stderr_chan ; (out, err)
| Error _ as status ->
L.(die ExternalError)
"Error executing: %s@\n%s@\n"
(String.concat ~sep:" " (prog :: args))
(Unix.Exit_or_signal.to_string_hum status)
let pipeline ~producer_prog ~producer_args ~consumer_prog ~consumer_args =
let pipe_in, pipe_out = Unix.pipe () in
match Unix.fork () with

@ -12,6 +12,11 @@ val create_process_and_wait : prog:string -> args:string list -> unit
execution. The standard out and error are not redirected. If the commands fails to execute,
prints an error message and exits. *)
val create_process_and_wait_with_output : prog:string -> args:string list -> string * string
(** Given an command to be executed, creates a process to execute this command, and waits for its
execution. The standard out and error are returned. If the commands fails to execute, prints an
error message and exits. *)
val print_error_and_exit : ?exit_code:int -> ('a, Format.formatter, unit, 'b) format4 -> 'a
(** Prints an error message to a log file, prints a message saying that the error can be found in
that file, and exist, with default code 1 or a given code. *)

@ -26,6 +26,7 @@ type mode =
| Maven of string * string list
| NdkBuild of string list
| PythonCapture of Config.build_system * string list
| XcodeBuild of string * string list
| XcodeXcpretty of string * string list
let is_analyze_mode = function Analyze -> true | _ -> false
@ -48,6 +49,8 @@ let pp_mode fmt = function
F.fprintf fmt "PythonCapture driver mode:@\nbuild system = '%s'@\nargs = %a"
(Config.string_of_build_system bs)
Pp.cli_args args
| XcodeBuild (prog, args) ->
F.fprintf fmt "XcodeBuild driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args
| XcodeXcpretty (prog, args) ->
F.fprintf fmt "XcodeXcpretty driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args
| Javac (_, prog, args) ->
@ -290,9 +293,13 @@ let capture ~changed_files = function
L.progress "Capturing in maven mode...@." ;
Maven.capture ~prog ~args
| NdkBuild build_cmd ->
L.progress "Capturing in ndk-build mode...@." ;
NdkBuild.capture ~build_cmd
| PythonCapture (build_system, build_cmd) ->
python_capture build_system build_cmd
| XcodeBuild (prog, args) ->
L.progress "Capturing in xcodebuild mode...@." ;
XcodeBuild.capture ~prog ~args
| XcodeXcpretty (prog, args) ->
L.progress "Capturing using xcodebuild and xcpretty...@." ;
check_xcpretty () ;
@ -534,11 +541,13 @@ let mode_of_build_command build_cmd (buck_mode : BuckMode.t option) =
Maven (prog, args)
| BXcode, _ when Config.xcpretty ->
XcodeXcpretty (prog, args)
| BXcode, _ ->
XcodeBuild (prog, args)
| BBuck, Some ClangFlavors ->
BuckClangFlavor build_cmd
| BNdk, _ ->
NdkBuild build_cmd
| ((BAnt | BGradle | BXcode) as build_system), _ ->
| ((BAnt | BGradle) as build_system), _ ->
PythonCapture (build_system, build_cmd) )

@ -23,6 +23,7 @@ type mode =
| Maven of string * string list
| NdkBuild of string list
| PythonCapture of Config.build_system * string list
| XcodeBuild of string * string list
| XcodeXcpretty of string * string list
val is_analyze_mode : mode -> bool

@ -0,0 +1,50 @@
(*
* 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 ~prog ~args =
let apple_clang =
Process.create_process_and_wait_with_output ~prog:"xcrun" ~args:["--find"; "clang"]
|> fst |> String.strip
in
let xcode_version, _ =
Process.create_process_and_wait_with_output ~prog:"xcodebuild" ~args:["-version"]
in
let apple_clang_version, _ =
Process.create_process_and_wait_with_output ~prog:apple_clang ~args:["--version"]
in
L.environment_info "Xcode version: %s@." xcode_version ;
L.environment_info "clang version: %s@." apple_clang_version ;
let args =
List.append args
[ Printf.sprintf "CC=%s" Config.wrappers_dir ^/ "clang"
; Printf.sprintf "CPLUSPLUS=%s" Config.wrappers_dir ^/ "clang++"
; "GCC_PRECOMPILE_PREFIX_HEADER=NO" ]
in
let infer_args =
Option.fold (Sys.getenv CommandLineOption.args_env_var)
~init:(Printf.sprintf "%s%c%s" "--fcp-apple-clang" CommandLineOption.env_var_sep apple_clang)
~f:(fun acc arg -> Printf.sprintf "%s%c%s" acc CommandLineOption.env_var_sep arg)
in
L.debug Capture Verbose "%s [%s] [%s]@." prog (String.concat ~sep:"," args) infer_args ;
let {Unix.Process_info.stdin; stdout; stderr; pid} =
Unix.create_process_env ~prog ~args
~env:(`Extend [(CommandLineOption.args_env_var, infer_args)])
()
in
let stdout_chan = Unix.in_channel_of_descr stdout in
let stderr_chan = Unix.in_channel_of_descr stderr in
Unix.close stdin ;
Utils.with_channel_in stdout_chan ~f:(L.progress "XCODEBUILD: %s@.") ;
Utils.with_channel_in stderr_chan ~f:(L.progress "XCODEBUILD: %s@.") ;
match Unix.waitpid pid with
| Ok () ->
In_channel.close stdout_chan ; In_channel.close stderr_chan
| Error _ as err ->
L.die ExternalError "*** capture failed to execute: %s"
(Unix.Exit_or_signal.to_string_hum err)

@ -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 : prog:string -> args:string list -> unit
Loading…
Cancel
Save