Reviewed By: ngorogiannis Differential Revision: D20416859 fbshipit-source-id: abac2c6b4master
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
|
@ -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…
Reference in new issue