| |
| # Temporarily disable tautological-*-compare chromium:778316. |
| # Temporarily add no-unknown-warning-option to deal with old clang versions. |
| FLAGS_TO_ADD = set(( |
| '-Wno-unused-local-typedefs', |
| '-Wno-deprecated-declarations', |
| '-Wno-tautological-constant-compare', |
| '-Wno-tautological-unsigned-enum-zero-compare', |
| '-Wno-unknown-warning-option', |
| )) |
| |
| |
| def exec_and_bisect(execargs, bisect_stage, argv0): |
| """Execute compiler, return and invoke bisection driver.""" |
| import bisect_driver |
| |
| bisect_dir = os.environ.get('BISECT_DIR', '/tmp/sysroot_bisect') |
| try: |
| ret = bisect_driver.bisect_driver(bisect_stage, bisect_dir, execargs) |
| except OSError as e: |
| handle_exec_exception(e, argv0, execargs) |
| |
| sys.exit(ret) |
| |
| |
| def main(argv): |
| """Main function for clang wrapper script.""" |
| |
| # Only FORTIFY_SOURCE hardening flag is applicable for clang. |
| clang_flags = [ |
| '-Qunused-arguments', |
| '-grecord-gcc-switches', |
| ] |
| |
| use_clang_tidy = os.environ.get('WITH_TIDY') |
| if use_clang_tidy: |
| c_src_file = find_source_file(argv) |
| if not c_src_file: |
| use_clang_tidy = False |
| else: |
| c_src_file = '' |
| |
| myargs = argv[1:] |
| |
| bisect_stage = os.environ.get('BISECT_STAGE') |
| |
| print_cmdline = '-print-cmdline' in myargs |
| |
| # Filter unsupported linker flags if sanitizers are used. |
| filter_unsupported_asan_flags = has_sanitizer_flags(myargs) |
| |
| clang_cmdline = clang_flags + list(FLAGS_TO_ADD) |
| clang_flags = list(FLAGS_TO_ADD) |
| |
| cmdline = [x for x in myargs if x not in WRAPPER_ONLY_OPTIONS] |
| |
| if filter_unsupported_asan_flags: |
| cmdline = [x for x in cmdline if x not in LINKER_UNSUPPORTED_ASAN_FLAGS] |
| |
| prog_base = os.path.basename(sys.argv[0]) |
| if prog_base.startswith('x86_64') or startswith_i86(prog_base): |
| cmdline.extend(X86_DISABLE_FLAGS) |
| |
| sysroot = os.environ.get('SYSROOT', '/') |
| |
| # Get the clang binary location relative to the wrapper. |
| clang_bin = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'clang') |
| |
| for flag in cmdline: |
| if not (flag in CLANG_UNSUPPORTED or |
| flag.startswith(CLANG_UNSUPPORTED_PREFIXES)): |
| # Strip off -Xclang-only= if present. |
| if flag.startswith('-Xclang-only='): |
| opt = flag.partition('=')[2] |
| clang_cmdline.append(opt) |
| elif flag.startswith('-Xclang-path='): |
| import subprocess |
| # Use clang installed at the given path. But use the resource directory |
| # for the main clang since the custom clang installation won't have |
| # the cross-target libraries. |
| resource_path = subprocess.check_output([clang_bin, |
| '--print-resource-dir']) |
| clang_cmdline.append('-resource-dir=%s' % resource_path.strip()) |
| clang_cmdline.append('--gcc-toolchain=/usr') |
| clang_path = flag.partition('=')[2] |
| clang_bin = os.path.join(clang_path, 'clang') |
| elif flag in GCC_TO_CLANG.keys(): |
| clang_cmdline.append(GCC_TO_CLANG[flag]) |
| elif not flag in CLANG_ARM_OPTIONS_TO_BE_DISCARDED: |
| clang_cmdline.append(flag) |
| |
| clang_tidy_bin = clang_bin + '-tidy' |
| clang_comp = os.environ.get('CLANG', clang_bin) |
| |
| # Check for clang or clang++. |
| if sys.argv[0].endswith('++'): |
| clang_comp += '++' |
| |
| execargs = [] |
| argv0 = clang_comp |
| execargs += [clang_comp] + clang_cmdline |
| |
| if use_clang_tidy: |
| import subprocess |
| tidy_execargs = [] |
| default_tidy_checks = ('-checks=*,google*,-google-build-using-namespace,' |
| '-google-default-arguments,-readability-*,' |
| '-cppcoreguidelines-*,-modernize-*,' |
| '-google-explicit-constructor,-google-readability*,' |
| '-google-runtime-int,-google-runtime-references') |
| tidy_args = [default_tidy_checks] |
| resource_path = subprocess.check_output([clang_comp, |
| '--print-resource-dir']) |
| resource_dir_arg = ['-resource-dir=%s' % resource_path.strip()] |
| tidy_execargs += [clang_tidy_bin] + tidy_args + [c_src_file] + ['--'] \ |
| + resource_dir_arg + clang_cmdline |
| |
| if print_cmdline: |
| print("Calling clang-tidy:") |
| print(repr(tidy_execargs)) |
| |
| retval = subprocess.call(tidy_execargs) |
| if retval != 0 and print_cmdline: |
| print("Call to clang-tidy failed!") |
| |
| if print_cmdline: |
| print('[%s] %s' % (argv0, ' '.join(execargs))) |
| |
| sys.stdout.flush() |
| |
| if not bisect_stage: |
| try: |
| os.execv(argv0, execargs) |
| except OSError as e: |
| handle_exec_exception(e, argv0, False, execargs) |
| |
| # Only comes here if doing bisection. |
| exec_and_bisect(execargs, bisect_stage, argv0) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv)) |