Android: Remove apk modules for Android Studio
It is no longer necessary to list all the apk targets as separate modules now that we have the _all pseudo module. Having the separate modules resulted in bugs where Android Studio could not distinguish between prod code and test code since some modules viewed dirs as prod and some as test. The --split-projects flag can be used to see the dependency graph, and when only a single module will be generated, the _all pseudo module will not replace it. For android studio's _all pseudo module, move all known test dirs to androidTest instead of main so that they are properly displayed when filtered. BUG=620034 Review-Url: https://codereview.chromium.org/2837863002 Cr-Commit-Position: refs/heads/master@{#467704}
This commit is contained in:
@ -4,7 +4,9 @@
|
||||
{% macro expand_sourceset(variables, prefix) %}
|
||||
{% if variables is defined %}
|
||||
{{ prefix }} {
|
||||
{% if variables.android_manifest is defined %}
|
||||
manifest.srcFile "{{ variables.android_manifest }}"
|
||||
{% endif %}
|
||||
{% if variables.java_dirs is defined %}
|
||||
java.srcDirs = [
|
||||
{% for path in variables.java_dirs %}
|
||||
|
@ -199,6 +199,9 @@ class _ProjectEntry(object):
|
||||
"""Returns the target type from its .build_config."""
|
||||
return self.DepsInfo()['type']
|
||||
|
||||
def IsValid(self):
|
||||
return self.GetType() in ('android_apk', 'java_library', 'java_binary')
|
||||
|
||||
def ResZips(self):
|
||||
return self.DepsInfo().get('owned_resources_zips', [])
|
||||
|
||||
@ -545,6 +548,13 @@ def _GenerateGradleFile(entry, generator, build_vars, source_properties,
|
||||
_TemplatePath(target_type.split('_')[0]), variables)
|
||||
|
||||
|
||||
def _IsTestDir(path):
|
||||
return ('javatests/' in path or
|
||||
'junit/' in path or
|
||||
'test/' in path or
|
||||
'testing/' in path)
|
||||
|
||||
|
||||
def _GenerateModuleAll(gradle_output_dir, generator, build_vars,
|
||||
source_properties, jinja_processor):
|
||||
"""Returns the data for a pseudo build.gradle of all dirs.
|
||||
@ -558,12 +568,18 @@ def _GenerateModuleAll(gradle_output_dir, generator, build_vars,
|
||||
prebuilts = sorted(generator.processed_prebuilts)
|
||||
def Relativize(paths):
|
||||
return _RebasePath(paths, os.path.join(gradle_output_dir, _MODULE_ALL))
|
||||
main_java_dirs = [d for d in java_dirs if not _IsTestDir(d)]
|
||||
test_java_dirs = [d for d in java_dirs if _IsTestDir(d)]
|
||||
variables['main'] = {
|
||||
'android_manifest': Relativize(_DEFAULT_ANDROID_MANIFEST_PATH),
|
||||
'java_dirs': Relativize(java_dirs),
|
||||
'java_dirs': Relativize(main_java_dirs),
|
||||
'prebuilts': Relativize(prebuilts),
|
||||
'java_excludes': ['**/*.java'],
|
||||
}
|
||||
variables['android_test'] = {
|
||||
'java_dirs': Relativize(test_java_dirs),
|
||||
'java_excludes': ['**/*.java'],
|
||||
}
|
||||
data = jinja_processor.Render(
|
||||
_TemplatePath(target_type.split('_')[0]), variables)
|
||||
_WriteFile(
|
||||
@ -575,7 +591,7 @@ def _GenerateRootGradle(jinja_processor):
|
||||
return jinja_processor.Render(_TemplatePath('root'))
|
||||
|
||||
|
||||
def _GenerateSettingsGradle(project_entries):
|
||||
def _GenerateSettingsGradle(project_entries, add_all_module):
|
||||
"""Returns the data for settings.gradle."""
|
||||
project_name = os.path.basename(os.path.dirname(host_paths.DIR_SOURCE_ROOT))
|
||||
lines = []
|
||||
@ -584,10 +600,11 @@ def _GenerateSettingsGradle(project_entries):
|
||||
lines.append('rootProject.projectDir = settingsDir')
|
||||
lines.append('')
|
||||
|
||||
lines.append('include ":{0}"'.format(_MODULE_ALL))
|
||||
lines.append(
|
||||
'project(":{0}").projectDir = new File(settingsDir, "{0}")'.format(
|
||||
_MODULE_ALL))
|
||||
if add_all_module:
|
||||
lines.append('include ":{0}"'.format(_MODULE_ALL))
|
||||
lines.append(
|
||||
'project(":{0}").projectDir = new File(settingsDir, "{0}")'.format(
|
||||
_MODULE_ALL))
|
||||
for entry in project_entries:
|
||||
# Example target: android_webview:android_webview_java__build_config
|
||||
lines.append('include ":%s"' % entry.ProjectName())
|
||||
@ -697,7 +714,6 @@ def main():
|
||||
devil_chromium.Initialize(output_directory=output_dir)
|
||||
run_tests_helper.SetLogLevel(args.verbose_count)
|
||||
|
||||
# TODO(wnwen): Fix packaging so that gradle resources work in this case.
|
||||
if args.split_projects:
|
||||
assert not args.use_gradle_process_resources, (
|
||||
'Gradle resources does not work without --split-projects.')
|
||||
@ -743,21 +759,22 @@ def main():
|
||||
if args.split_projects:
|
||||
main_entries = _FindAllProjectEntries(main_entries)
|
||||
logging.info('Found %d dependent build_config targets.', len(main_entries))
|
||||
entries = _CombineTestEntries(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:
|
||||
if entry.GetType() not in ('android_apk', 'java_library', 'java_binary'):
|
||||
continue
|
||||
|
||||
data = _GenerateGradleFile(entry, generator, build_vars, source_properties,
|
||||
jinja_processor)
|
||||
if data:
|
||||
project_entries.append(entry)
|
||||
# Build all paths references by .gradle that exist within output_dir.
|
||||
generated_inputs.extend(generator.GeneratedInputs(entry))
|
||||
zip_tuples.extend(
|
||||
@ -766,18 +783,21 @@ def main():
|
||||
zip_tuples.extend(
|
||||
(s, os.path.join(generator.EntryOutputDir(entry), _RES_SUBDIR))
|
||||
for s in generator.AllResZips(entry))
|
||||
_WriteFile(
|
||||
os.path.join(generator.EntryOutputDir(entry), _GRADLE_BUILD_FILE),
|
||||
data)
|
||||
if not add_all_module:
|
||||
project_entries.append(entry)
|
||||
_WriteFile(
|
||||
os.path.join(generator.EntryOutputDir(entry), _GRADLE_BUILD_FILE),
|
||||
data)
|
||||
|
||||
_GenerateModuleAll(_gradle_output_dir, generator, build_vars,
|
||||
source_properties, jinja_processor)
|
||||
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))
|
||||
_GenerateSettingsGradle(project_entries, add_all_module))
|
||||
|
||||
sdk_path = _RebasePath(build_vars['android_sdk_root'])
|
||||
_WriteFile(os.path.join(generator.project_dir, 'local.properties'),
|
||||
@ -791,7 +811,7 @@ def main():
|
||||
if zip_tuples:
|
||||
_ExtractZips(generator.project_dir, zip_tuples)
|
||||
|
||||
logging.warning('Project created! (%d subprojects)', len(project_entries))
|
||||
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')
|
||||
|
@ -24,12 +24,6 @@ projects for:
|
||||
build/android/gradle/generate_gradle.py --extra-target //chrome/android:chrome_public_apk
|
||||
```
|
||||
|
||||
For those upgrading from Android Studio 2.2 to 2.3:
|
||||
|
||||
* Use `gn clean` and `gn gen`
|
||||
* Clean up in `//third_party/android_tools` with `git clean -ffd`.
|
||||
* Remove project from android studio and regenerate with `generate_gradle.py`.
|
||||
|
||||
For first-time Android Studio users:
|
||||
|
||||
* Avoid running the setup wizard.
|
||||
@ -37,6 +31,12 @@ For first-time Android Studio users:
|
||||
`//third_party/android_tools`.
|
||||
* To skip it, select "Cancel" when it comes up.
|
||||
|
||||
For those upgrading from Android Studio 2.2 to 2.3:
|
||||
|
||||
* Use `gn clean` and `gn gen`
|
||||
* Clean up in `//third_party/android_tools` with `git clean -ffd`.
|
||||
* Remove project from android studio and regenerate with `generate_gradle.py`.
|
||||
|
||||
To import the project:
|
||||
|
||||
* Use "Import Project", and select the directory containing the generated
|
||||
@ -52,9 +52,14 @@ You need to re-run `generate_gradle.py` whenever `BUILD.gn` files change.
|
||||
|
||||
## How It Works
|
||||
|
||||
Android Studio integration works by generating `build.gradle` files based on GN
|
||||
targets. Each valid target produces a separate Gradle sub-project.
|
||||
Instrumentation tests are combined with their `apk_under_test`.
|
||||
By default, only a single module is generated. If more than one apk target is
|
||||
specified, then an `_all` module is generated. Otherwise a single apk module is
|
||||
generated. Since instrumentation tests are combined with their `apk_under_test`
|
||||
target, they count as one module together.
|
||||
|
||||
To see more detailed structure of gn targets, the `--split-projects` flag can
|
||||
be used. This will generate one module for every gn target in the dependency
|
||||
graph.
|
||||
|
||||
### Excluded Files
|
||||
|
||||
@ -127,7 +132,7 @@ resources, native libraries, etc.
|
||||
* Add the line `org.gradle.daemon=true` to `~/.gradle/gradle.properties`,
|
||||
creating it if necessary.
|
||||
|
||||
## Status (as of April 19th, 2017)
|
||||
## Status (as of April 27th, 2017)
|
||||
|
||||
### What works
|
||||
|
||||
@ -139,6 +144,7 @@ resources, native libraries, etc.
|
||||
* Java debugging (see
|
||||
[here](/docs/android_debugging_instructions.md#Android-Studio)).
|
||||
* Import resolution and refactoring across all modules.
|
||||
* Correct lint and AndroidManifest when only one target is specified.
|
||||
|
||||
### What doesn't work (yet) ([crbug](https://bugs.chromium.org/p/chromium/issues/detail?id=620034))
|
||||
|
||||
|
Reference in New Issue
Block a user