| 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 16 matching lines...) Expand all  Loading... | 
| 27 import jinja_template | 27 import jinja_template | 
| 28 from util import build_utils | 28 from util import build_utils | 
| 29 | 29 | 
| 30 | 30 | 
| 31 _DEFAULT_ANDROID_MANIFEST_PATH = os.path.join( | 31 _DEFAULT_ANDROID_MANIFEST_PATH = os.path.join( | 
| 32     host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'AndroidManifest.xml') | 32     host_paths.DIR_SOURCE_ROOT, 'build', 'android', 'AndroidManifest.xml') | 
| 33 _FILE_DIR = os.path.dirname(__file__) | 33 _FILE_DIR = os.path.dirname(__file__) | 
| 34 _SRCJARS_SUBDIR = 'extracted-srcjars' | 34 _SRCJARS_SUBDIR = 'extracted-srcjars' | 
| 35 _JNI_LIBS_SUBDIR = 'symlinked-libs' | 35 _JNI_LIBS_SUBDIR = 'symlinked-libs' | 
| 36 _ARMEABI_SUBDIR = 'armeabi' | 36 _ARMEABI_SUBDIR = 'armeabi' | 
|  | 37 _RES_SUBDIR = 'extracted-res' | 
| 37 | 38 | 
| 38 _DEFAULT_TARGETS = [ | 39 _DEFAULT_TARGETS = [ | 
| 39     # TODO(agrieve): Requires alternate android.jar to compile. | 40     # TODO(agrieve): Requires alternate android.jar to compile. | 
| 40     # '//android_webview:system_webview_apk', | 41     # '//android_webview:system_webview_apk', | 
| 41     '//android_webview/test:android_webview_apk', | 42     '//android_webview/test:android_webview_apk', | 
| 42     '//android_webview/test:android_webview_test_apk', | 43     '//android_webview/test:android_webview_test_apk', | 
| 43     '//base:base_junit_tests', | 44     '//base:base_junit_tests', | 
| 44     '//chrome/android:chrome_junit_tests', | 45     '//chrome/android:chrome_junit_tests', | 
| 45     '//chrome/android:chrome_public_apk', | 46     '//chrome/android:chrome_public_apk', | 
| 46     '//chrome/android:chrome_public_test_apk', | 47     '//chrome/android:chrome_public_test_apk', | 
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 169   def DepsInfo(self): | 170   def DepsInfo(self): | 
| 170     return self.BuildConfig()['deps_info'] | 171     return self.BuildConfig()['deps_info'] | 
| 171 | 172 | 
| 172   def Gradle(self): | 173   def Gradle(self): | 
| 173     return self.BuildConfig()['gradle'] | 174     return self.BuildConfig()['gradle'] | 
| 174 | 175 | 
| 175   def GetType(self): | 176   def GetType(self): | 
| 176     """Returns the target type from its .build_config.""" | 177     """Returns the target type from its .build_config.""" | 
| 177     return self.DepsInfo()['type'] | 178     return self.DepsInfo()['type'] | 
| 178 | 179 | 
|  | 180   def ResZips(self): | 
|  | 181     return self.DepsInfo().get('owned_resources_zips') | 
|  | 182 | 
| 179   def JavaFiles(self): | 183   def JavaFiles(self): | 
| 180     if self._java_files is None: | 184     if self._java_files is None: | 
| 181       java_sources_file = self.Gradle().get('java_sources_file') | 185       java_sources_file = self.Gradle().get('java_sources_file') | 
| 182       java_files = [] | 186       java_files = [] | 
| 183       if java_sources_file: | 187       if java_sources_file: | 
| 184         java_sources_file = _RebasePath(java_sources_file) | 188         java_sources_file = _RebasePath(java_sources_file) | 
| 185         java_files = build_utils.ReadSourcesList(java_sources_file) | 189         java_files = build_utils.ReadSourcesList(java_sources_file) | 
| 186       self._java_files = java_files | 190       self._java_files = java_files | 
| 187     return self._java_files | 191     return self._java_files | 
| 188 | 192 | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 204     return jni_libs | 208     return jni_libs | 
| 205 | 209 | 
| 206   def _GenJavaDirs(self, entry): | 210   def _GenJavaDirs(self, entry): | 
| 207     java_dirs, excludes = _CreateJavaSourceDir( | 211     java_dirs, excludes = _CreateJavaSourceDir( | 
| 208         constants.GetOutDirectory(), entry.JavaFiles()) | 212         constants.GetOutDirectory(), entry.JavaFiles()) | 
| 209     if self.Srcjars(entry): | 213     if self.Srcjars(entry): | 
| 210       java_dirs.append( | 214       java_dirs.append( | 
| 211           os.path.join(self.EntryOutputDir(entry), _SRCJARS_SUBDIR)) | 215           os.path.join(self.EntryOutputDir(entry), _SRCJARS_SUBDIR)) | 
| 212     return java_dirs, excludes | 216     return java_dirs, excludes | 
| 213 | 217 | 
|  | 218   def _GenResDirs(self, entry): | 
|  | 219     res_dirs = list(entry.DepsInfo().get('owned_resources_dirs', [])) | 
|  | 220     if entry.ResZips(): | 
|  | 221       res_dirs.append(os.path.join(self.EntryOutputDir(entry), _RES_SUBDIR)) | 
|  | 222     return res_dirs | 
|  | 223 | 
| 214   def _Relativize(self, entry, paths): | 224   def _Relativize(self, entry, paths): | 
| 215     return _RebasePath(paths, self.EntryOutputDir(entry)) | 225     return _RebasePath(paths, self.EntryOutputDir(entry)) | 
| 216 | 226 | 
| 217   def EntryOutputDir(self, entry): | 227   def EntryOutputDir(self, entry): | 
| 218     return os.path.join(self.project_dir, entry.GradleSubdir()) | 228     return os.path.join(self.project_dir, entry.GradleSubdir()) | 
| 219 | 229 | 
| 220   def Srcjars(self, entry): | 230   def Srcjars(self, entry): | 
| 221     srcjars = _RebasePath(entry.Gradle().get('bundled_srcjars', [])) | 231     srcjars = _RebasePath(entry.Gradle().get('bundled_srcjars', [])) | 
| 222     if not self.use_gradle_process_resources: | 232     if not self.use_gradle_process_resources: | 
| 223       srcjars += _RebasePath(entry.BuildConfig()['javac']['srcjars']) | 233       srcjars += _RebasePath(entry.BuildConfig()['javac']['srcjars']) | 
| 224     return srcjars | 234     return srcjars | 
| 225 | 235 | 
| 226   def GeneratedInputs(self, entry): | 236   def GeneratedInputs(self, entry): | 
| 227     generated_inputs = [] | 237     generated_inputs = [] | 
| 228     generated_inputs.extend(self.Srcjars(entry)) | 238     generated_inputs.extend(self.Srcjars(entry)) | 
|  | 239     generated_inputs.extend(_RebasePath(entry.ResZips())) | 
| 229     generated_inputs.extend( | 240     generated_inputs.extend( | 
| 230         p for p in entry.JavaFiles() if not p.startswith('..')) | 241         p for p in entry.JavaFiles() if not p.startswith('..')) | 
| 231     generated_inputs.extend(entry.Gradle()['dependent_prebuilt_jars']) | 242     generated_inputs.extend(entry.Gradle()['dependent_prebuilt_jars']) | 
| 232     return generated_inputs | 243     return generated_inputs | 
| 233 | 244 | 
| 234   def Generate(self, entry): | 245   def Generate(self, entry): | 
| 235     variables = {} | 246     variables = {} | 
| 236     android_test_manifest = entry.Gradle().get( | 247     android_test_manifest = entry.Gradle().get( | 
| 237         'android_manifest', _DEFAULT_ANDROID_MANIFEST_PATH) | 248         'android_manifest', _DEFAULT_ANDROID_MANIFEST_PATH) | 
| 238     variables['android_manifest'] = self._Relativize( | 249     variables['android_manifest'] = self._Relativize( | 
| 239         entry, android_test_manifest) | 250         entry, android_test_manifest) | 
| 240     java_dirs, excludes = self._GenJavaDirs(entry) | 251     java_dirs, excludes = self._GenJavaDirs(entry) | 
| 241     variables['java_dirs'] = self._Relativize(entry, java_dirs) | 252     variables['java_dirs'] = self._Relativize(entry, java_dirs) | 
| 242     variables['java_excludes'] = excludes | 253     variables['java_excludes'] = excludes | 
| 243     variables['jni_libs'] = self._Relativize(entry, self._GenJniLibs(entry)) | 254     variables['jni_libs'] = self._Relativize(entry, self._GenJniLibs(entry)) | 
|  | 255     variables['res_dirs'] = self._Relativize(entry, self._GenResDirs(entry)) | 
| 244     deps = [_ProjectEntry.FromBuildConfigPath(p) | 256     deps = [_ProjectEntry.FromBuildConfigPath(p) | 
| 245             for p in entry.Gradle()['dependent_android_projects']] | 257             for p in entry.Gradle()['dependent_android_projects']] | 
| 246     variables['android_project_deps'] = [d.ProjectName() for d in deps] | 258     variables['android_project_deps'] = [d.ProjectName() for d in deps] | 
| 247     # TODO(agrieve): Add an option to use interface jars and see if that speeds | 259     # TODO(agrieve): Add an option to use interface jars and see if that speeds | 
| 248     # things up at all. | 260     # things up at all. | 
| 249     variables['prebuilts'] = self._Relativize( | 261     variables['prebuilts'] = self._Relativize( | 
| 250         entry, entry.Gradle()['dependent_prebuilt_jars']) | 262         entry, entry.Gradle()['dependent_prebuilt_jars']) | 
| 251     deps = [_ProjectEntry.FromBuildConfigPath(p) | 263     deps = [_ProjectEntry.FromBuildConfigPath(p) | 
| 252             for p in entry.Gradle()['dependent_java_projects']] | 264             for p in entry.Gradle()['dependent_java_projects']] | 
| 253     variables['java_project_deps'] = [d.ProjectName() for d in deps] | 265     variables['java_project_deps'] = [d.ProjectName() for d in deps] | 
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 429   lines.append('') | 441   lines.append('') | 
| 430 | 442 | 
| 431   for entry in project_entries: | 443   for entry in project_entries: | 
| 432     # Example target: android_webview:android_webview_java__build_config | 444     # Example target: android_webview:android_webview_java__build_config | 
| 433     lines.append('include ":%s"' % entry.ProjectName()) | 445     lines.append('include ":%s"' % entry.ProjectName()) | 
| 434     lines.append('project(":%s").projectDir = new File(settingsDir, "%s")' % | 446     lines.append('project(":%s").projectDir = new File(settingsDir, "%s")' % | 
| 435                  (entry.ProjectName(), entry.GradleSubdir())) | 447                  (entry.ProjectName(), entry.GradleSubdir())) | 
| 436   return '\n'.join(lines) | 448   return '\n'.join(lines) | 
| 437 | 449 | 
| 438 | 450 | 
| 439 def _ExtractSrcjars(entry_output_dir, srcjar_tuples): | 451 def _ExtractFile(zip_path, extracted_path): | 
|  | 452   logging.info('Extracting %s to %s', zip_path, extracted_path) | 
|  | 453   with zipfile.ZipFile(zip_path) as z: | 
|  | 454     z.extractall(extracted_path) | 
|  | 455 | 
|  | 456 | 
|  | 457 def _ExtractZips(entry_output_dir, zip_tuples): | 
| 440   """Extracts all srcjars to the directory given by the tuples.""" | 458   """Extracts all srcjars to the directory given by the tuples.""" | 
| 441   extracted_paths = set(s[1] for s in srcjar_tuples) | 459   extracted_paths = set(s[1] for s in zip_tuples) | 
| 442   for extracted_path in extracted_paths: | 460   for extracted_path in extracted_paths: | 
| 443     assert _IsSubpathOf(extracted_path, entry_output_dir) | 461     assert _IsSubpathOf(extracted_path, entry_output_dir) | 
| 444     shutil.rmtree(extracted_path, True) | 462     shutil.rmtree(extracted_path, True) | 
| 445 | 463 | 
| 446   for srcjar_path, extracted_path in srcjar_tuples: | 464   for zip_path, extracted_path in zip_tuples: | 
| 447     logging.info('Extracting %s to %s', srcjar_path, extracted_path) | 465     _ExtractFile(zip_path, extracted_path) | 
| 448     with zipfile.ZipFile(srcjar_path) as z: |  | 
| 449       z.extractall(extracted_path) |  | 
| 450 | 466 | 
| 451 | 467 | 
| 452 def _FindAllProjectEntries(main_entries): | 468 def _FindAllProjectEntries(main_entries): | 
| 453   """Returns the list of all _ProjectEntry instances given the root project.""" | 469   """Returns the list of all _ProjectEntry instances given the root project.""" | 
| 454   found = set() | 470   found = set() | 
| 455   to_scan = list(main_entries) | 471   to_scan = list(main_entries) | 
| 456   while to_scan: | 472   while to_scan: | 
| 457     cur_entry = to_scan.pop() | 473     cur_entry = to_scan.pop() | 
| 458     if cur_entry in found: | 474     if cur_entry in found: | 
| 459       continue | 475       continue | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 554 | 570 | 
| 555   all_entries = _FindAllProjectEntries(main_entries) | 571   all_entries = _FindAllProjectEntries(main_entries) | 
| 556   logging.info('Found %d dependent build_config targets.', len(all_entries)) | 572   logging.info('Found %d dependent build_config targets.', len(all_entries)) | 
| 557   entries = _CombineTestEntries(all_entries) | 573   entries = _CombineTestEntries(all_entries) | 
| 558   logging.info('Creating %d projects for targets.', len(entries)) | 574   logging.info('Creating %d projects for targets.', len(entries)) | 
| 559 | 575 | 
| 560   logging.warning('Writing .gradle files...') | 576   logging.warning('Writing .gradle files...') | 
| 561   jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) | 577   jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) | 
| 562   build_vars = _ReadBuildVars(output_dir) | 578   build_vars = _ReadBuildVars(output_dir) | 
| 563   project_entries = [] | 579   project_entries = [] | 
| 564   srcjar_tuples = [] | 580   zip_tuples = [] | 
| 565   generated_inputs = [] | 581   generated_inputs = [] | 
| 566   for entry in entries: | 582   for entry in entries: | 
| 567     if entry.GetType() not in ('android_apk', 'java_library', 'java_binary'): | 583     if entry.GetType() not in ('android_apk', 'java_library', 'java_binary'): | 
| 568       continue | 584       continue | 
| 569 | 585 | 
| 570     data = _GenerateGradleFile(entry, generator, build_vars, jinja_processor) | 586     data = _GenerateGradleFile(entry, generator, build_vars, jinja_processor) | 
| 571     if data: | 587     if data: | 
| 572       project_entries.append(entry) | 588       project_entries.append(entry) | 
| 573       # Build all paths references by .gradle that exist within output_dir. | 589       # Build all paths references by .gradle that exist within output_dir. | 
| 574       generated_inputs.extend(generator.GeneratedInputs(entry)) | 590       generated_inputs.extend(generator.GeneratedInputs(entry)) | 
| 575       srcjar_tuples.extend( | 591       zip_tuples.extend( | 
| 576           (s, os.path.join(generator.EntryOutputDir(entry), _SRCJARS_SUBDIR)) | 592           (s, os.path.join(generator.EntryOutputDir(entry), _SRCJARS_SUBDIR)) | 
| 577           for s in generator.Srcjars(entry)) | 593           for s in generator.Srcjars(entry)) | 
|  | 594       zip_tuples.extend( | 
|  | 595           (s, os.path.join(generator.EntryOutputDir(entry), _RES_SUBDIR)) | 
|  | 596           for s in _RebasePath(entry.ResZips())) | 
| 578       _WriteFile( | 597       _WriteFile( | 
| 579           os.path.join(generator.EntryOutputDir(entry), 'build.gradle'), data) | 598           os.path.join(generator.EntryOutputDir(entry), 'build.gradle'), data) | 
| 580 | 599 | 
| 581   _WriteFile(os.path.join(generator.project_dir, 'build.gradle'), | 600   _WriteFile(os.path.join(generator.project_dir, 'build.gradle'), | 
| 582              _GenerateRootGradle(jinja_processor)) | 601              _GenerateRootGradle(jinja_processor)) | 
| 583 | 602 | 
| 584   _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), | 603   _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), | 
| 585              _GenerateSettingsGradle(project_entries)) | 604              _GenerateSettingsGradle(project_entries)) | 
| 586 | 605 | 
| 587   sdk_path = _RebasePath(build_vars['android_sdk_root']) | 606   sdk_path = _RebasePath(build_vars['android_sdk_root']) | 
| 588   _WriteFile(os.path.join(generator.project_dir, 'local.properties'), | 607   _WriteFile(os.path.join(generator.project_dir, 'local.properties'), | 
| 589              _GenerateLocalProperties(sdk_path)) | 608              _GenerateLocalProperties(sdk_path)) | 
| 590 | 609 | 
| 591   if generated_inputs: | 610   if generated_inputs: | 
| 592     logging.warning('Building generated source files...') | 611     logging.warning('Building generated source files...') | 
| 593     targets = _RebasePath(generated_inputs, output_dir) | 612     targets = _RebasePath(generated_inputs, output_dir) | 
| 594     _RunNinja(output_dir, targets) | 613     _RunNinja(output_dir, targets) | 
| 595 | 614 | 
| 596   if srcjar_tuples: | 615   if zip_tuples: | 
| 597     _ExtractSrcjars(generator.project_dir, srcjar_tuples) | 616     _ExtractZips(generator.project_dir, zip_tuples) | 
| 598 | 617 | 
| 599   logging.warning('Project created! (%d subprojects)', len(project_entries)) | 618   logging.warning('Project created! (%d subprojects)', len(project_entries)) | 
| 600   logging.warning('Generated projects work best with Android Studio 2.2') | 619   logging.warning('Generated projects work best with Android Studio 2.2') | 
| 601   logging.warning('For more tips: https://chromium.googlesource.com/chromium' | 620   logging.warning('For more tips: https://chromium.googlesource.com/chromium' | 
| 602                   '/src.git/+/master/docs/android_studio.md') | 621                   '/src.git/+/master/docs/android_studio.md') | 
| 603 | 622 | 
| 604 | 623 | 
| 605 if __name__ == '__main__': | 624 if __name__ == '__main__': | 
| 606   main() | 625   main() | 
| OLD | NEW | 
|---|