| |
| # 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', |
| '-fno-addrsig', |
| '-fuse-ld=lld', |
| ] |
| |
| 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(LLVM_NEXT_FLAGS_TO_ADD) + 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 UNSUPPORTED_ASAN_FLAGS] |
| clang_cmdline = [x for x in clang_cmdline if x not in UNSUPPORTED_ASAN_FLAGS] |
| |
| # Add flags for fuzzer. |
| if has_fuzzer_flags(myargs): |
| clang_cmdline.extend(FUZZER_FLAGS_TO_ADD) |
| |
| 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 = ','.join([ |
| '*', |
| 'google*', |
| '-bugprone-narrowing-conversions', |
| '-cppcoreguidelines-*', |
| '-fuchsia-*', |
| '-google-build-using-namespace', |
| '-google-default-arguments', |
| '-google-explicit-constructor', |
| '-google-readability*', |
| '-google-runtime-int', |
| '-google-runtime-references', |
| '-hicpp-avoid-c-arrays', |
| '-hicpp-braces-around-statements', |
| '-hicpp-no-array-decay', |
| '-hicpp-signed-bitwise', |
| '-hicpp-uppercase-literal-suffix', |
| '-hicpp-use-auto', |
| '-llvm-namespace-comment', |
| '-misc-non-private-member-variables-in-classes', |
| '-misc-unused-parameters', |
| '-modernize-*', |
| '-readability-*', |
| ]) |
| tidy_args = ['-checks=' + 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() |
| |
| # We'll sometimes pull in a new compiler (or similar) and want a good way of |
| # vetting it. New warnings are useful, but actively block the potentially more |
| # interesting things (actually building the world, testing, etc). This is our |
| # escape hatch. |
| if os.getenv('FORCE_DISABLE_WERROR'): |
| sys.exit(double_build_with_wno_error(execargs)) |
| |
| 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)) |