From e8b91192d933152016ccf1bd0531d58d6cfa1d2b Mon Sep 17 00:00:00 2001 From: martinoluca Date: Thu, 18 Jun 2015 07:26:17 -0100 Subject: [PATCH] Add @import support for Xcode projects Summary: @public This is a workaround to a clang crash that happens whenever `-fmodules` and `YojsonASTExporter` are used together. This workaround, uses the `-plugin` argument instead of `-add-plugin` one for the clang frontend, and as a result of that, it overrides the default action of clang, which means no object files are emitted, but just the AST. To generate the missing data needed by the subsequent building phases of xcodebuild, we run Apple's clang. Test Plan: Compiled project containing Pods and `@import`, through a command of the form: infer -- xcodebuild -workspace project_name.xcworkspace -scheme project_name -sdk iphonesimulator --- infer/lib/capture/clang | 1 + infer/lib/capture/xcodebuild.py | 15 ++++++++------- infer/lib/clang/clang_general_wrapper | 18 +++++++++++++++++- infer/lib/clang/clang_wrapper | 2 +- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/infer/lib/capture/clang b/infer/lib/capture/clang index 7f8a0ba7b..675aba811 100755 --- a/infer/lib/capture/clang +++ b/infer/lib/capture/clang @@ -16,4 +16,5 @@ if [ -z $INFER_RESULTS_DIR ]; then exit $? fi + "${SCRIPT_PATH%/}/../clang/clang_general_wrapper$XX" "$@" diff --git a/infer/lib/capture/xcodebuild.py b/infer/lib/capture/xcodebuild.py index 4701f2b19..ce951cdd3 100644 --- a/infer/lib/capture/xcodebuild.py +++ b/infer/lib/capture/xcodebuild.py @@ -40,19 +40,20 @@ class XcodebuildCapture: # get the path to 'true' using xcrun true_path = subprocess.check_output(['xcrun', '--find', 'true']).strip() + apple_clang_path = \ + subprocess.check_output(['xcrun', '--find', 'clang']).strip() # these settings will instruct xcodebuild on which clang to use - # and to not run any linking - self.cmd += ['LD={true_path}'.format(true_path=true_path)] - self.cmd += ['LDPLUSPLUS={true_path}'.format(true_path=true_path)] self.cmd += ['CC={wrapper}'.format(wrapper=CLANG_WRAPPER)] self.cmd += ['CPLUSPLUS={wrapper}'.format(wrapper=CLANGPLUSPLUS_WRAPPER)] - self.cmd += ['LIPO={true_path}'.format(true_path=true_path)] - env_vars['INFER_RESULTS_DIR'] = self.args.infer_out + # 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'] - # fix the GenerateDSYMFile error - self.cmd += ["DEBUG_INFORMATION_FORMAT='dwarf'"] + env_vars['INFER_RESULTS_DIR'] = self.args.infer_out + env_vars['FCP_APPLE_CLANG'] = apple_clang_path try: subprocess.check_call(self.cmd, env=env_vars) diff --git a/infer/lib/clang/clang_general_wrapper b/infer/lib/clang/clang_general_wrapper index 64c9b73c9..b5445bdd8 100755 --- a/infer/lib/clang/clang_general_wrapper +++ b/infer/lib/clang/clang_general_wrapper @@ -35,6 +35,8 @@ INFER_FRONTEND_ARGS=($FCP_INFER_FRONTEND_ARGS) REPORT_FRONTEND_FAILURE="${FCP_REPORT_FRONTEND_FAILURE}" # enable debug mode (to get more data saved to disk for future inspections) DEBUG_MODE="${FCP_DEBUG_MODE}" +# specify where is located Apple's clang +APPLE_CLANG="${FCP_APPLE_CLANG}" if [ -z "$RESULTS_DIR" ]; then echo '$FCP_RESULTS_DIR with the name of the output directory not provided.' > /dev/stderr @@ -105,11 +107,20 @@ then if [ -n "$SOURCE_FILE" ] then + # (t7400979) this is a workaround to avoid that clang crashes when the -fmodules flag + # and the YojsonASTExporter plugin are used. Since the -plugin argument disables + # the generation of .o files, we invoke apple clang again to generate the expected + # artifacts. This will keep xcodebuild plus all the sub-steps happy. + if [ -n "$APPLE_CLANG" ]; then + ADD_PLUGIN_FLAG="-plugin" + else + ADD_PLUGIN_FLAG="-add-plugin" + fi ATTACH_PLUGIN="1" IFS=$'\n' EXTRA_ARGS=("-Xclang" "-load" "-Xclang" "${PLUGIN_PATH}" - "-Xclang" "-add-plugin" + "-Xclang" "$ADD_PLUGIN_FLAG" "-Xclang" "${PLUGIN_NAME}") if [ -n "$SYNTAX_ONLY" ]; then EXTRA_ARGS+=("-fsyntax-only") @@ -164,4 +175,9 @@ else STATUS=$? fi +# run apple clang if required (and if any) +if [ -n "$APPLE_CLANG" ]; then + "${APPLE_CLANG}$XX" "$@" || exit $? +fi + exit $STATUS diff --git a/infer/lib/clang/clang_wrapper b/infer/lib/clang/clang_wrapper index a57bc22aa..3c1467bef 100755 --- a/infer/lib/clang/clang_wrapper +++ b/infer/lib/clang/clang_wrapper @@ -15,7 +15,7 @@ COMMAND=("${CLANG_COMPILER}${XX}") # Remove command line options not supported by the opensource compiler or the plugins. for X in "$@" do - if [ "$X" != "-fapplication-extension" ] && [ "$X" != "-fmodules" ] + if [ "$X" != "-fapplication-extension" ] then COMMAND+=("$X") fi