| Index: build/android/gradle/generate_gradle.py
|
| diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py
|
| index 1170b63ec2bbf44e81e93c47532ed31fa454db6f..7a8ec3219da3879e133c3b2eae041febc58a9b58 100755
|
| --- a/build/android/gradle/generate_gradle.py
|
| +++ b/build/android/gradle/generate_gradle.py
|
| @@ -121,22 +121,34 @@ def _QueryForAllGnTargets(output_dir):
|
|
|
| class _ProjectEntry(object):
|
| """Helper class for project entries."""
|
| +
|
| + _cached_entries = {}
|
| +
|
| def __init__(self, gn_target):
|
| - assert gn_target.startswith('//'), gn_target
|
| - if ':' not in gn_target:
|
| - gn_target = '%s:%s' % (gn_target, os.path.basename(gn_target))
|
| + # Use _ProjectEntry.FromGnTarget instead for caching.
|
| self._gn_target = gn_target
|
| self._build_config = None
|
| self._java_files = None
|
| + self._all_entries = None
|
| self.android_test_entry = None
|
|
|
| @classmethod
|
| + def FromGnTarget(cls, gn_target):
|
| + assert gn_target.startswith('//'), gn_target
|
| + if ':' not in gn_target:
|
| + gn_target = '%s:%s' % (gn_target, os.path.basename(gn_target))
|
| + if gn_target not in cls._cached_entries:
|
| + cls._cached_entries[gn_target] = cls(gn_target)
|
| + return cls._cached_entries[gn_target]
|
| +
|
| + @classmethod
|
| def FromBuildConfigPath(cls, path):
|
| prefix = 'gen/'
|
| suffix = '.build_config'
|
| assert path.startswith(prefix) and path.endswith(suffix), path
|
| subdir = path[len(prefix):-len(suffix)]
|
| - return cls('//%s:%s' % (os.path.split(subdir)))
|
| + gn_target = '//%s:%s' % (os.path.split(subdir))
|
| + return cls.FromGnTarget(gn_target)
|
|
|
| def __hash__(self):
|
| return hash(self._gn_target)
|
| @@ -197,6 +209,29 @@ class _ProjectEntry(object):
|
| self._java_files = java_files
|
| return self._java_files
|
|
|
| + def GeneratedJavaFiles(self):
|
| + return [p for p in self.JavaFiles() if not p.startswith('..')]
|
| +
|
| + def PrebuiltJars(self):
|
| + return self.Gradle()['dependent_prebuilt_jars']
|
| +
|
| + def AllEntries(self):
|
| + """Returns a list of all entries that the current entry depends on.
|
| +
|
| + This includes the entry itself to make iterating simpler."""
|
| + if self._all_entries is None:
|
| + logging.debug('Generating entries for %s', self.GnTarget())
|
| + deps = [_ProjectEntry.FromBuildConfigPath(p)
|
| + for p in self.Gradle()['dependent_android_projects']]
|
| + deps.extend(_ProjectEntry.FromBuildConfigPath(p)
|
| + for p in self.Gradle()['dependent_java_projects'])
|
| + all_entries = set()
|
| + for dep in deps:
|
| + all_entries.update(dep.AllEntries())
|
| + all_entries.add(self)
|
| + self._all_entries = list(all_entries)
|
| + return self._all_entries
|
| +
|
|
|
| class _ProjectContextGenerator(object):
|
| """Helper class to generate gradle build files"""
|
| @@ -218,7 +253,7 @@ class _ProjectContextGenerator(object):
|
| return jni_libs
|
|
|
| def _GenJavaDirs(self, entry):
|
| - java_dirs, excludes = _CreateJavaSourceDir(
|
| + java_dirs, excludes = _ComputeJavaSourceDirsAndExcludes(
|
| constants.GetOutDirectory(), entry.JavaFiles())
|
| if self.Srcjars(entry):
|
| java_dirs.append(
|
| @@ -232,18 +267,19 @@ class _ProjectContextGenerator(object):
|
| return res_dirs
|
|
|
| def _GenCustomManifest(self, entry):
|
| - """Returns the path to the generated AndroidManifest.xml."""
|
| - javac = entry.Javac()
|
| - resource_packages = javac['resource_packages']
|
| - output_file = os.path.join(
|
| - self.EntryOutputDir(entry), 'AndroidManifest.xml')
|
| + """Returns the path to the generated AndroidManifest.xml.
|
|
|
| + Gradle uses package id from manifest when generating R.class. So, we need
|
| + to generate a custom manifest if we let gradle process resources. We cannot
|
| + simply set android.defaultConfig.applicationId because it is not supported
|
| + for library targets."""
|
| + resource_packages = entry.Javac().get('resource_packages')
|
| if not resource_packages:
|
| - logging.error('Target ' + entry.GnTarget() + ' includes resources from '
|
| + logging.debug('Target ' + entry.GnTarget() + ' includes resources from '
|
| 'unknown package. Unable to process with gradle.')
|
| return _DEFAULT_ANDROID_MANIFEST_PATH
|
| elif len(resource_packages) > 1:
|
| - logging.error('Target ' + entry.GnTarget() + ' includes resources from '
|
| + logging.debug('Target ' + entry.GnTarget() + ' includes resources from '
|
| 'multiple packages. Unable to process with gradle.')
|
| return _DEFAULT_ANDROID_MANIFEST_PATH
|
|
|
| @@ -251,6 +287,8 @@ class _ProjectContextGenerator(object):
|
| variables['compile_sdk_version'] = self.build_vars['android_sdk_version']
|
| variables['package'] = resource_packages[0]
|
|
|
| + output_file = os.path.join(
|
| + self.EntryOutputDir(entry), 'AndroidManifest.xml')
|
| data = self.jinja_processor.Render(_TemplatePath('manifest'), variables)
|
| _WriteFile(output_file, data)
|
|
|
| @@ -272,9 +310,8 @@ class _ProjectContextGenerator(object):
|
| generated_inputs = []
|
| generated_inputs.extend(self.Srcjars(entry))
|
| generated_inputs.extend(_RebasePath(entry.ResZips()))
|
| - generated_inputs.extend(
|
| - p for p in entry.JavaFiles() if not p.startswith('..'))
|
| - generated_inputs.extend(entry.Gradle()['dependent_prebuilt_jars'])
|
| + generated_inputs.extend(entry.GeneratedJavaFiles())
|
| + generated_inputs.extend(entry.PrebuiltJars())
|
| return generated_inputs
|
|
|
| def Generate(self, entry):
|
| @@ -286,22 +323,14 @@ class _ProjectContextGenerator(object):
|
| variables['res_dirs'] = self._Relativize(entry, self._GenResDirs(entry))
|
| android_manifest = entry.Gradle().get('android_manifest')
|
| if not android_manifest:
|
| - # Gradle uses package id from manifest when generating R.class. So, we
|
| - # need to generate a custom manifest if we let gradle process resources.
|
| - # We cannot simply set android.defaultConfig.applicationId because it is
|
| - # not supported for library targets.
|
| - if variables['res_dirs']:
|
| - android_manifest = self._GenCustomManifest(entry)
|
| - else:
|
| - android_manifest = _DEFAULT_ANDROID_MANIFEST_PATH
|
| + android_manifest = self._GenCustomManifest(entry)
|
| variables['android_manifest'] = self._Relativize(entry, android_manifest)
|
| + # TODO(agrieve): Add an option to use interface jars and see if that speeds
|
| + # things up at all.
|
| + variables['prebuilts'] = self._Relativize(entry, entry.PrebuiltJars())
|
| deps = [_ProjectEntry.FromBuildConfigPath(p)
|
| for p in entry.Gradle()['dependent_android_projects']]
|
| variables['android_project_deps'] = [d.ProjectName() for d in deps]
|
| - # TODO(agrieve): Add an option to use interface jars and see if that speeds
|
| - # things up at all.
|
| - variables['prebuilts'] = self._Relativize(
|
| - entry, entry.Gradle()['dependent_prebuilt_jars'])
|
| deps = [_ProjectEntry.FromBuildConfigPath(p)
|
| for p in entry.Gradle()['dependent_java_projects']]
|
| variables['java_project_deps'] = [d.ProjectName() for d in deps]
|
| @@ -352,7 +381,7 @@ def _ComputeExcludeFilters(wanted_files, unwanted_files, parent_dir):
|
| return excludes
|
|
|
|
|
| -def _CreateJavaSourceDir(output_dir, java_files):
|
| +def _ComputeJavaSourceDirsAndExcludes(output_dir, java_files):
|
| """Computes the list of java source directories and exclude patterns.
|
|
|
| 1. Computes the root java source directories from the list of files.
|
| @@ -467,6 +496,10 @@ def _GenerateGradleFile(entry, generator, build_vars, jinja_processor):
|
| if entry.android_test_entry:
|
| variables['android_test'] = generator.Generate(
|
| entry.android_test_entry)
|
| + for key, value in variables['android_test'].iteritems():
|
| + if isinstance(value, list):
|
| + variables['android_test'][key] = list(
|
| + set(value) - set(variables['main'][key]))
|
|
|
| return jinja_processor.Render(
|
| _TemplatePath(target_type.split('_')[0]), variables)
|
| @@ -606,7 +639,7 @@ def main():
|
| targets = [re.sub(r'_junit_tests$', '_junit_tests__java_binary', t)
|
| for t in targets]
|
|
|
| - main_entries = [_ProjectEntry(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])
|
|
|