blob: 72e9338b27d6c9761a09e50012e5f061b1e55a53 [file] [log] [blame]
# 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))