1#!/usr/bin/env python3 2# Copyright 2021 The Chromium Authors 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import argparse 7 8from util import build_utils 9from util import diff_utils 10 11IGNORE_FLAG_PREFIXES = [ 12 # For cflags. 13 '-DANDROID_NDK_VERSION_ROLL', 14 '-DCR_LIBCXX_REVISION', 15 '-I', 16 '-g', 17 '-fcrash-diagnostics-dir=', 18 '-fprofile', 19 '--no-system-header-prefix', 20 '--system-header-prefix', 21 '-isystem', 22 '-iquote', 23 '-fmodule-map', 24 '-frandom-seed', 25 '-c ', 26 '-o ', 27 '-fmodule-name=', 28 '--sysroot=', 29 '-fcolor-diagnostics', 30 '-MF ', 31 '-MD', 32 33 # For ldflags. 34 '-Wl,--thinlto-cache-dir', 35 '-Wl,--thinlto-cache-policy', 36 '-Wl,--thinlto-jobs', 37 '-Wl,--start-lib', 38 '-Wl,--end-lib', 39 '-Wl,-whole-archive', 40 '-Wl,-no-whole-archive', 41 '-l', 42 '-L', 43 '-Wl,-soname', 44 '-Wl,-version-script', 45 '-Wl,--version-script', 46 '-fdiagnostics-color', 47 '-Wl,--color-diagnostics', 48 '-B', 49 '-Wl,--dynamic-linker', 50 '-DCR_CLANG_REVISION=', 51] 52 53FLAGS_WITH_PARAMS = ( 54 '-Xclang', 55 '-mllvm', 56 '-Xclang -fdebug-compilation-dir', 57 '-Xclang -add-plugin', 58) 59 60 61def KeepFlag(flag): 62 return not any(flag.startswith(prefix) for prefix in IGNORE_FLAG_PREFIXES) 63 64 65def MergeFlags(flags): 66 flags = _MergeFlagsHelper(flags) 67 # For double params eg: -Xclang -fdebug-compilation-dir 68 flags = _MergeFlagsHelper(flags) 69 return flags 70 71 72def _MergeFlagsHelper(flags): 73 merged_flags = [] 74 while flags: 75 current_flag = flags.pop(0) 76 if flags: 77 next_flag = flags[0] 78 else: 79 next_flag = None 80 merge_flags = False 81 82 # Special case some flags that always come with params. 83 if current_flag in FLAGS_WITH_PARAMS: 84 merge_flags = True 85 # Assume flags without '-' are a param. 86 if next_flag and not next_flag.startswith('-'): 87 merge_flags = True 88 # Special case -plugin-arg prefix because it has the plugin name. 89 if current_flag.startswith('-Xclang -plugin-arg'): 90 merge_flags = True 91 if merge_flags: 92 merged_flag = '{} {}'.format(current_flag, next_flag) 93 merged_flags.append(merged_flag) 94 flags.pop(0) 95 else: 96 merged_flags.append(current_flag) 97 return merged_flags 98 99 100def ParseFlags(flag_file_path): 101 flags = [] 102 with open(flag_file_path) as f: 103 for flag in f.read().splitlines(): 104 if KeepFlag(flag): 105 flags.append(flag) 106 return flags 107 108 109def main(): 110 """Compare the flags with the checked in list.""" 111 parser = argparse.ArgumentParser() 112 diff_utils.AddCommandLineFlags(parser) 113 parser.add_argument('--current-flags', 114 help='Path to flags to check against expectations.') 115 options = parser.parse_args() 116 117 flags = ParseFlags(options.current_flags) 118 flags = MergeFlags(flags) 119 120 msg = """ 121This expectation file is meant to inform the build team about changes to 122flags used when building native libraries in chrome (most importantly any 123that relate to security). This is to ensure the flags are replicated when 124building native libraries outside of the repo. Please update the .expected 125files and a WATCHLIST entry will alert the build team to your change.""" 126 diff_utils.CheckExpectations('\n'.join(sorted(flags)), 127 options, 128 custom_msg=msg) 129 130 131if __name__ == '__main__': 132 main() 133