def main(): argparser = argparse.ArgumentParser(description='Print APK size metrics.') argparser.add_argument('--min-pak-resource-size', type=int, default=20*1024, help='Minimum byte size of displayed pak resources.') argparser.add_argument('--chromium-output-directory', help='Location of the build artifacts.') argparser.add_argument('--chartjson', action='store_true', help='Sets output mode to chartjson.') argparser.add_argument('--output-dir', default='.', help='Directory to save chartjson to.') argparser.add_argument('--no-output-dir', action='store_true', help='Skip all measurements that rely on having ' 'output-dir') argparser.add_argument('--no-static-initializer-check', action='store_false', dest='static_initializer_check', default=True, help='Skip checking for static initializers') argparser.add_argument('-d', '--device', help='Dummy option for perf runner.') argparser.add_argument('--estimate-patch-size', action='store_true', help='Include patch size estimates. Useful for perf ' 'builders where a reference APK is available but adds ' '~3 mins to run time.') argparser.add_argument('--reference-apk-builder', default=apk_downloader.DEFAULT_BUILDER, help='Builder name to use for reference APK for patch ' 'size estimates.') argparser.add_argument('--reference-apk-bucket', default=apk_downloader.DEFAULT_BUCKET, help='Storage bucket holding reference APKs.') argparser.add_argument('apk', help='APK file path.') args = argparser.parse_args() chartjson = _BASE_CHART.copy() if args.chartjson else None if args.chromium_output_directory: constants.SetOutputDirectory(args.chromium_output_directory) if not args.no_output_dir: constants.CheckOutputDirectory() devil_chromium.Initialize() build_vars = _ReadBuildVars(constants.GetOutDirectory()) tools_prefix = os.path.join(constants.GetOutDirectory(), build_vars['android_tool_prefix']) else: tools_prefix = '' PrintApkAnalysis(args.apk, tools_prefix, chartjson=chartjson) _PrintDexAnalysis(args.apk, chartjson=chartjson) if args.estimate_patch_size: _PrintPatchSizeEstimate(args.apk, args.reference_apk_builder, args.reference_apk_bucket, chartjson=chartjson) if not args.no_output_dir: PrintPakAnalysis(args.apk, args.min_pak_resource_size) if args.static_initializer_check: _PrintStaticInitializersCountFromApk( args.apk, tools_prefix, chartjson=chartjson) if chartjson: results_path = os.path.join(args.output_dir, 'results-chart.json') logging.critical('Dumping json to %s', results_path) with open(results_path, 'w') as json_file: json.dump(chartjson, json_file)
def main(argv): parser = argparse.ArgumentParser( usage='Usage: %(prog)s [options] device_port ' 'host_port [device_port_2 host_port_2] ...', description=__doc__) parser.add_argument( '-v', '--verbose', dest='verbose_count', default=0, action='count', help='Verbose level (multiple times for more)') parser.add_argument( '--device', help='Serial number of device we should use.') parser.add_argument( '--blacklist-file', help='Device blacklist JSON file.') parser.add_argument( '--debug', action='store_const', const='Debug', dest='build_type', default='Release', help='DEPRECATED: use --output-directory instead.') parser.add_argument( '--output-directory', help='Path to the root build directory.') parser.add_argument( 'ports', nargs='+', type=int, help='Port pair to reverse forward.') args = parser.parse_args(argv) run_tests_helper.SetLogLevel(args.verbose_count) if len(args.ports) < 2 or len(args.ports) % 2: parser.error('Need even number of port pairs') port_pairs = zip(args.ports[::2], args.ports[1::2]) if args.build_type: constants.SetBuildType(args.build_type) if args.output_directory: constants.SetOutputDirectory(args.output_directory) devil_chromium.Initialize(output_directory=constants.GetOutDirectory()) blacklist = (device_blacklist.Blacklist(args.blacklist_file) if args.blacklist_file else None) device = device_utils.DeviceUtils.HealthyDevices( blacklist=blacklist, device_arg=args.device)[0] try: forwarder.Forwarder.Map(port_pairs, device) while True: time.sleep(60) except KeyboardInterrupt: sys.exit(0) finally: forwarder.Forwarder.UnmapAllDevicePorts(device)
def ProcessCommonOptions(args): """Processes and handles all common options.""" run_tests_helper.SetLogLevel(args.verbose_count) constants.SetBuildType(args.build_type) if args.build_directory: constants.SetBuildDirectory(args.build_directory) if args.output_directory: constants.SetOutputDirectory(args.output_directory) devil_custom_deps = None if args.adb_path: devil_custom_deps = { 'adb': { devil_env.GetPlatform(): [args.adb_path] } } devil_chromium.Initialize( output_directory=constants.GetOutDirectory(), custom_deps=devil_custom_deps) # Some things such as Forwarder require ADB to be in the environment path. adb_dir = os.path.dirname(constants.GetAdbPath()) if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep): os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH']
def main(): parser = argparse.ArgumentParser() parser.add_argument( 'json_path', help='The path to the generated incremental apk .json.') parser.add_argument('-d', '--device', dest='device', help='Target device for apk to install on.') parser.add_argument('--uninstall', action='store_true', default=False, help='Remove the app and all side-loaded files.') parser.add_argument('--output-directory', help='Path to the root build directory.') parser.add_argument('--no-threading', action='store_false', default=True, dest='threading', help='Do not install and push concurrently') parser.add_argument( '--no-cache', action='store_false', default=True, dest='cache', help='Do not use cached information about what files are ' 'currently on the target device.') parser.add_argument('-v', '--verbose', dest='verbose_count', default=0, action='count', help='Verbose level (multiple times for more)') args = parser.parse_args() run_tests_helper.SetLogLevel(args.verbose_count) if args.output_directory: constants.SetOutputDirectory(args.output_directory) devil_chromium.Initialize(output_directory=constants.GetOutDirectory()) # Retries are annoying when commands fail for legitimate reasons. Might want # to enable them if this is ever used on bots though. device = device_utils.DeviceUtils.HealthyDevices( device_arg=args.device, default_retries=0, enable_device_files_cache=True)[0] if args.uninstall: with open(args.json_path) as f: install_dict = json.load(f) apk = apk_helper.ToHelper(install_dict['apk_path']) Uninstall(device, apk.GetPackageName(), enable_device_cache=args.cache) else: Install(device, args.json_path, enable_device_cache=args.cache, use_concurrency=args.threading)
def main(): custom_handler = logging.StreamHandler(sys.stdout) custom_handler.setFormatter(run_tests_helper.CustomFormatter()) logging.getLogger().addHandler(custom_handler) logging.getLogger().setLevel(logging.INFO) parser = optparse.OptionParser() parser.add_option('--device', help='The serial number of the device. If not specified ' 'will use all devices.') parser.add_option('--blacklist-file', help='Device blacklist JSON file.') parser.add_option( '-a', '--all-tombstones', action='store_true', help="""Resolve symbols for all tombstones, rather than just the most recent""") parser.add_option('-s', '--stack', action='store_true', help='Also include symbols for stack data') parser.add_option('-w', '--wipe-tombstones', action='store_true', help='Erase all tombstones from device after processing') parser.add_option('-j', '--jobs', type='int', default=4, help='Number of jobs to use when processing multiple ' 'crash stacks.') parser.add_option('--output-directory', help='Path to the root build directory.') options, _ = parser.parse_args() devil_chromium.Initialize() blacklist = (device_blacklist.Blacklist(options.blacklist_file) if options.blacklist_file else None) if options.output_directory: constants.SetOutputDirectory(options.output_directory) # Do an up-front test that the output directory is known. constants.CheckOutputDirectory() if options.device: devices = [device_utils.DeviceUtils(options.device)] else: devices = device_utils.DeviceUtils.HealthyDevices(blacklist) # This must be done serially because strptime can hit a race condition if # used for the first time in a multithreaded environment. # http://bugs.python.org/issue7980 tombstones = [] for device in devices: tombstones += _GetTombstonesForDevice(device, options) _ResolveTombstones(options.jobs, tombstones)
def __init__(self, config): self.adb_path = constants.GetAdbPath() self.paths = Paths(config) self.device = None self.shell_args = [] self.target_package = apk_helper.GetPackageName(self.paths.apk_path) self.temp_gdb_dir = None # This is used by decive_utils.Install to check if the apk needs updating. constants.SetOutputDirectory(self.paths.build_dir)
def ProcessCommonOptions(args): """Processes and handles all common options.""" run_tests_helper.SetLogLevel(args.verbose_count, add_handler=False) handler = logging_utils.ColorStreamHandler() handler.setFormatter(run_tests_helper.CustomFormatter()) logging.getLogger().addHandler(handler) constants.SetBuildType(args.build_type) if args.output_directory: constants.SetOutputDirectory(args.output_directory)
def _ConfigOutDir(out_dir): if out_dir: constants.SetOutputDirectory(out_dir) else: try: # Triggers auto-detection when CWD == output directory. constants.CheckOutputDirectory() out_dir = constants.GetOutDirectory() except Exception: # pylint: disable=broad-except pass return out_dir
def _ConfigOutDirAndToolsPrefix(out_dir): if out_dir: constants.SetOutputDirectory(out_dir) else: out_dir = constants.GetOutDirectory() if out_dir: build_vars = build_utils.ReadBuildVars( os.path.join(out_dir, "build_vars.txt")) tool_prefix = os.path.join(out_dir, build_vars['android_tool_prefix']) else: tool_prefix = '' return out_dir, tool_prefix
def main(): custom_handler = logging.StreamHandler(sys.stdout) custom_handler.setFormatter(run_tests_helper.CustomFormatter()) logging.getLogger().addHandler(custom_handler) logging.getLogger().setLevel(logging.INFO) parser = argparse.ArgumentParser() parser.add_argument('--device', help='The serial number of the device. If not specified ' 'will use all devices.') parser.add_argument('--blacklist-file', help='Device blacklist JSON file.') parser.add_argument('-a', '--all-tombstones', action='store_true', help='Resolve symbols for all tombstones, rather than ' 'just the most recent.') parser.add_argument('-s', '--stack', action='store_true', help='Also include symbols for stack data') parser.add_argument('-w', '--wipe-tombstones', action='store_true', help='Erase all tombstones from device after processing') parser.add_argument('-j', '--jobs', type=int, default=4, help='Number of jobs to use when processing multiple ' 'crash stacks.') parser.add_argument('--output-directory', help='Path to the root build directory.') parser.add_argument('--adb-path', type=os.path.abspath, help='Path to the adb binary.') args = parser.parse_args() devil_chromium.Initialize(adb_path=args.adb_path) blacklist = (device_blacklist.Blacklist(args.blacklist_file) if args.blacklist_file else None) if args.output_directory: constants.SetOutputDirectory(args.output_directory) # Do an up-front test that the output directory is known. constants.CheckOutputDirectory() if args.device: devices = [device_utils.DeviceUtils(args.device)] else: devices = device_utils.DeviceUtils.HealthyDevices(blacklist) # This must be done serially because strptime can hit a race condition if # used for the first time in a multithreaded environment. # http://bugs.python.org/issue7980 for device in devices: resolved_tombstones = ResolveTombstones( device, args.all_tombstones, args.stack, args.wipe_tombstones, args.jobs) for line in resolved_tombstones: logging.info(line)
def Run(output_directory, apk_path, incremental_json, command_line_flags_file, target_cpu, proguard_mapping_path): """Entry point for generated wrapper scripts.""" constants.SetOutputDirectory(output_directory) devil_chromium.Initialize(output_directory=output_directory) parser = argparse.ArgumentParser() exists_or_none = lambda p: p if p and os.path.exists(p) else None parser.set_defaults(command_line_flags_file=command_line_flags_file, target_cpu=target_cpu, apk_path=exists_or_none(apk_path), incremental_json=exists_or_none(incremental_json), proguard_mapping_path=proguard_mapping_path) _RunInternal(parser, output_directory=output_directory)
def _ConfigOutDirAndToolsPrefix(out_dir): if out_dir: constants.SetOutputDirectory(out_dir) else: try: # Triggers auto-detection when CWD == output directory. constants.CheckOutputDirectory() out_dir = constants.GetOutDirectory() except Exception: # pylint: disable=broad-except return out_dir, '' build_vars = gn_helpers.ReadBuildVars(out_dir) tool_prefix = os.path.join(out_dir, build_vars['android_tool_prefix']) return out_dir, tool_prefix
def main(): parser = argparse.ArgumentParser( description=__doc__ + _list_benchmarks(), formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('benchmark', nargs='+', metavar='BENCHMARK', choices=_BENCHMARKS.keys(), help='Names of default benchmark(s) to run.') parser.add_argument('-A', '--args', choices=_GN_ARG_PRESETS.keys(), default='fast_local_dev', help='The set of GN args to use for these benchmarks.') parser.add_argument('-r', '--repeat', type=int, default=1, help='Number of times to repeat the benchmark.') parser.add_argument( '-C', '--output-directory', help='If outdir is not provided, will attempt to guess.') parser.add_argument('-v', '--verbose', action='count', default=0, help='1 to print logging, 2 to print ninja output.') args = parser.parse_args() if args.output_directory: constants.SetOutputDirectory(args.output_directory) constants.CheckOutputDirectory() out_dir = constants.GetOutDirectory() if args.verbose >= 2: level = logging.DEBUG elif args.verbose == 1: level = logging.INFO else: level = logging.WARNING logging.basicConfig( level=level, format='%(levelname).1s %(relativeCreated)6d %(message)s') gn_args = _GN_ARG_PRESETS[args.args] results = run_benchmarks(args.benchmark, gn_args, out_dir, args.repeat) print('Summary') print(f'gn args: {" ".join(gn_args)}') for name, result in results: print(f'{name}: {_format_result(result)}')
def ProcessCommonOptions(args): """Processes and handles all common options.""" run_tests_helper.SetLogLevel(args.verbose_count) constants.SetBuildType(args.build_type) if args.build_directory: constants.SetBuildDirectory(args.build_directory) if args.output_directory: constants.SetOutputDirectory(args.output_directory) if args.adb_path: constants.SetAdbPath(args.adb_path) # Some things such as Forwarder require ADB to be in the environment path. adb_dir = os.path.dirname(constants.GetAdbPath()) if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep): os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH']
def main(): argparser = argparse.ArgumentParser(description='Print APK size metrics.') argparser.add_argument( '--min-pak-resource-size', type=int, default=20 * 1024, help='Minimum byte size of displayed pak resources.') argparser.add_argument('--chromium-output-directory', help='Location of the build artifacts.') argparser.add_argument('--chartjson', action='store_true', help='Sets output mode to chartjson.') argparser.add_argument('--output-dir', default='.', help='Directory to save chartjson to.') argparser.add_argument('--no-output-dir', action='store_true', help='Skip all measurements that rely on having ' 'output-dir') argparser.add_argument('-d', '--device', help='Dummy option for perf runner.') argparser.add_argument('apk', help='APK file path.') args = argparser.parse_args() chartjson = _BASE_CHART.copy() if args.chartjson else None if args.chromium_output_directory: constants.SetOutputDirectory(args.chromium_output_directory) if not args.no_output_dir: constants.CheckOutputDirectory() devil_chromium.Initialize() build_vars = _ReadBuildVars(constants.GetOutDirectory()) tools_prefix = build_vars['android_tool_prefix'] else: tools_prefix = '' PrintApkAnalysis(args.apk, tools_prefix, chartjson=chartjson) _PrintDexAnalysis(args.apk, chartjson=chartjson) if not args.no_output_dir: PrintPakAnalysis(args.apk, args.min_pak_resource_size) _PrintStaticInitializersCountFromApk(args.apk, tools_prefix, chartjson=chartjson) if chartjson: results_path = os.path.join(args.output_dir, 'results-chart.json') logging.critical('Dumping json to %s', results_path) with open(results_path, 'w') as json_file: json.dump(chartjson, json_file)
def _ConfigOutDirAndToolsPrefix(out_dir): if out_dir: constants.SetOutputDirectory(os.path.abspath(out_dir)) else: try: out_dir = constants.GetOutDirectory() devil_chromium.Initialize() except EnvironmentError: pass if out_dir: build_vars = build_utils.ReadBuildVars() tool_prefix = os.path.join(out_dir, build_vars['android_tool_prefix']) else: tool_prefix = '' return out_dir, tool_prefix
def ProcessCommonOptions(args): """Processes and handles all common options.""" run_tests_helper.SetLogLevel(args.verbose_count, add_handler=False) # pylint: disable=redefined-variable-type if args.verbose_count > 0: handler = logging_utils.ColorStreamHandler() else: handler = logging.StreamHandler(sys.stdout) # pylint: enable=redefined-variable-type handler.setFormatter(run_tests_helper.CustomFormatter()) logging.getLogger().addHandler(handler) constants.SetBuildType(args.build_type) if args.output_directory: constants.SetOutputDirectory(args.output_directory)
def main(): parser = optparse.OptionParser() parser.add_option('-l', '--logcat', help='File containing adb logcat output with ASan stacks. ' 'Use stdin if not specified.') parser.add_option('--output-directory', help='Path to the root build directory.') options, _ = parser.parse_args() if options.output_directory: constants.SetOutputDirectory(options.output_directory) if options.logcat: asan_input = file(options.logcat, 'r') else: asan_input = sys.stdin _Symbolize(asan_input.readlines())
def main(): arg_parser = argparse.ArgumentParser( description='Finds which build target contains a particular Java class.' ) arg_parser.add_argument('-C', '--output-directory', help='Build output directory.') arg_parser.add_argument('classes', nargs='+', help=f'Java classes to search for') arg_parser.add_argument('-v', '--verbose', action='store_true', help=f'Verbose logging.') arguments = arg_parser.parse_args() logging.basicConfig( level=logging.DEBUG if arguments.verbose else logging.WARNING, format='%(asctime)s.%(msecs)03d %(levelname).1s %(message)s', datefmt='%H:%M:%S') if arguments.output_directory: constants.SetOutputDirectory(arguments.output_directory) constants.CheckOutputDirectory() out_dir: str = constants.GetOutDirectory() index = ClassLookupIndex(pathlib.Path(out_dir)) for class_name in arguments.classes: class_entries = index.match(class_name) if not class_entries: print(f'Could not find build target for class "{class_name}"') elif len(class_entries) == 1: class_entry = class_entries[0] print(f'Class {class_entry.full_class_name} found:') print(f' "{class_entry.target}"') else: print(f'Multiple targets with classes that match "{class_name}":') print() for class_entry in class_entries: print(f' "{class_entry.target}"') print(f' contains {class_entry.full_class_name}') print()
def main(): parser = argparse.ArgumentParser() parser.add_argument('-l', '--logcat', help='File containing adb logcat output with ASan ' 'stacks. Use stdin if not specified.') parser.add_argument('--output-directory', help='Path to the root build directory.') parser.add_argument('--arch', default='arm', help='CPU architecture name') args = parser.parse_args() if args.output_directory: constants.SetOutputDirectory(args.output_directory) # Do an up-front test that the output directory is known. constants.CheckOutputDirectory() if args.logcat: asan_input = open(args.logcat, 'r') else: asan_input = sys.stdin _PrintSymbolized(asan_input.readlines(), args.arch)
def main(args): parser = argparse.ArgumentParser(description='Extra argument parser', add_help=False) parser.add_argument( '--output-directory', action='store', default=None, help='Sets the CHROMIUM_OUTPUT_DIR environment variable') known_options, rest_args = parser.parse_known_args(args) constants.SetOutputDirectory( os.path.realpath(known_options.output_directory or os.getcwd())) config = chromium_config.ChromiumConfig( top_level_dir=os.path.dirname(__file__), benchmark_dirs=[os.path.dirname(__file__)]) ret_val = browser_test_runner.Run(config, rest_args) if '--help' in rest_args or '-h' in rest_args: print('\n\nCommand line arguments used in ' 'run_webview_component_smoketest.py') parser.print_help() return ret_val
def main(): parser = argparse.ArgumentParser() parser.add_argument('--output-directory', help='Path to the root build directory.') parser.add_argument('-v', '--verbose', dest='verbose_count', default=0, action='count', help='Verbose level') parser.add_argument( '--target', dest='targets', action='append', help='GN target to generate project for. Replaces set of ' 'default targets. May be repeated.') parser.add_argument( '--extra-target', dest='extra_targets', action='append', help='GN target to generate project for, in addition to ' 'the default ones. May be repeated.') parser.add_argument('--project-dir', help='Root of the output project.', default=os.path.join('$CHROMIUM_OUTPUT_DIR', 'gradle')) parser.add_argument('--all', action='store_true', help='Include all .java files reachable from any ' 'apk/test/binary target. On by default unless ' '--split-projects is used (--split-projects can ' 'slow down Studio given too many targets).') parser.add_argument('--use-gradle-process-resources', action='store_true', help='Have gradle generate R.java rather than ninja') parser.add_argument('--split-projects', action='store_true', help='Split projects by their gn deps rather than ' 'combining all the dependencies of each target') version_group = parser.add_mutually_exclusive_group() version_group.add_argument( '--beta', action='store_true', help='Generate a project that is compatible with ' 'Android Studio Beta.') version_group.add_argument( '--canary', action='store_true', help='Generate a project that is compatible with ' 'Android Studio Canary.') sdk_group = parser.add_mutually_exclusive_group() sdk_group.add_argument( '--sdk', choices=[ 'AndroidStudioCurrent', 'AndroidStudioDefault', 'ChromiumSdkRoot' ], default='ChromiumSdkRoot', help="Set the project's SDK root. This can be set to " "Android Studio's current SDK root, the default " "Android Studio SDK root, or Chromium's SDK " "root. The default is Chromium's SDK root, but " "using this means that updates and additions to " "the SDK (e.g. installing emulators), will " "modify this root, hence possibly causing " "conflicts on the next repository sync.") sdk_group.add_argument( '--sdk-path', help='An explict path for the SDK root, setting this ' 'is an alternative to setting the --sdk option') args = parser.parse_args() if args.output_directory: constants.SetOutputDirectory(args.output_directory) constants.CheckOutputDirectory() output_dir = constants.GetOutDirectory() devil_chromium.Initialize(output_directory=output_dir) run_tests_helper.SetLogLevel(args.verbose_count) if args.use_gradle_process_resources: assert args.split_projects, ( 'Gradle resources does not work without --split-projects.') _gradle_output_dir = os.path.abspath( args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir)) jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) build_vars = _ReadPropertiesFile(os.path.join(output_dir, 'build_vars.txt')) source_properties = _ReadPropertiesFile( _RebasePath( os.path.join(build_vars['android_sdk_build_tools'], 'source.properties'))) if args.beta: channel = 'beta' elif args.canary: channel = 'canary' else: channel = 'stable' generator = _ProjectContextGenerator(_gradle_output_dir, build_vars, args.use_gradle_process_resources, jinja_processor, args.split_projects, channel) logging.warning('Creating project at: %s', generator.project_dir) # Generate for "all targets" by default when not using --split-projects (too # slow), and when no --target has been explicitly set. "all targets" means all # java targets that are depended on by an apk or java_binary (leaf # java_library targets will not be included). args.all = args.all or (not args.split_projects and not args.targets) targets_from_args = set(args.targets or _DEFAULT_TARGETS) if args.extra_targets: targets_from_args.update(args.extra_targets) if args.all: # Run GN gen if necessary (faster than running "gn gen" in the no-op case). _RunNinja(constants.GetOutDirectory(), ['build.ninja']) # Query ninja for all __build_config targets. targets = _QueryForAllGnTargets(output_dir) else: targets = [ re.sub(r'_test_apk$', '_test_apk__apk', t) for t in targets_from_args ] main_entries = [_ProjectEntry.FromGnTarget(t) for t in targets] logging.warning('Building .build_config files...') _RunNinja(output_dir, [e.NinjaBuildConfigTarget() for e in main_entries]) if args.all: # There are many unused libraries, so restrict to those that are actually # used by apks/binaries/tests or that are explicitly mentioned in --targets. main_entries = [ e for e in main_entries if (e.GetType() in ('android_apk', 'java_binary', 'junit_binary') or e.GnTarget() in targets_from_args or e.GnTarget().endswith('_test_apk__apk')) ] if args.split_projects: main_entries = _FindAllProjectEntries(main_entries) logging.info('Generating for %d targets.', len(main_entries)) entries = [e for e in _CombineTestEntries(main_entries) if e.IsValid()] logging.info('Creating %d projects for targets.', len(entries)) # When only one entry will be generated we want it to have a valid # build.gradle file with its own AndroidManifest. add_all_module = not args.split_projects and len(entries) > 1 logging.warning('Writing .gradle files...') project_entries = [] zip_tuples = [] generated_inputs = [] for entry in entries: data = _GenerateGradleFile(entry, generator, build_vars, source_properties, jinja_processor) if data: # Build all paths references by .gradle that exist within output_dir. generated_inputs.extend(generator.GeneratedInputs(entry)) zip_tuples.extend(( s, os.path.join(generator.EntryOutputDir(entry), _SRCJARS_SUBDIR)) for s in generator.AllSrcjars(entry)) zip_tuples.extend( (s, os.path.join(generator.EntryOutputDir(entry), _RES_SUBDIR)) for s in generator.AllResZips(entry)) if not add_all_module: project_entries.append(entry) _WriteFile( os.path.join(generator.EntryOutputDir(entry), _GRADLE_BUILD_FILE), data) if add_all_module: _GenerateModuleAll(_gradle_output_dir, generator, build_vars, source_properties, jinja_processor) _WriteFile(os.path.join(generator.project_dir, _GRADLE_BUILD_FILE), _GenerateRootGradle(jinja_processor, channel)) _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), _GenerateSettingsGradle(project_entries, add_all_module)) if args.sdk != "AndroidStudioCurrent": if args.sdk_path: sdk_path = _RebasePath(args.sdk_path) elif args.sdk == "AndroidStudioDefault": sdk_path = os.path.expanduser('~/Android/Sdk') else: sdk_path = _RebasePath(build_vars['android_sdk_root']) _WriteFile(os.path.join(generator.project_dir, 'local.properties'), _GenerateLocalProperties(sdk_path)) if generated_inputs: logging.warning('Building generated source files...') targets = _RebasePath(generated_inputs, output_dir) _RunNinja(output_dir, targets) if zip_tuples: _ExtractZips(generator.project_dir, zip_tuples) logging.warning('Project created!') logging.warning('Generated projects work with Android Studio %s', channel) logging.warning('For more tips: https://chromium.googlesource.com/chromium' '/src.git/+/master/docs/android_studio.md')
def main(): parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument( '-C', '--output-directory', help='If outdir is not provided, will attempt to guess.') parser.add_argument('--gn-labels', action='store_true', help='Print GN labels rather than ninja targets') parser.add_argument( '--nested', action='store_true', help='Do not convert nested targets to their top-level equivalents. ' 'E.g. Without this, foo_test__apk -> foo_test') parser.add_argument('--print-types', action='store_true', help='Print type of each target') parser.add_argument('--build-build-configs', action='store_true', help='Build all .build_config files.') parser.add_argument('--type', action='append', help='Restrict to targets of given type', choices=_VALID_TYPES) parser.add_argument('--stats', action='store_true', help='Print counts of each target type.') parser.add_argument('-v', '--verbose', default=0, action='count') args = parser.parse_args() args.build_build_configs |= bool(args.type or args.print_types or args.stats) logging.basicConfig( level=logging.WARNING - (10 * args.verbose), format='%(levelname).1s %(relativeCreated)6d %(message)s') if args.output_directory: constants.SetOutputDirectory(args.output_directory) constants.CheckOutputDirectory() output_dir = constants.GetOutDirectory() # Query ninja for all __build_config_crbug_908819 targets. targets = _query_for_build_config_targets(output_dir) entries = [_TargetEntry(t) for t in targets] if args.build_build_configs: logging.warning('Building %d .build_config files...', len(entries)) _run_ninja(output_dir, [e.ninja_build_config_target for e in entries]) if args.type: entries = [e for e in entries if e.get_type() in args.type] if args.stats: counts = collections.Counter(e.get_type() for e in entries) for entry_type, count in sorted(counts.items()): print(f'{entry_type}: {count}') else: for e in entries: if args.gn_labels: to_print = e.gn_target else: to_print = e.ninja_target # Convert to top-level target if not args.nested: to_print = to_print.replace('__test_apk__apk', '').replace('__apk', '') if args.print_types: to_print = f'{to_print}: {e.get_type()}' print(to_print)
def ProcessCommonOptions(args): """Processes and handles all common options.""" run_tests_helper.SetLogLevel(args.verbose_count) constants.SetBuildType(args.build_type) if args.output_directory: constants.SetOutputDirectory(args.output_directory)
def main(): parser = argparse.ArgumentParser() parser.add_argument('--output-directory', help='Path to the root build directory.') parser.add_argument('-v', '--verbose', dest='verbose_count', default=0, action='count', help='Verbose level') parser.add_argument( '--target', dest='targets', action='append', help='GN target to generate project for. Replaces set of ' 'default targets. May be repeated.') parser.add_argument( '--extra-target', dest='extra_targets', action='append', help='GN target to generate project for, in addition to ' 'the default ones. May be repeated.') parser.add_argument('--project-dir', help='Root of the output project.', default=os.path.join('$CHROMIUM_OUTPUT_DIR', 'gradle')) parser.add_argument('--all', action='store_true', help='Include all .java files reachable from any ' 'apk/test/binary target. On by default unless ' '--split-projects is used (--split-projects can ' 'slow down Studio given too many targets).') parser.add_argument('--use-gradle-process-resources', action='store_true', help='Have gradle generate R.java rather than ninja') parser.add_argument('--split-projects', action='store_true', help='Split projects by their gn deps rather than ' 'combining all the dependencies of each target') parser.add_argument('--native-target', dest='native_targets', action='append', help='GN native targets to generate for. May be ' 'repeated.') parser.add_argument( '--compile-sdk-version', type=int, default=0, help='Override compileSdkVersion for android sdk docs. ' 'Useful when sources for android_sdk_version is ' 'not available in Android Studio.') parser.add_argument('--sdk-path', default=os.path.expanduser('~/Android/Sdk'), help='The path to use as the SDK root, overrides the ' 'default at ~/Android/Sdk.') version_group = parser.add_mutually_exclusive_group() version_group.add_argument( '--beta', action='store_true', help='Generate a project that is compatible with ' 'Android Studio Beta.') version_group.add_argument( '--canary', action='store_true', help='Generate a project that is compatible with ' 'Android Studio Canary.') args = parser.parse_args() if args.output_directory: constants.SetOutputDirectory(args.output_directory) constants.CheckOutputDirectory() output_dir = constants.GetOutDirectory() devil_chromium.Initialize(output_directory=output_dir) run_tests_helper.SetLogLevel(args.verbose_count) if args.use_gradle_process_resources: assert args.split_projects, ( 'Gradle resources does not work without --split-projects.') _gradle_output_dir = os.path.abspath( args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir)) logging.warning('Creating project at: %s', _gradle_output_dir) # Generate for "all targets" by default when not using --split-projects (too # slow), and when no --target has been explicitly set. "all targets" means all # java targets that are depended on by an apk or java_binary (leaf # java_library targets will not be included). args.all = args.all or (not args.split_projects and not args.targets) targets_from_args = set(args.targets or _DEFAULT_TARGETS) if args.extra_targets: targets_from_args.update(args.extra_targets) if args.all: if args.native_targets: _RunGnGen(output_dir, ['--ide=json']) elif not os.path.exists(os.path.join(output_dir, 'build.ninja')): _RunGnGen(output_dir) else: # Faster than running "gn gen" in the no-op case. _RunNinja(output_dir, ['build.ninja']) # Query ninja for all __build_config_crbug_908819 targets. targets = _QueryForAllGnTargets(output_dir) else: assert not args.native_targets, 'Native editing requires --all.' targets = [ re.sub(r'_test_apk$', _INSTRUMENTATION_TARGET_SUFFIX, t) for t in targets_from_args ] # Necessary after "gn clean" if not os.path.exists(os.path.join(output_dir, 'build_vars.txt')): _RunGnGen(output_dir) build_vars = _ReadPropertiesFile(os.path.join(output_dir, 'build_vars.txt')) jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) if args.beta: channel = 'beta' elif args.canary: channel = 'canary' else: channel = 'stable' if args.compile_sdk_version: build_vars['compile_sdk_version'] = args.compile_sdk_version else: build_vars['compile_sdk_version'] = build_vars['android_sdk_version'] generator = _ProjectContextGenerator(_gradle_output_dir, build_vars, args.use_gradle_process_resources, jinja_processor, args.split_projects, channel) main_entries = [_ProjectEntry.FromGnTarget(t) for t in targets] if args.all: # There are many unused libraries, so restrict to those that are actually # used by apks/bundles/binaries/tests or that are explicitly mentioned in # --targets. BASE_TYPES = ('android_apk', 'android_app_bundle_module', 'java_binary', 'junit_binary') main_entries = [ e for e in main_entries if (e.GetType() in BASE_TYPES or e.GnTarget() in targets_from_args or e.GnTarget().endswith(_INSTRUMENTATION_TARGET_SUFFIX)) ] if args.split_projects: main_entries = _FindAllProjectEntries(main_entries) logging.info('Generating for %d targets.', len(main_entries)) entries = [e for e in _CombineTestEntries(main_entries) if e.IsValid()] logging.info('Creating %d projects for targets.', len(entries)) logging.warning('Writing .gradle files...') project_entries = [] # When only one entry will be generated we want it to have a valid # build.gradle file with its own AndroidManifest. for entry in entries: data = _GenerateGradleFile(entry, generator, build_vars, jinja_processor) if data and not args.all: project_entries.append((entry.ProjectName(), entry.GradleSubdir())) _WriteFile( os.path.join(generator.EntryOutputDir(entry), _GRADLE_BUILD_FILE), data) if args.all: project_entries.append((_MODULE_ALL, _MODULE_ALL)) _GenerateModuleAll(_gradle_output_dir, generator, build_vars, jinja_processor, args.native_targets) _WriteFile(os.path.join(generator.project_dir, _GRADLE_BUILD_FILE), _GenerateRootGradle(jinja_processor, channel)) _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), _GenerateSettingsGradle(project_entries)) # Ensure the Android Studio sdk is correctly initialized. if not os.path.exists(args.sdk_path): # Help first-time users avoid Android Studio forcibly changing back to # the previous default due to not finding a valid sdk under this dir. shutil.copytree(_RebasePath(build_vars['android_sdk_root']), args.sdk_path) _WriteFile(os.path.join(generator.project_dir, 'local.properties'), _GenerateLocalProperties(args.sdk_path)) _WriteFile(os.path.join(generator.project_dir, 'gradle.properties'), _GenerateGradleProperties()) wrapper_properties = os.path.join(generator.project_dir, 'gradle', 'wrapper', 'gradle-wrapper.properties') if os.path.exists(wrapper_properties): os.unlink(wrapper_properties) if args.canary: _WriteFile(wrapper_properties, _GenerateGradleWrapperPropertiesCanary()) generated_inputs = set() for entry in entries: entries_to_gen = [entry] entries_to_gen.extend(entry.android_test_entries) for entry_to_gen in entries_to_gen: # Build all paths references by .gradle that exist within output_dir. generated_inputs.update(generator.GeneratedInputs(entry_to_gen)) if generated_inputs: targets = _RebasePath(generated_inputs, output_dir) _RunNinja(output_dir, targets) logging.warning( 'Generated files will only appear once you\'ve built them.') logging.warning('Generated projects for Android Studio %s', channel) logging.warning('For more tips: https://chromium.googlesource.com/chromium' '/src.git/+/master/docs/android_studio.md')
def main(): parser = argparse.ArgumentParser() parser.add_argument('--output-directory', help='Path to the root build directory.') parser.add_argument('-v', '--verbose', dest='verbose_count', default=0, action='count', help='Verbose level') parser.add_argument( '--target', dest='targets', action='append', help='GN target to generate project for. Replaces set of ' 'default targets. May be repeated.') parser.add_argument( '--extra-target', dest='extra_targets', action='append', help='GN target to generate project for, in addition to ' 'the default ones. May be repeated.') parser.add_argument('--project-dir', help='Root of the output project.', default=os.path.join('$CHROMIUM_OUTPUT_DIR', 'gradle')) parser.add_argument('--all', action='store_true', help='Generate all java targets (slows down IDE)') parser.add_argument('--use-gradle-process-resources', action='store_true', help='Have gradle generate R.java rather than ninja') parser.add_argument('--split-projects', action='store_true', help='Split projects by their gn deps rather than ' 'combining all the dependencies of each target') args = parser.parse_args() if args.output_directory: constants.SetOutputDirectory(args.output_directory) constants.CheckOutputDirectory() output_dir = constants.GetOutDirectory() devil_chromium.Initialize(output_directory=output_dir) run_tests_helper.SetLogLevel(args.verbose_count) if args.use_gradle_process_resources: assert args.split_projects, ( 'Gradle resources does not work without --split-projects.') _gradle_output_dir = os.path.abspath( args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir)) jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) build_vars = _ReadPropertiesFile(os.path.join(output_dir, 'build_vars.txt')) source_properties = _ReadPropertiesFile( _RebasePath( os.path.join(build_vars['android_sdk_build_tools'], 'source.properties'))) generator = _ProjectContextGenerator(_gradle_output_dir, build_vars, args.use_gradle_process_resources, jinja_processor, args.split_projects) logging.warning('Creating project at: %s', generator.project_dir) if args.all: # Run GN gen if necessary (faster than running "gn gen" in the no-op case). _RunNinja(constants.GetOutDirectory(), ['build.ninja']) # Query ninja for all __build_config targets. targets = _QueryForAllGnTargets(output_dir) else: targets = args.targets or _DEFAULT_TARGETS if args.extra_targets: targets.extend(args.extra_targets) targets = [re.sub(r'_test_apk$', '_test_apk__apk', t) for t in targets] # TODO(wnwen): Utilize Gradle's test constructs for our junit tests? targets = [ re.sub(r'_junit_tests$', '_junit_tests__java_binary', t) for t in targets ] main_entries = [_ProjectEntry.FromGnTarget(t) for t in targets] logging.warning('Building .build_config files...') _RunNinja(output_dir, [e.NinjaBuildConfigTarget() for e in main_entries]) # There are many unused libraries, so restrict to those that are actually used # when using --all. if args.all: main_entries = [ e for e in main_entries if (e.GetType() == 'android_apk' or e.GnTarget().endswith('_test_apk__apk') or e.GnTarget().endswith('_junit_tests__java_binary')) ] if args.split_projects: main_entries = _FindAllProjectEntries(main_entries) logging.info('Found %d dependent build_config targets.', len(main_entries)) entries = [e for e in _CombineTestEntries(main_entries) if e.IsValid()] logging.info('Creating %d projects for targets.', len(entries)) # When only one entry will be generated we want it to have a valid # build.gradle file with its own AndroidManifest. add_all_module = not args.split_projects and len(entries) > 1 logging.warning('Writing .gradle files...') project_entries = [] zip_tuples = [] generated_inputs = [] for entry in entries: data = _GenerateGradleFile(entry, generator, build_vars, source_properties, jinja_processor) if data: # Build all paths references by .gradle that exist within output_dir. generated_inputs.extend(generator.GeneratedInputs(entry)) zip_tuples.extend(( s, os.path.join(generator.EntryOutputDir(entry), _SRCJARS_SUBDIR)) for s in generator.AllSrcjars(entry)) zip_tuples.extend( (s, os.path.join(generator.EntryOutputDir(entry), _RES_SUBDIR)) for s in generator.AllResZips(entry)) if not add_all_module: project_entries.append(entry) _WriteFile( os.path.join(generator.EntryOutputDir(entry), _GRADLE_BUILD_FILE), data) if add_all_module: _GenerateModuleAll(_gradle_output_dir, generator, build_vars, source_properties, jinja_processor) _WriteFile(os.path.join(generator.project_dir, _GRADLE_BUILD_FILE), _GenerateRootGradle(jinja_processor)) _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), _GenerateSettingsGradle(project_entries, add_all_module)) sdk_path = _RebasePath(build_vars['android_sdk_root']) _WriteFile(os.path.join(generator.project_dir, 'local.properties'), _GenerateLocalProperties(sdk_path)) if generated_inputs: logging.warning('Building generated source files...') targets = _RebasePath(generated_inputs, output_dir) _RunNinja(output_dir, targets) if zip_tuples: _ExtractZips(generator.project_dir, zip_tuples) logging.warning('Project created!') logging.warning('Generated projects work with Android Studio 2.3') logging.warning('For more tips: https://chromium.googlesource.com/chromium' '/src.git/+/master/docs/android_studio.md')
def main(): parser = argparse.ArgumentParser() parser.add_argument('apk_path', help='The path to the APK to install.') parser.add_argument('--split', action='append', dest='splits', help='A glob matching the apk splits. ' 'Can be specified multiple times.') parser.add_argument('--native_lib', dest='native_libs', help='Path to native library (repeatable)', action='append', default=[]) parser.add_argument('--dex-file', dest='dex_files', help='Path to dex files (repeatable)', action='append', default=[]) parser.add_argument('-d', '--device', dest='device', help='Target device for apk to install on.') parser.add_argument('--uninstall', action='store_true', default=False, help='Remove the app and all side-loaded files.') parser.add_argument('--output-directory', help='Path to the root build directory.') parser.add_argument('--no-threading', action='store_false', default=True, dest='threading', help='Do not install and push concurrently') parser.add_argument( '--no-cache', action='store_false', default=True, dest='cache', help='Do not use cached information about what files are ' 'currently on the target device.') parser.add_argument('--show-proguard-warning', action='store_true', default=False, help='Print a warning about proguard being disabled') parser.add_argument('--dont-even-try', help='Prints this message and exits.') parser.add_argument('-v', '--verbose', dest='verbose_count', default=0, action='count', help='Verbose level (multiple times for more)') args = parser.parse_args() run_tests_helper.SetLogLevel(args.verbose_count) constants.SetBuildType('Debug') if args.output_directory: constants.SetOutputDirectory(args.output_directory) devil_chromium.Initialize(output_directory=constants.GetOutDirectory()) if args.dont_even_try: logging.fatal(args.dont_even_try) return 1 # Retries are annoying when commands fail for legitimate reasons. Might want # to enable them if this is ever used on bots though. device = device_utils.DeviceUtils.HealthyDevices( device_arg=args.device, default_retries=0, enable_device_files_cache=True)[0] apk = apk_helper.ToHelper(args.apk_path) if args.uninstall: Uninstall(device, apk.GetPackageName(), enable_device_cache=args.cache) else: Install(device, apk, split_globs=args.splits, native_libs=args.native_libs, dex_files=args.dex_files, enable_device_cache=args.cache, use_concurrency=args.threading, show_proguard_warning=args.show_proguard_warning)
packed_libs = [] for option, value in options: if option == "--help": PrintUsage() elif option == "--symbols-dir": symbol.SYMBOLS_DIR = os.path.abspath(os.path.expanduser(value)) elif option == "--symbols-zip": zip_arg = os.path.abspath(os.path.expanduser(value)) elif option == "--arch": symbol.ARCH = value arch_defined = True elif option == "--chrome-symbols-dir": symbol.CHROME_SYMBOLS_DIR = os.path.join(constants.DIR_SOURCE_ROOT, value) elif option == "--output-directory": constants.SetOutputDirectory(os.path.abspath(value)) elif option == "--packed-lib": packed_libs.append(os.path.abspath(os.path.expanduser(value))) elif option == "--more-info": more_info = True elif option == "--less-info": more_info = False elif option == "--fallback-monochrome": fallback_monochrome = True elif option == "--verbose": logging.basicConfig(level=logging.DEBUG) elif option in ('--packed-relocation-adjustments', '--no-packed-relocation-adjustments'): print( '--[no-]packed-relocation-adjustments options are deprecated. ' 'Specify packed libs directory instead.')
def main(argv): usage = """Usage: %prog [options] file1 file2 ... Pass any number of files to graph their sizes. Any files with the extension '.apk' will be broken down into their components on a separate graph.""" option_parser = optparse.OptionParser(usage=usage) option_parser.add_option('--so-path', help='Path to libchrome.so.') option_parser.add_option('--so-with-symbols-path', help='Path to libchrome.so with symbols.') option_parser.add_option( '--min-pak-resource-size', type='int', default=20 * 1024, help='Minimum byte size of displayed pak resources.') option_parser.add_option('--build_type', dest='build_type', default='Debug', help='Sets the build type, default is Debug.') option_parser.add_option('--chromium-output-directory', help='Location of the build artifacts. ' 'Takes precidence over --build_type.') option_parser.add_option('--chartjson', action="store_true", help='Sets output mode to chartjson.') option_parser.add_option('--output-dir', default='.', help='Directory to save chartjson to.') option_parser.add_option('-d', '--device', help='Dummy option for perf runner.') options, args = option_parser.parse_args(argv) files = args[1:] chartjson = _BASE_CHART.copy() if options.chartjson else None constants.SetBuildType(options.build_type) if options.chromium_output_directory: constants.SetOutputDirectory(options.chromium_output_directory) constants.CheckOutputDirectory() # For backward compatibilty with buildbot scripts, treat --so-path as just # another file to print the size of. We don't need it for anything special any # more. if options.so_path: files.append(options.so_path) if not files: option_parser.error('Must specify a file') devil_chromium.Initialize() if options.so_with_symbols_path: PrintStaticInitializersCount(options.so_with_symbols_path, chartjson=chartjson) PrintResourceSizes(files, chartjson=chartjson) for f in files: if f.endswith('.apk'): PrintApkAnalysis(f, chartjson=chartjson) PrintPakAnalysis(f, options.min_pak_resource_size) if chartjson: results_path = os.path.join(options.output_dir, 'results-chart.json') with open(results_path, 'w') as json_file: json.dump(chartjson, json_file)
def main(): parser = argparse.ArgumentParser() parser.add_argument('apk_path', help='The path to the APK to install.') parser.add_argument('--split', action='append', dest='splits', help='A glob matching the apk splits. ' 'Can be specified multiple times.') parser.add_argument('--native_lib', dest='native_libs', help='Path to native library (repeatable)', action='append', default=[]) parser.add_argument('--dex-file', dest='dex_files', help='Path to dex files (repeatable)', action='append', default=[]) parser.add_argument('-d', '--device', dest='device', help='Target device for apk to install on.') parser.add_argument('--uninstall', action='store_true', default=False, help='Remove the app and all side-loaded files.') parser.add_argument('--output-directory', help='Path to the root build directory.') parser.add_argument('--no-threading', action='store_false', default=True, dest='threading', help='Do not install and push concurrently') parser.add_argument( '--no-cache', action='store_false', default=True, dest='cache', help='Do not use cached information about what files are ' 'currently on the target device.') parser.add_argument('--show-proguard-warning', action='store_true', default=False, help='Print a warning about proguard being disabled') parser.add_argument('-v', '--verbose', dest='verbose_count', default=0, action='count', help='Verbose level (multiple times for more)') args = parser.parse_args() run_tests_helper.SetLogLevel(args.verbose_count) constants.SetBuildType('Debug') if args.output_directory: constants.SetOutputDirectory(args.output_directory) if args.device: # Retries are annoying when commands fail for legitimate reasons. Might want # to enable them if this is ever used on bots though. device = device_utils.DeviceUtils(args.device, default_retries=0, enable_device_files_cache=True) else: devices = device_utils.DeviceUtils.HealthyDevices( default_retries=0, enable_device_files_cache=True) if not devices: raise device_errors.NoDevicesError() elif len(devices) == 1: device = devices[0] else: all_devices = device_utils.DeviceUtils.parallel(devices) msg = ('More than one device available.\n' 'Use --device=SERIAL to select a device.\n' 'Available devices:\n') descriptions = all_devices.pMap( lambda d: d.build_description).pGet(None) for d, desc in zip(devices, descriptions): msg += ' %s (%s)\n' % (d, desc) raise Exception(msg) apk = apk_helper.ToHelper(args.apk_path) if args.uninstall: Uninstall(device, apk.GetPackageName()) else: Install(device, apk, split_globs=args.splits, native_libs=args.native_libs, dex_files=args.dex_files, enable_device_cache=args.cache, use_concurrency=args.threading, show_proguard_warning=args.show_proguard_warning)