| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright 2016 The Chromium Authors. All rights reserved. | 2 # Copyright 2016 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Generates an Android Studio project from a GN target.""" | 6 """Generates an Android Studio project from a GN target.""" |
| 7 | 7 |
| 8 import argparse | 8 import argparse |
| 9 import codecs | 9 import codecs |
| 10 import glob | 10 import glob |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 def Gradle(self): | 192 def Gradle(self): |
| 193 return self.BuildConfig()['gradle'] | 193 return self.BuildConfig()['gradle'] |
| 194 | 194 |
| 195 def Javac(self): | 195 def Javac(self): |
| 196 return self.BuildConfig()['javac'] | 196 return self.BuildConfig()['javac'] |
| 197 | 197 |
| 198 def GetType(self): | 198 def GetType(self): |
| 199 """Returns the target type from its .build_config.""" | 199 """Returns the target type from its .build_config.""" |
| 200 return self.DepsInfo()['type'] | 200 return self.DepsInfo()['type'] |
| 201 | 201 |
| 202 def IsValid(self): |
| 203 return self.GetType() in ('android_apk', 'java_library', 'java_binary') |
| 204 |
| 202 def ResZips(self): | 205 def ResZips(self): |
| 203 return self.DepsInfo().get('owned_resources_zips', []) | 206 return self.DepsInfo().get('owned_resources_zips', []) |
| 204 | 207 |
| 205 def ResDirs(self): | 208 def ResDirs(self): |
| 206 return self.DepsInfo().get('owned_resources_dirs', []) | 209 return self.DepsInfo().get('owned_resources_dirs', []) |
| 207 | 210 |
| 208 def JavaFiles(self): | 211 def JavaFiles(self): |
| 209 if self._java_files is None: | 212 if self._java_files is None: |
| 210 java_sources_file = self.Gradle().get('java_sources_file') | 213 java_sources_file = self.Gradle().get('java_sources_file') |
| 211 java_files = [] | 214 java_files = [] |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 538 entry.android_test_entry) | 541 entry.android_test_entry) |
| 539 for key, value in variables['android_test'].iteritems(): | 542 for key, value in variables['android_test'].iteritems(): |
| 540 if isinstance(value, list): | 543 if isinstance(value, list): |
| 541 variables['android_test'][key] = sorted( | 544 variables['android_test'][key] = sorted( |
| 542 set(value) - set(variables['main'][key])) | 545 set(value) - set(variables['main'][key])) |
| 543 | 546 |
| 544 return jinja_processor.Render( | 547 return jinja_processor.Render( |
| 545 _TemplatePath(target_type.split('_')[0]), variables) | 548 _TemplatePath(target_type.split('_')[0]), variables) |
| 546 | 549 |
| 547 | 550 |
| 551 def _IsTestDir(path): |
| 552 return ('javatests/' in path or |
| 553 'junit/' in path or |
| 554 'test/' in path or |
| 555 'testing/' in path) |
| 556 |
| 557 |
| 548 def _GenerateModuleAll(gradle_output_dir, generator, build_vars, | 558 def _GenerateModuleAll(gradle_output_dir, generator, build_vars, |
| 549 source_properties, jinja_processor): | 559 source_properties, jinja_processor): |
| 550 """Returns the data for a pseudo build.gradle of all dirs. | 560 """Returns the data for a pseudo build.gradle of all dirs. |
| 551 | 561 |
| 552 See //docs/android_studio.md for more details.""" | 562 See //docs/android_studio.md for more details.""" |
| 553 variables = _GenerateBaseVars(generator, build_vars, source_properties) | 563 variables = _GenerateBaseVars(generator, build_vars, source_properties) |
| 554 target_type = 'android_apk' | 564 target_type = 'android_apk' |
| 555 variables['target_name'] = _MODULE_ALL | 565 variables['target_name'] = _MODULE_ALL |
| 556 variables['template_type'] = target_type | 566 variables['template_type'] = target_type |
| 557 java_dirs = sorted(generator.processed_java_dirs) | 567 java_dirs = sorted(generator.processed_java_dirs) |
| 558 prebuilts = sorted(generator.processed_prebuilts) | 568 prebuilts = sorted(generator.processed_prebuilts) |
| 559 def Relativize(paths): | 569 def Relativize(paths): |
| 560 return _RebasePath(paths, os.path.join(gradle_output_dir, _MODULE_ALL)) | 570 return _RebasePath(paths, os.path.join(gradle_output_dir, _MODULE_ALL)) |
| 571 main_java_dirs = [d for d in java_dirs if not _IsTestDir(d)] |
| 572 test_java_dirs = [d for d in java_dirs if _IsTestDir(d)] |
| 561 variables['main'] = { | 573 variables['main'] = { |
| 562 'android_manifest': Relativize(_DEFAULT_ANDROID_MANIFEST_PATH), | 574 'android_manifest': Relativize(_DEFAULT_ANDROID_MANIFEST_PATH), |
| 563 'java_dirs': Relativize(java_dirs), | 575 'java_dirs': Relativize(main_java_dirs), |
| 564 'prebuilts': Relativize(prebuilts), | 576 'prebuilts': Relativize(prebuilts), |
| 565 'java_excludes': ['**/*.java'], | 577 'java_excludes': ['**/*.java'], |
| 566 } | 578 } |
| 579 variables['android_test'] = { |
| 580 'java_dirs': Relativize(test_java_dirs), |
| 581 'java_excludes': ['**/*.java'], |
| 582 } |
| 567 data = jinja_processor.Render( | 583 data = jinja_processor.Render( |
| 568 _TemplatePath(target_type.split('_')[0]), variables) | 584 _TemplatePath(target_type.split('_')[0]), variables) |
| 569 _WriteFile( | 585 _WriteFile( |
| 570 os.path.join(gradle_output_dir, _MODULE_ALL, _GRADLE_BUILD_FILE), data) | 586 os.path.join(gradle_output_dir, _MODULE_ALL, _GRADLE_BUILD_FILE), data) |
| 571 | 587 |
| 572 | 588 |
| 573 def _GenerateRootGradle(jinja_processor): | 589 def _GenerateRootGradle(jinja_processor): |
| 574 """Returns the data for the root project's build.gradle.""" | 590 """Returns the data for the root project's build.gradle.""" |
| 575 return jinja_processor.Render(_TemplatePath('root')) | 591 return jinja_processor.Render(_TemplatePath('root')) |
| 576 | 592 |
| 577 | 593 |
| 578 def _GenerateSettingsGradle(project_entries): | 594 def _GenerateSettingsGradle(project_entries, add_all_module): |
| 579 """Returns the data for settings.gradle.""" | 595 """Returns the data for settings.gradle.""" |
| 580 project_name = os.path.basename(os.path.dirname(host_paths.DIR_SOURCE_ROOT)) | 596 project_name = os.path.basename(os.path.dirname(host_paths.DIR_SOURCE_ROOT)) |
| 581 lines = [] | 597 lines = [] |
| 582 lines.append('// Generated by //build/android/gradle/generate_gradle.py') | 598 lines.append('// Generated by //build/android/gradle/generate_gradle.py') |
| 583 lines.append('rootProject.name = "%s"' % project_name) | 599 lines.append('rootProject.name = "%s"' % project_name) |
| 584 lines.append('rootProject.projectDir = settingsDir') | 600 lines.append('rootProject.projectDir = settingsDir') |
| 585 lines.append('') | 601 lines.append('') |
| 586 | 602 |
| 587 lines.append('include ":{0}"'.format(_MODULE_ALL)) | 603 if add_all_module: |
| 588 lines.append( | 604 lines.append('include ":{0}"'.format(_MODULE_ALL)) |
| 589 'project(":{0}").projectDir = new File(settingsDir, "{0}")'.format( | 605 lines.append( |
| 590 _MODULE_ALL)) | 606 'project(":{0}").projectDir = new File(settingsDir, "{0}")'.format( |
| 607 _MODULE_ALL)) |
| 591 for entry in project_entries: | 608 for entry in project_entries: |
| 592 # Example target: android_webview:android_webview_java__build_config | 609 # Example target: android_webview:android_webview_java__build_config |
| 593 lines.append('include ":%s"' % entry.ProjectName()) | 610 lines.append('include ":%s"' % entry.ProjectName()) |
| 594 lines.append('project(":%s").projectDir = new File(settingsDir, "%s")' % | 611 lines.append('project(":%s").projectDir = new File(settingsDir, "%s")' % |
| 595 (entry.ProjectName(), entry.GradleSubdir())) | 612 (entry.ProjectName(), entry.GradleSubdir())) |
| 596 return '\n'.join(lines) | 613 return '\n'.join(lines) |
| 597 | 614 |
| 598 | 615 |
| 599 def _ExtractFile(zip_path, extracted_path): | 616 def _ExtractFile(zip_path, extracted_path): |
| 600 logging.info('Extracting %s to %s', zip_path, extracted_path) | 617 logging.info('Extracting %s to %s', zip_path, extracted_path) |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 help='Split projects by their gn deps rather than ' | 707 help='Split projects by their gn deps rather than ' |
| 691 'combining all the dependencies of each target') | 708 'combining all the dependencies of each target') |
| 692 args = parser.parse_args() | 709 args = parser.parse_args() |
| 693 if args.output_directory: | 710 if args.output_directory: |
| 694 constants.SetOutputDirectory(args.output_directory) | 711 constants.SetOutputDirectory(args.output_directory) |
| 695 constants.CheckOutputDirectory() | 712 constants.CheckOutputDirectory() |
| 696 output_dir = constants.GetOutDirectory() | 713 output_dir = constants.GetOutDirectory() |
| 697 devil_chromium.Initialize(output_directory=output_dir) | 714 devil_chromium.Initialize(output_directory=output_dir) |
| 698 run_tests_helper.SetLogLevel(args.verbose_count) | 715 run_tests_helper.SetLogLevel(args.verbose_count) |
| 699 | 716 |
| 700 # TODO(wnwen): Fix packaging so that gradle resources work in this case. | |
| 701 if args.split_projects: | 717 if args.split_projects: |
| 702 assert not args.use_gradle_process_resources, ( | 718 assert not args.use_gradle_process_resources, ( |
| 703 'Gradle resources does not work without --split-projects.') | 719 'Gradle resources does not work without --split-projects.') |
| 704 | 720 |
| 705 _gradle_output_dir = os.path.abspath( | 721 _gradle_output_dir = os.path.abspath( |
| 706 args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir)) | 722 args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir)) |
| 707 jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) | 723 jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) |
| 708 build_vars = _ReadPropertiesFile(os.path.join(output_dir, 'build_vars.txt')) | 724 build_vars = _ReadPropertiesFile(os.path.join(output_dir, 'build_vars.txt')) |
| 709 source_properties = _ReadPropertiesFile( | 725 source_properties = _ReadPropertiesFile( |
| 710 _RebasePath(os.path.join(build_vars['android_sdk_build_tools'], | 726 _RebasePath(os.path.join(build_vars['android_sdk_build_tools'], |
| (...skipping 25 matching lines...) Expand all Loading... |
| 736 # when using --all. | 752 # when using --all. |
| 737 if args.all: | 753 if args.all: |
| 738 main_entries = [e for e in main_entries if ( | 754 main_entries = [e for e in main_entries if ( |
| 739 e.GetType() == 'android_apk' or | 755 e.GetType() == 'android_apk' or |
| 740 e.GnTarget().endswith('_test_apk__apk') or | 756 e.GnTarget().endswith('_test_apk__apk') or |
| 741 e.GnTarget().endswith('_junit_tests__java_binary'))] | 757 e.GnTarget().endswith('_junit_tests__java_binary'))] |
| 742 | 758 |
| 743 if args.split_projects: | 759 if args.split_projects: |
| 744 main_entries = _FindAllProjectEntries(main_entries) | 760 main_entries = _FindAllProjectEntries(main_entries) |
| 745 logging.info('Found %d dependent build_config targets.', len(main_entries)) | 761 logging.info('Found %d dependent build_config targets.', len(main_entries)) |
| 746 entries = _CombineTestEntries(main_entries) | 762 |
| 763 entries = [e for e in _CombineTestEntries(main_entries) if e.IsValid()] |
| 747 logging.info('Creating %d projects for targets.', len(entries)) | 764 logging.info('Creating %d projects for targets.', len(entries)) |
| 748 | 765 |
| 766 # When only one entry will be generated we want it to have a valid |
| 767 # build.gradle file with its own AndroidManifest. |
| 768 add_all_module = not args.split_projects and len(entries) > 1 |
| 769 |
| 749 logging.warning('Writing .gradle files...') | 770 logging.warning('Writing .gradle files...') |
| 750 project_entries = [] | 771 project_entries = [] |
| 751 zip_tuples = [] | 772 zip_tuples = [] |
| 752 generated_inputs = [] | 773 generated_inputs = [] |
| 753 for entry in entries: | 774 for entry in entries: |
| 754 if entry.GetType() not in ('android_apk', 'java_library', 'java_binary'): | |
| 755 continue | |
| 756 | |
| 757 data = _GenerateGradleFile(entry, generator, build_vars, source_properties, | 775 data = _GenerateGradleFile(entry, generator, build_vars, source_properties, |
| 758 jinja_processor) | 776 jinja_processor) |
| 759 if data: | 777 if data: |
| 760 project_entries.append(entry) | |
| 761 # Build all paths references by .gradle that exist within output_dir. | 778 # Build all paths references by .gradle that exist within output_dir. |
| 762 generated_inputs.extend(generator.GeneratedInputs(entry)) | 779 generated_inputs.extend(generator.GeneratedInputs(entry)) |
| 763 zip_tuples.extend( | 780 zip_tuples.extend( |
| 764 (s, os.path.join(generator.EntryOutputDir(entry), _SRCJARS_SUBDIR)) | 781 (s, os.path.join(generator.EntryOutputDir(entry), _SRCJARS_SUBDIR)) |
| 765 for s in generator.AllSrcjars(entry)) | 782 for s in generator.AllSrcjars(entry)) |
| 766 zip_tuples.extend( | 783 zip_tuples.extend( |
| 767 (s, os.path.join(generator.EntryOutputDir(entry), _RES_SUBDIR)) | 784 (s, os.path.join(generator.EntryOutputDir(entry), _RES_SUBDIR)) |
| 768 for s in generator.AllResZips(entry)) | 785 for s in generator.AllResZips(entry)) |
| 769 _WriteFile( | 786 if not add_all_module: |
| 770 os.path.join(generator.EntryOutputDir(entry), _GRADLE_BUILD_FILE), | 787 project_entries.append(entry) |
| 771 data) | 788 _WriteFile( |
| 789 os.path.join(generator.EntryOutputDir(entry), _GRADLE_BUILD_FILE), |
| 790 data) |
| 772 | 791 |
| 773 _GenerateModuleAll(_gradle_output_dir, generator, build_vars, | 792 if add_all_module: |
| 774 source_properties, jinja_processor) | 793 _GenerateModuleAll(_gradle_output_dir, generator, build_vars, |
| 794 source_properties, jinja_processor) |
| 775 | 795 |
| 776 _WriteFile(os.path.join(generator.project_dir, _GRADLE_BUILD_FILE), | 796 _WriteFile(os.path.join(generator.project_dir, _GRADLE_BUILD_FILE), |
| 777 _GenerateRootGradle(jinja_processor)) | 797 _GenerateRootGradle(jinja_processor)) |
| 778 | 798 |
| 779 _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), | 799 _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), |
| 780 _GenerateSettingsGradle(project_entries)) | 800 _GenerateSettingsGradle(project_entries, add_all_module)) |
| 781 | 801 |
| 782 sdk_path = _RebasePath(build_vars['android_sdk_root']) | 802 sdk_path = _RebasePath(build_vars['android_sdk_root']) |
| 783 _WriteFile(os.path.join(generator.project_dir, 'local.properties'), | 803 _WriteFile(os.path.join(generator.project_dir, 'local.properties'), |
| 784 _GenerateLocalProperties(sdk_path)) | 804 _GenerateLocalProperties(sdk_path)) |
| 785 | 805 |
| 786 if generated_inputs: | 806 if generated_inputs: |
| 787 logging.warning('Building generated source files...') | 807 logging.warning('Building generated source files...') |
| 788 targets = _RebasePath(generated_inputs, output_dir) | 808 targets = _RebasePath(generated_inputs, output_dir) |
| 789 _RunNinja(output_dir, targets) | 809 _RunNinja(output_dir, targets) |
| 790 | 810 |
| 791 if zip_tuples: | 811 if zip_tuples: |
| 792 _ExtractZips(generator.project_dir, zip_tuples) | 812 _ExtractZips(generator.project_dir, zip_tuples) |
| 793 | 813 |
| 794 logging.warning('Project created! (%d subprojects)', len(project_entries)) | 814 logging.warning('Project created!') |
| 795 logging.warning('Generated projects work with Android Studio 2.3') | 815 logging.warning('Generated projects work with Android Studio 2.3') |
| 796 logging.warning('For more tips: https://chromium.googlesource.com/chromium' | 816 logging.warning('For more tips: https://chromium.googlesource.com/chromium' |
| 797 '/src.git/+/master/docs/android_studio.md') | 817 '/src.git/+/master/docs/android_studio.md') |
| 798 | 818 |
| 799 | 819 |
| 800 if __name__ == '__main__': | 820 if __name__ == '__main__': |
| 801 main() | 821 main() |
| OLD | NEW |