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 collections | |
10 import glob | 11 import glob |
11 import logging | 12 import logging |
12 import os | 13 import os |
13 import re | 14 import re |
14 import shutil | 15 import shutil |
15 import subprocess | 16 import subprocess |
16 import sys | 17 import sys |
17 import zipfile | 18 import zipfile |
18 | 19 |
19 _BUILD_ANDROID = os.path.join(os.path.dirname(__file__), os.pardir) | 20 _BUILD_ANDROID = os.path.join(os.path.dirname(__file__), os.pardir) |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 return self.BuildConfig()['gradle'] | 191 return self.BuildConfig()['gradle'] |
191 | 192 |
192 def Javac(self): | 193 def Javac(self): |
193 return self.BuildConfig()['javac'] | 194 return self.BuildConfig()['javac'] |
194 | 195 |
195 def GetType(self): | 196 def GetType(self): |
196 """Returns the target type from its .build_config.""" | 197 """Returns the target type from its .build_config.""" |
197 return self.DepsInfo()['type'] | 198 return self.DepsInfo()['type'] |
198 | 199 |
199 def ResZips(self): | 200 def ResZips(self): |
200 return self.DepsInfo().get('owned_resources_zips') | 201 return self.DepsInfo().get('owned_resources_zips', []) |
202 | |
203 def ResDirs(self): | |
204 return self.DepsInfo().get('owned_resources_dirs', []) | |
201 | 205 |
202 def JavaFiles(self): | 206 def JavaFiles(self): |
203 if self._java_files is None: | 207 if self._java_files is None: |
204 java_sources_file = self.Gradle().get('java_sources_file') | 208 java_sources_file = self.Gradle().get('java_sources_file') |
205 java_files = [] | 209 java_files = [] |
206 if java_sources_file: | 210 if java_sources_file: |
207 java_sources_file = _RebasePath(java_sources_file) | 211 java_sources_file = _RebasePath(java_sources_file) |
208 java_files = build_utils.ReadSourcesList(java_sources_file) | 212 java_files = build_utils.ReadSourcesList(java_sources_file) |
209 self._java_files = java_files | 213 self._java_files = java_files |
210 return self._java_files | 214 return self._java_files |
211 | 215 |
212 def GeneratedJavaFiles(self): | 216 def GeneratedJavaFiles(self): |
213 return [p for p in self.JavaFiles() if not p.startswith('..')] | 217 return [p for p in self.JavaFiles() if not p.startswith('..')] |
214 | 218 |
215 def PrebuiltJars(self): | 219 def PrebuiltJars(self): |
216 return self.Gradle()['dependent_prebuilt_jars'] | 220 return self.Gradle().get('dependent_prebuilt_jars', []) |
217 | 221 |
218 def AllEntries(self): | 222 def AllEntries(self): |
219 """Returns a list of all entries that the current entry depends on. | 223 """Returns a list of all entries that the current entry depends on. |
220 | 224 |
221 This includes the entry itself to make iterating simpler.""" | 225 This includes the entry itself to make iterating simpler.""" |
222 if self._all_entries is None: | 226 if self._all_entries is None: |
223 logging.debug('Generating entries for %s', self.GnTarget()) | 227 logging.debug('Generating entries for %s', self.GnTarget()) |
224 deps = [_ProjectEntry.FromBuildConfigPath(p) | 228 deps = [_ProjectEntry.FromBuildConfigPath(p) |
225 for p in self.Gradle()['dependent_android_projects']] | 229 for p in self.Gradle()['dependent_android_projects']] |
226 deps.extend(_ProjectEntry.FromBuildConfigPath(p) | 230 deps.extend(_ProjectEntry.FromBuildConfigPath(p) |
227 for p in self.Gradle()['dependent_java_projects']) | 231 for p in self.Gradle()['dependent_java_projects']) |
228 all_entries = set() | 232 all_entries = set() |
229 for dep in deps: | 233 for dep in deps: |
230 all_entries.update(dep.AllEntries()) | 234 all_entries.update(dep.AllEntries()) |
231 all_entries.add(self) | 235 all_entries.add(self) |
232 self._all_entries = list(all_entries) | 236 self._all_entries = list(all_entries) |
233 return self._all_entries | 237 return self._all_entries |
234 | 238 |
235 | 239 |
236 class _ProjectContextGenerator(object): | 240 class _ProjectContextGenerator(object): |
237 """Helper class to generate gradle build files""" | 241 """Helper class to generate gradle build files""" |
238 def __init__(self, project_dir, build_vars, use_gradle_process_resources, | 242 def __init__(self, project_dir, build_vars, use_gradle_process_resources, |
239 jinja_processor): | 243 jinja_processor, split_projects): |
240 self.project_dir = project_dir | 244 self.project_dir = project_dir |
241 self.build_vars = build_vars | 245 self.build_vars = build_vars |
242 self.use_gradle_process_resources = use_gradle_process_resources | 246 self.use_gradle_process_resources = use_gradle_process_resources |
243 self.jinja_processor = jinja_processor | 247 self.jinja_processor = jinja_processor |
248 self.split_projects = split_projects | |
244 | 249 |
245 def _GenJniLibs(self, entry): | 250 def _GenJniLibs(self, root_entry): |
246 native_section = entry.BuildConfig().get('native') | 251 libraries = [] |
247 if native_section: | 252 for entry in self._GetEntries(root_entry): |
248 jni_libs = _CreateJniLibsDir( | 253 libraries += entry.BuildConfig().get('native', []) |
249 constants.GetOutDirectory(), self.EntryOutputDir(entry), | 254 if libraries: |
250 native_section.get('libraries')) | 255 return _CreateJniLibsDir(constants.GetOutDirectory(), |
251 else: | 256 self.EntryOutputDir(root_entry), libraries) |
252 jni_libs = [] | 257 return [] |
253 return jni_libs | |
254 | 258 |
255 def _GenJavaDirs(self, entry): | 259 def _GenJavaDirs(self, root_entry): |
260 java_files = [] | |
261 for entry in self._GetEntries(root_entry): | |
262 java_files += entry.JavaFiles() | |
256 java_dirs, excludes = _ComputeJavaSourceDirsAndExcludes( | 263 java_dirs, excludes = _ComputeJavaSourceDirsAndExcludes( |
257 constants.GetOutDirectory(), entry.JavaFiles()) | 264 constants.GetOutDirectory(), java_files) |
258 if self.Srcjars(entry): | |
259 java_dirs.append( | |
260 os.path.join(self.EntryOutputDir(entry), _SRCJARS_SUBDIR)) | |
261 return java_dirs, excludes | 265 return java_dirs, excludes |
262 | 266 |
263 def _GenResDirs(self, entry): | |
264 res_dirs = list(entry.DepsInfo().get('owned_resources_dirs', [])) | |
265 if entry.ResZips(): | |
266 res_dirs.append(os.path.join(self.EntryOutputDir(entry), _RES_SUBDIR)) | |
267 return res_dirs | |
268 | |
269 def _GenCustomManifest(self, entry): | 267 def _GenCustomManifest(self, entry): |
270 """Returns the path to the generated AndroidManifest.xml. | 268 """Returns the path to the generated AndroidManifest.xml. |
271 | 269 |
272 Gradle uses package id from manifest when generating R.class. So, we need | 270 Gradle uses package id from manifest when generating R.class. So, we need |
273 to generate a custom manifest if we let gradle process resources. We cannot | 271 to generate a custom manifest if we let gradle process resources. We cannot |
274 simply set android.defaultConfig.applicationId because it is not supported | 272 simply set android.defaultConfig.applicationId because it is not supported |
275 for library targets.""" | 273 for library targets.""" |
276 resource_packages = entry.Javac().get('resource_packages') | 274 resource_packages = entry.Javac().get('resource_packages') |
277 if not resource_packages: | 275 if not resource_packages: |
278 logging.debug('Target ' + entry.GnTarget() + ' includes resources from ' | 276 logging.debug('Target ' + entry.GnTarget() + ' includes resources from ' |
(...skipping 11 matching lines...) Expand all Loading... | |
290 output_file = os.path.join( | 288 output_file = os.path.join( |
291 self.EntryOutputDir(entry), 'AndroidManifest.xml') | 289 self.EntryOutputDir(entry), 'AndroidManifest.xml') |
292 data = self.jinja_processor.Render(_TemplatePath('manifest'), variables) | 290 data = self.jinja_processor.Render(_TemplatePath('manifest'), variables) |
293 _WriteFile(output_file, data) | 291 _WriteFile(output_file, data) |
294 | 292 |
295 return output_file | 293 return output_file |
296 | 294 |
297 def _Relativize(self, entry, paths): | 295 def _Relativize(self, entry, paths): |
298 return _RebasePath(paths, self.EntryOutputDir(entry)) | 296 return _RebasePath(paths, self.EntryOutputDir(entry)) |
299 | 297 |
300 def EntryOutputDir(self, entry): | 298 def _Srcjars(self, entry): |
301 return os.path.join(self.project_dir, entry.GradleSubdir()) | |
302 | |
303 def Srcjars(self, entry): | |
304 srcjars = _RebasePath(entry.Gradle().get('bundled_srcjars', [])) | 299 srcjars = _RebasePath(entry.Gradle().get('bundled_srcjars', [])) |
305 if not self.use_gradle_process_resources: | 300 if not self.use_gradle_process_resources: |
306 srcjars += _RebasePath(entry.BuildConfig()['javac']['srcjars']) | 301 srcjars += _RebasePath(entry.BuildConfig()['javac']['srcjars']) |
307 return srcjars | 302 return srcjars |
308 | 303 |
309 def GeneratedInputs(self, entry): | 304 def _GetEntries(self, entry): |
310 generated_inputs = [] | 305 if self.split_projects: |
311 generated_inputs.extend(self.Srcjars(entry)) | 306 return [entry] |
312 generated_inputs.extend(_RebasePath(entry.ResZips())) | 307 return entry.AllEntries() |
313 generated_inputs.extend(entry.GeneratedJavaFiles()) | |
314 generated_inputs.extend(entry.PrebuiltJars()) | |
315 return generated_inputs | |
316 | 308 |
317 def Generate(self, entry): | 309 def EntryOutputDir(self, entry): |
318 variables = {} | 310 return os.path.join(self.project_dir, entry.GradleSubdir()) |
319 java_dirs, excludes = self._GenJavaDirs(entry) | 311 |
320 variables['java_dirs'] = self._Relativize(entry, java_dirs) | 312 def AllSrcjars(self, root_entry): |
321 variables['java_excludes'] = excludes | 313 srcjars = [] |
322 variables['jni_libs'] = self._Relativize(entry, self._GenJniLibs(entry)) | 314 for entry in self._GetEntries(root_entry): |
323 variables['res_dirs'] = self._Relativize(entry, self._GenResDirs(entry)) | 315 srcjars += self._Srcjars(entry) |
324 android_manifest = entry.Gradle().get('android_manifest') | 316 return set(srcjars) |
325 if not android_manifest: | 317 |
326 android_manifest = self._GenCustomManifest(entry) | 318 def AllResZips(self, root_entry): |
327 variables['android_manifest'] = self._Relativize(entry, android_manifest) | 319 res_zips = [] |
320 for entry in self._GetEntries(root_entry): | |
321 res_zips += entry.ResZips() | |
322 return set(_RebasePath(res_zips)) | |
323 | |
324 def GeneratedInputs(self, root_entry): | |
325 generated_inputs = set(self.AllResZips(root_entry)) | |
326 generated_inputs.update(self.AllSrcjars(root_entry)) | |
327 for entry in self._GetEntries(root_entry): | |
328 generated_inputs.update(entry.GeneratedJavaFiles()) | |
329 generated_inputs.update(entry.PrebuiltJars()) | |
330 return set(generated_inputs) | |
331 | |
332 def Generate(self, root_entry): | |
328 # TODO(agrieve): Add an option to use interface jars and see if that speeds | 333 # TODO(agrieve): Add an option to use interface jars and see if that speeds |
329 # things up at all. | 334 # things up at all. |
330 variables['prebuilts'] = self._Relativize(entry, entry.PrebuiltJars()) | 335 variables = collections.defaultdict(list) |
agrieve
2017/02/21 17:52:05
nit: some variables can be non-lists, so using a d
| |
331 deps = [_ProjectEntry.FromBuildConfigPath(p) | 336 java_dirs, excludes = self._GenJavaDirs(root_entry) |
332 for p in entry.Gradle()['dependent_android_projects']] | 337 java_dirs.sort() |
333 variables['android_project_deps'] = [d.ProjectName() for d in deps] | 338 variables['java_dirs'] += self._Relativize(root_entry, java_dirs) |
334 deps = [_ProjectEntry.FromBuildConfigPath(p) | 339 variables['java_dirs'].append(_SRCJARS_SUBDIR) |
335 for p in entry.Gradle()['dependent_java_projects']] | 340 variables['java_excludes'] += excludes |
336 variables['java_project_deps'] = [d.ProjectName() for d in deps] | 341 variables['jni_libs'] += self._Relativize( |
342 root_entry, set(self._GenJniLibs(root_entry))) | |
343 for entry in self._GetEntries(root_entry): | |
344 variables['prebuilts'] += entry.PrebuiltJars() | |
345 variables['res_dirs'] += entry.ResDirs() | |
346 variables['prebuilts'] = self._Relativize( | |
347 root_entry, set(variables['prebuilts'])) | |
348 variables['res_dirs'] = self._Relativize( | |
349 root_entry, set(variables['res_dirs'])) | |
350 variables['res_dirs'].append(_RES_SUBDIR) | |
351 android_manifest = root_entry.Gradle().get('android_manifest') | |
352 if not android_manifest: | |
353 android_manifest = self._GenCustomManifest(root_entry) | |
354 variables['android_manifest'] = self._Relativize( | |
355 root_entry, android_manifest) | |
356 if self.split_projects: | |
357 deps = [_ProjectEntry.FromBuildConfigPath(p) | |
358 for p in root_entry.Gradle()['dependent_android_projects']] | |
359 variables['android_project_deps'] = [d.ProjectName() for d in deps] | |
360 deps = [_ProjectEntry.FromBuildConfigPath(p) | |
361 for p in root_entry.Gradle()['dependent_java_projects']] | |
362 variables['java_project_deps'] = [d.ProjectName() for d in deps] | |
337 return variables | 363 return variables |
338 | 364 |
339 | 365 |
340 def _ComputeJavaSourceDirs(java_files): | 366 def _ComputeJavaSourceDirs(java_files): |
341 """Returns a dictionary of source dirs with each given files in one.""" | 367 """Returns a dictionary of source dirs with each given files in one.""" |
342 found_roots = {} | 368 found_roots = {} |
343 for path in java_files: | 369 for path in java_files: |
344 path_root = path | 370 path_root = path |
345 # Recognize these tokens as top-level. | 371 # Recognize these tokens as top-level. |
346 while True: | 372 while True: |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
601 dest='targets', | 627 dest='targets', |
602 action='append', | 628 action='append', |
603 help='GN target to generate project for. ' | 629 help='GN target to generate project for. ' |
604 'May be repeated.') | 630 'May be repeated.') |
605 parser.add_argument('--project-dir', | 631 parser.add_argument('--project-dir', |
606 help='Root of the output project.', | 632 help='Root of the output project.', |
607 default=os.path.join('$CHROMIUM_OUTPUT_DIR', 'gradle')) | 633 default=os.path.join('$CHROMIUM_OUTPUT_DIR', 'gradle')) |
608 parser.add_argument('--all', | 634 parser.add_argument('--all', |
609 action='store_true', | 635 action='store_true', |
610 help='Generate all java targets (slows down IDE)') | 636 help='Generate all java targets (slows down IDE)') |
611 parser.add_argument('--use-gradle-process-resources', | 637 parser.add_argument('--use-gradle-process-resources', |
agrieve
2017/02/21 17:52:05
I'm guessing that non-split projects will currentl
| |
612 action='store_true', | 638 action='store_true', |
613 help='Have gradle generate R.java rather than ninja') | 639 help='Have gradle generate R.java rather than ninja') |
640 parser.add_argument('--split-projects', | |
641 action='store_true', | |
642 help='Split projects by their gn deps rather than ' | |
643 'combining all the dependencies of each target') | |
614 args = parser.parse_args() | 644 args = parser.parse_args() |
615 if args.output_directory: | 645 if args.output_directory: |
616 constants.SetOutputDirectory(args.output_directory) | 646 constants.SetOutputDirectory(args.output_directory) |
617 constants.CheckOutputDirectory() | 647 constants.CheckOutputDirectory() |
618 output_dir = constants.GetOutDirectory() | 648 output_dir = constants.GetOutDirectory() |
619 devil_chromium.Initialize(output_directory=output_dir) | 649 devil_chromium.Initialize(output_directory=output_dir) |
620 run_tests_helper.SetLogLevel(args.verbose_count) | 650 run_tests_helper.SetLogLevel(args.verbose_count) |
621 | 651 |
622 _gradle_output_dir = os.path.abspath( | 652 _gradle_output_dir = os.path.abspath( |
623 args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir)) | 653 args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir)) |
624 jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) | 654 jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR) |
625 build_vars = _ReadBuildVars(output_dir) | 655 build_vars = _ReadBuildVars(output_dir) |
626 generator = _ProjectContextGenerator(_gradle_output_dir, build_vars, | 656 generator = _ProjectContextGenerator(_gradle_output_dir, build_vars, |
627 args.use_gradle_process_resources, jinja_processor) | 657 args.use_gradle_process_resources, jinja_processor, args.split_projects) |
628 logging.warning('Creating project at: %s', generator.project_dir) | 658 logging.warning('Creating project at: %s', generator.project_dir) |
629 | 659 |
630 if args.all: | 660 if args.all: |
631 # Run GN gen if necessary (faster than running "gn gen" in the no-op case). | 661 # Run GN gen if necessary (faster than running "gn gen" in the no-op case). |
632 _RunNinja(constants.GetOutDirectory(), ['build.ninja']) | 662 _RunNinja(constants.GetOutDirectory(), ['build.ninja']) |
633 # Query ninja for all __build_config targets. | 663 # Query ninja for all __build_config targets. |
634 targets = _QueryForAllGnTargets(output_dir) | 664 targets = _QueryForAllGnTargets(output_dir) |
635 else: | 665 else: |
636 targets = args.targets or _DEFAULT_TARGETS | 666 targets = args.targets or _DEFAULT_TARGETS |
637 targets = [re.sub(r'_test_apk$', '_test_apk__apk', t) for t in targets] | 667 targets = [re.sub(r'_test_apk$', '_test_apk__apk', t) for t in targets] |
638 # TODO(wnwen): Utilize Gradle's test constructs for our junit tests? | 668 # TODO(wnwen): Utilize Gradle's test constructs for our junit tests? |
639 targets = [re.sub(r'_junit_tests$', '_junit_tests__java_binary', t) | 669 targets = [re.sub(r'_junit_tests$', '_junit_tests__java_binary', t) |
640 for t in targets] | 670 for t in targets] |
641 | 671 |
642 main_entries = [_ProjectEntry.FromGnTarget(t) for t in targets] | 672 main_entries = [_ProjectEntry.FromGnTarget(t) for t in targets] |
643 | 673 |
644 logging.warning('Building .build_config files...') | 674 logging.warning('Building .build_config files...') |
645 _RunNinja(output_dir, [e.NinjaBuildConfigTarget() for e in main_entries]) | 675 _RunNinja(output_dir, [e.NinjaBuildConfigTarget() for e in main_entries]) |
646 | 676 |
647 # There are many unused libraries, so restrict to those that are actually used | 677 # There are many unused libraries, so restrict to those that are actually used |
648 # when using --all. | 678 # when using --all. |
649 if args.all: | 679 if args.all: |
650 main_entries = [e for e in main_entries if e.GetType() == 'android_apk'] | 680 main_entries = [e for e in main_entries if e.GetType() == 'android_apk'] |
651 | 681 |
652 all_entries = _FindAllProjectEntries(main_entries) | 682 if args.split_projects: |
653 logging.info('Found %d dependent build_config targets.', len(all_entries)) | 683 main_entries = _FindAllProjectEntries(main_entries) |
654 entries = _CombineTestEntries(all_entries) | 684 logging.info('Found %d dependent build_config targets.', len(main_entries)) |
685 entries = _CombineTestEntries(main_entries) | |
655 logging.info('Creating %d projects for targets.', len(entries)) | 686 logging.info('Creating %d projects for targets.', len(entries)) |
656 | 687 |
657 logging.warning('Writing .gradle files...') | 688 logging.warning('Writing .gradle files...') |
658 project_entries = [] | 689 project_entries = [] |
659 zip_tuples = [] | 690 zip_tuples = [] |
660 generated_inputs = [] | 691 generated_inputs = [] |
661 for entry in entries: | 692 for entry in entries: |
662 if entry.GetType() not in ('android_apk', 'java_library', 'java_binary'): | 693 if entry.GetType() not in ('android_apk', 'java_library', 'java_binary'): |
663 continue | 694 continue |
664 | 695 |
665 data = _GenerateGradleFile(entry, generator, build_vars, jinja_processor) | 696 data = _GenerateGradleFile(entry, generator, build_vars, jinja_processor) |
666 if data: | 697 if data: |
667 project_entries.append(entry) | 698 project_entries.append(entry) |
668 # Build all paths references by .gradle that exist within output_dir. | 699 # Build all paths references by .gradle that exist within output_dir. |
669 generated_inputs.extend(generator.GeneratedInputs(entry)) | 700 generated_inputs.extend(generator.GeneratedInputs(entry)) |
670 zip_tuples.extend( | 701 zip_tuples.extend( |
671 (s, os.path.join(generator.EntryOutputDir(entry), _SRCJARS_SUBDIR)) | 702 (s, os.path.join(generator.EntryOutputDir(entry), _SRCJARS_SUBDIR)) |
672 for s in generator.Srcjars(entry)) | 703 for s in generator.AllSrcjars(entry)) |
673 zip_tuples.extend( | 704 zip_tuples.extend( |
674 (s, os.path.join(generator.EntryOutputDir(entry), _RES_SUBDIR)) | 705 (s, os.path.join(generator.EntryOutputDir(entry), _RES_SUBDIR)) |
675 for s in _RebasePath(entry.ResZips())) | 706 for s in generator.AllResZips(entry)) |
676 _WriteFile( | 707 _WriteFile( |
677 os.path.join(generator.EntryOutputDir(entry), 'build.gradle'), data) | 708 os.path.join(generator.EntryOutputDir(entry), 'build.gradle'), data) |
678 | 709 |
679 _WriteFile(os.path.join(generator.project_dir, 'build.gradle'), | 710 _WriteFile(os.path.join(generator.project_dir, 'build.gradle'), |
680 _GenerateRootGradle(jinja_processor)) | 711 _GenerateRootGradle(jinja_processor)) |
681 | 712 |
682 _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), | 713 _WriteFile(os.path.join(generator.project_dir, 'settings.gradle'), |
683 _GenerateSettingsGradle(project_entries)) | 714 _GenerateSettingsGradle(project_entries)) |
684 | 715 |
685 sdk_path = _RebasePath(build_vars['android_sdk_root']) | 716 sdk_path = _RebasePath(build_vars['android_sdk_root']) |
686 _WriteFile(os.path.join(generator.project_dir, 'local.properties'), | 717 _WriteFile(os.path.join(generator.project_dir, 'local.properties'), |
687 _GenerateLocalProperties(sdk_path)) | 718 _GenerateLocalProperties(sdk_path)) |
688 | 719 |
689 if generated_inputs: | 720 if generated_inputs: |
690 logging.warning('Building generated source files...') | 721 logging.warning('Building generated source files...') |
691 targets = _RebasePath(generated_inputs, output_dir) | 722 targets = _RebasePath(generated_inputs, output_dir) |
692 _RunNinja(output_dir, targets) | 723 _RunNinja(output_dir, targets) |
693 | 724 |
694 if zip_tuples: | 725 if zip_tuples: |
695 _ExtractZips(generator.project_dir, zip_tuples) | 726 _ExtractZips(generator.project_dir, zip_tuples) |
696 | 727 |
697 logging.warning('Project created! (%d subprojects)', len(project_entries)) | 728 logging.warning('Project created! (%d subprojects)', len(project_entries)) |
698 logging.warning('Generated projects work best with Android Studio 2.2') | 729 logging.warning('Generated projects work best with Android Studio 2.2') |
699 logging.warning('For more tips: https://chromium.googlesource.com/chromium' | 730 logging.warning('For more tips: https://chromium.googlesource.com/chromium' |
700 '/src.git/+/master/docs/android_studio.md') | 731 '/src.git/+/master/docs/android_studio.md') |
701 | 732 |
702 | 733 |
703 if __name__ == '__main__': | 734 if __name__ == '__main__': |
704 main() | 735 main() |
OLD | NEW |