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() 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, gn_helpers.BUILD_VARS_FILENAME)): _RunGnGen(output_dir) build_vars = gn_helpers.ReadBuildVars(output_dir) 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')