Richard He | 6663ed0 | 2020-07-27 18:55:50 | [diff] [blame] | 1 | #!/usr/bin/env vpython3 |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 2 | # Copyright 2020 The Chromium Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | |
| 6 | # Lint as: python3 |
| 7 | """Prints out available java targets. |
| 8 | |
| 9 | Examples: |
| 10 | # List GN target for bundles: |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 11 | build/android/list_java_targets.py -C out/Default --type android_app_bundle \ |
| 12 | --gn-labels |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 13 | |
| 14 | # List all android targets with types: |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 15 | build/android/list_java_targets.py -C out/Default --print-types |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 16 | |
| 17 | # Build all apk targets: |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 18 | build/android/list_java_targets.py -C out/Default --type android_apk | xargs \ |
| 19 | autoninja -C out/Default |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 20 | |
| 21 | # Show how many of each target type exist: |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 22 | build/android/list_java_targets.py -C out/Default --stats |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 23 | |
| 24 | """ |
| 25 | |
| 26 | import argparse |
| 27 | import collections |
| 28 | import json |
| 29 | import logging |
| 30 | import os |
| 31 | import subprocess |
| 32 | import sys |
| 33 | |
| 34 | _SRC_ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', |
| 35 | '..')) |
| 36 | sys.path.append(os.path.join(_SRC_ROOT, 'build', 'android')) |
| 37 | from pylib import constants |
| 38 | |
| 39 | _VALID_TYPES = ( |
| 40 | 'android_apk', |
| 41 | 'android_app_bundle', |
| 42 | 'android_app_bundle_module', |
| 43 | 'android_assets', |
| 44 | 'android_resources', |
| 45 | 'dist_aar', |
| 46 | 'dist_jar', |
| 47 | 'group', |
| 48 | 'java_annotation_processor', |
| 49 | 'java_binary', |
| 50 | 'java_library', |
| 51 | 'junit_binary', |
| 52 | 'system_java_library', |
| 53 | ) |
| 54 | |
| 55 | |
| 56 | def _run_ninja(output_dir, args): |
| 57 | cmd = [ |
| 58 | 'autoninja', |
| 59 | '-C', |
| 60 | output_dir, |
| 61 | ] |
| 62 | cmd.extend(args) |
| 63 | logging.info('Running: %r', cmd) |
| 64 | subprocess.run(cmd, check=True, stdout=sys.stderr) |
| 65 | |
| 66 | |
| 67 | def _query_for_build_config_targets(output_dir): |
| 68 | # Query ninja rather than GN since it's faster. |
| 69 | cmd = ['ninja', '-C', output_dir, '-t', 'targets'] |
| 70 | logging.info('Running: %r', cmd) |
| 71 | ninja_output = subprocess.run(cmd, |
| 72 | check=True, |
| 73 | capture_output=True, |
| 74 | encoding='ascii').stdout |
| 75 | ret = [] |
| 76 | SUFFIX = '__build_config_crbug_908819' |
| 77 | SUFFIX_LEN = len(SUFFIX) |
| 78 | for line in ninja_output.splitlines(): |
| 79 | ninja_target = line.rsplit(':', 1)[0] |
| 80 | # Ignore root aliases by ensuring a : exists. |
| 81 | if ':' in ninja_target and ninja_target.endswith(SUFFIX): |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 82 | ret.append(f'//{ninja_target[:-SUFFIX_LEN]}') |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 83 | return ret |
| 84 | |
| 85 | |
| 86 | class _TargetEntry(object): |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 87 | def __init__(self, gn_target): |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 88 | assert gn_target.startswith('//'), f'{gn_target} does not start with //' |
| 89 | assert ':' in gn_target, f'Non-root {gn_target} required' |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 90 | self.gn_target = gn_target |
| 91 | self._build_config = None |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 92 | |
| 93 | @property |
| 94 | def ninja_target(self): |
| 95 | return self.gn_target[2:] |
| 96 | |
| 97 | @property |
| 98 | def ninja_build_config_target(self): |
| 99 | return self.ninja_target + '__build_config_crbug_908819' |
| 100 | |
Henrique Nakashima | 5f306229 | 2021-03-25 21:55:45 | [diff] [blame^] | 101 | @property |
| 102 | def build_config_path(self): |
| 103 | """Returns the filepath of the project's .build_config.""" |
| 104 | ninja_target = self.ninja_target |
| 105 | # Support targets at the root level. e.g. //:foo |
| 106 | if ninja_target[0] == ':': |
| 107 | ninja_target = ninja_target[1:] |
| 108 | subpath = ninja_target.replace(':', os.path.sep) + '.build_config' |
| 109 | return os.path.join(constants.GetOutDirectory(), 'gen', subpath) |
| 110 | |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 111 | def build_config(self): |
| 112 | """Reads and returns the project's .build_config JSON.""" |
| 113 | if not self._build_config: |
Henrique Nakashima | 5f306229 | 2021-03-25 21:55:45 | [diff] [blame^] | 114 | with open(self.build_config_path) as jsonfile: |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 115 | self._build_config = json.load(jsonfile) |
| 116 | return self._build_config |
| 117 | |
| 118 | def get_type(self): |
| 119 | """Returns the target type from its .build_config.""" |
| 120 | return self.build_config()['deps_info']['type'] |
| 121 | |
Andrew Grieve | c5e15d1b | 2020-12-04 18:13:02 | [diff] [blame] | 122 | def proguard_enabled(self): |
| 123 | """Returns whether proguard runs for this target.""" |
| 124 | # Modules set proguard_enabled, but the proguarding happens only once at the |
| 125 | # bundle level. |
| 126 | if self.get_type() == 'android_app_bundle_module': |
| 127 | return False |
| 128 | return self.build_config()['deps_info'].get('proguard_enabled', False) |
| 129 | |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 130 | |
| 131 | def main(): |
| 132 | parser = argparse.ArgumentParser( |
| 133 | description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 134 | parser.add_argument('-C', |
| 135 | '--output-directory', |
| 136 | help='If outdir is not provided, will attempt to guess.') |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 137 | parser.add_argument('--gn-labels', |
| 138 | action='store_true', |
| 139 | help='Print GN labels rather than ninja targets') |
| 140 | parser.add_argument( |
| 141 | '--nested', |
| 142 | action='store_true', |
| 143 | help='Do not convert nested targets to their top-level equivalents. ' |
| 144 | 'E.g. Without this, foo_test__apk -> foo_test') |
| 145 | parser.add_argument('--print-types', |
| 146 | action='store_true', |
| 147 | help='Print type of each target') |
Henrique Nakashima | 5f306229 | 2021-03-25 21:55:45 | [diff] [blame^] | 148 | parser.add_argument('--print-build-config-paths', |
| 149 | action='store_true', |
| 150 | help='Print path to the .build_config of each target') |
Andrew Grieve | c5e15d1b | 2020-12-04 18:13:02 | [diff] [blame] | 151 | parser.add_argument('--build', |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 152 | action='store_true', |
| 153 | help='Build all .build_config files.') |
| 154 | parser.add_argument('--type', |
| 155 | action='append', |
| 156 | help='Restrict to targets of given type', |
| 157 | choices=_VALID_TYPES) |
| 158 | parser.add_argument('--stats', |
| 159 | action='store_true', |
| 160 | help='Print counts of each target type.') |
Andrew Grieve | c5e15d1b | 2020-12-04 18:13:02 | [diff] [blame] | 161 | parser.add_argument('--proguard-enabled', |
| 162 | action='store_true', |
| 163 | help='Restrict to targets that have proguard enabled') |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 164 | parser.add_argument('-v', '--verbose', default=0, action='count') |
| 165 | args = parser.parse_args() |
| 166 | |
Andrew Grieve | c5e15d1b | 2020-12-04 18:13:02 | [diff] [blame] | 167 | args.build |= bool(args.type or args.proguard_enabled or args.print_types |
| 168 | or args.stats) |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 169 | |
| 170 | logging.basicConfig(level=logging.WARNING - (10 * args.verbose), |
| 171 | format='%(levelname).1s %(relativeCreated)6d %(message)s') |
| 172 | |
| 173 | if args.output_directory: |
| 174 | constants.SetOutputDirectory(args.output_directory) |
| 175 | constants.CheckOutputDirectory() |
| 176 | output_dir = constants.GetOutDirectory() |
| 177 | |
| 178 | # Query ninja for all __build_config_crbug_908819 targets. |
| 179 | targets = _query_for_build_config_targets(output_dir) |
| 180 | entries = [_TargetEntry(t) for t in targets] |
| 181 | |
Andrew Grieve | c5e15d1b | 2020-12-04 18:13:02 | [diff] [blame] | 182 | if args.build: |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 183 | logging.warning('Building %d .build_config files...', len(entries)) |
| 184 | _run_ninja(output_dir, [e.ninja_build_config_target for e in entries]) |
| 185 | |
| 186 | if args.type: |
| 187 | entries = [e for e in entries if e.get_type() in args.type] |
| 188 | |
Andrew Grieve | c5e15d1b | 2020-12-04 18:13:02 | [diff] [blame] | 189 | if args.proguard_enabled: |
| 190 | entries = [e for e in entries if e.proguard_enabled()] |
| 191 | |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 192 | if args.stats: |
| 193 | counts = collections.Counter(e.get_type() for e in entries) |
| 194 | for entry_type, count in sorted(counts.items()): |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 195 | print(f'{entry_type}: {count}') |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 196 | else: |
| 197 | for e in entries: |
| 198 | if args.gn_labels: |
| 199 | to_print = e.gn_target |
| 200 | else: |
| 201 | to_print = e.ninja_target |
| 202 | |
| 203 | # Convert to top-level target |
| 204 | if not args.nested: |
Andrew Grieve | c5e15d1b | 2020-12-04 18:13:02 | [diff] [blame] | 205 | to_print = to_print.replace('__test_apk', '').replace('__apk', '') |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 206 | |
| 207 | if args.print_types: |
Peter Wen | a57817c | 2020-07-27 17:47:52 | [diff] [blame] | 208 | to_print = f'{to_print}: {e.get_type()}' |
Henrique Nakashima | 5f306229 | 2021-03-25 21:55:45 | [diff] [blame^] | 209 | elif args.print_build_config_paths: |
| 210 | to_print = f'{to_print}: {e.build_config_path}' |
Andrew Grieve | e95e8e28 | 2020-07-14 01:27:13 | [diff] [blame] | 211 | |
| 212 | print(to_print) |
| 213 | |
| 214 | |
| 215 | if __name__ == '__main__': |
| 216 | main() |