예제 #1
0
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
예제 #2
0
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')