Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(554)

Side by Side Diff: build/android/gradle/generate_gradle.py

Issue 2691353005: Generate custom manifests when letting gradle process resources. (Closed)
Patch Set: Changes according to Peter's comments. #1 Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | build/android/gradle/manifest.jinja » ('j') | build/android/gradle/manifest.jinja » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 path = os.path.join('gen', self.GradleSubdir() + '.build_config') 168 path = os.path.join('gen', self.GradleSubdir() + '.build_config')
169 self._build_config = build_utils.ReadJson(_RebasePath(path)) 169 self._build_config = build_utils.ReadJson(_RebasePath(path))
170 return self._build_config 170 return self._build_config
171 171
172 def DepsInfo(self): 172 def DepsInfo(self):
173 return self.BuildConfig()['deps_info'] 173 return self.BuildConfig()['deps_info']
174 174
175 def Gradle(self): 175 def Gradle(self):
176 return self.BuildConfig()['gradle'] 176 return self.BuildConfig()['gradle']
177 177
178 def Javac(self):
179 return self.BuildConfig()['javac']
180
178 def GetType(self): 181 def GetType(self):
179 """Returns the target type from its .build_config.""" 182 """Returns the target type from its .build_config."""
180 return self.DepsInfo()['type'] 183 return self.DepsInfo()['type']
181 184
182 def ResZips(self): 185 def ResZips(self):
183 return self.DepsInfo().get('owned_resources_zips') 186 return self.DepsInfo().get('owned_resources_zips')
184 187
185 def JavaFiles(self): 188 def JavaFiles(self):
186 if self._java_files is None: 189 if self._java_files is None:
187 java_sources_file = self.Gradle().get('java_sources_file') 190 java_sources_file = self.Gradle().get('java_sources_file')
188 java_files = [] 191 java_files = []
189 if java_sources_file: 192 if java_sources_file:
190 java_sources_file = _RebasePath(java_sources_file) 193 java_sources_file = _RebasePath(java_sources_file)
191 java_files = build_utils.ReadSourcesList(java_sources_file) 194 java_files = build_utils.ReadSourcesList(java_sources_file)
192 self._java_files = java_files 195 self._java_files = java_files
193 return self._java_files 196 return self._java_files
194 197
195 198
196 class _ProjectContextGenerator(object): 199 class _ProjectContextGenerator(object):
197 """Helper class to generate gradle build files""" 200 """Helper class to generate gradle build files"""
198 def __init__(self, project_dir, use_gradle_process_resources): 201 def __init__(
202 self, project_dir, use_gradle_process_resources, jinja_processor):
199 self.project_dir = project_dir 203 self.project_dir = project_dir
200 self.use_gradle_process_resources = use_gradle_process_resources 204 self.use_gradle_process_resources = use_gradle_process_resources
205 self.jinja_processor = jinja_processor
201 206
202 def _GenJniLibs(self, entry): 207 def _GenJniLibs(self, entry):
203 native_section = entry.BuildConfig().get('native') 208 native_section = entry.BuildConfig().get('native')
204 if native_section: 209 if native_section:
205 jni_libs = _CreateJniLibsDir( 210 jni_libs = _CreateJniLibsDir(
206 constants.GetOutDirectory(), self.EntryOutputDir(entry), 211 constants.GetOutDirectory(), self.EntryOutputDir(entry),
207 native_section.get('libraries')) 212 native_section.get('libraries'))
208 else: 213 else:
209 jni_libs = [] 214 jni_libs = []
210 return jni_libs 215 return jni_libs
211 216
212 def _GenJavaDirs(self, entry): 217 def _GenJavaDirs(self, entry):
213 java_dirs, excludes = _CreateJavaSourceDir( 218 java_dirs, excludes = _CreateJavaSourceDir(
214 constants.GetOutDirectory(), entry.JavaFiles()) 219 constants.GetOutDirectory(), entry.JavaFiles())
215 if self.Srcjars(entry): 220 if self.Srcjars(entry):
216 java_dirs.append( 221 java_dirs.append(
217 os.path.join(self.EntryOutputDir(entry), _SRCJARS_SUBDIR)) 222 os.path.join(self.EntryOutputDir(entry), _SRCJARS_SUBDIR))
218 return java_dirs, excludes 223 return java_dirs, excludes
219 224
220 def _GenResDirs(self, entry): 225 def _GenResDirs(self, entry):
221 res_dirs = list(entry.DepsInfo().get('owned_resources_dirs', [])) 226 res_dirs = list(entry.DepsInfo().get('owned_resources_dirs', []))
222 if entry.ResZips(): 227 if entry.ResZips():
223 res_dirs.append(os.path.join(self.EntryOutputDir(entry), _RES_SUBDIR)) 228 res_dirs.append(os.path.join(self.EntryOutputDir(entry), _RES_SUBDIR))
224 return res_dirs 229 return res_dirs
225 230
231 def _GenCustomManifest(self, entry):
232 """Returns the path to the generated AndroidManifest.xml."""
233 javac = entry.Javac()
234 resource_packages = javac['resource_packages']
235 output_file = os.path.join(
236 self.EntryOutputDir(entry), 'AndroidManifest.xml')
237
238 if not resource_packages:
239 logging.error('Target ' + entry.GnTarget() + ' includes resources from '
240 'unknown package. Unable to process with gradle.')
241 return _DEFAULT_ANDROID_MANIFEST_PATH
242 elif len(resource_packages) > 1:
243 logging.error('Target ' + entry.GnTarget() + ' includes resources from '
244 'multiple packages. Unable to process with gradle.')
245 return _DEFAULT_ANDROID_MANIFEST_PATH
246
247 variables = {}
248 variables['package'] = resource_packages[0]
249
250 data = self.jinja_processor.Render(_TemplatePath('manifest'), variables)
251 _WriteFile(output_file, data)
252
253 return output_file
254
226 def _Relativize(self, entry, paths): 255 def _Relativize(self, entry, paths):
227 return _RebasePath(paths, self.EntryOutputDir(entry)) 256 return _RebasePath(paths, self.EntryOutputDir(entry))
228 257
229 def EntryOutputDir(self, entry): 258 def EntryOutputDir(self, entry):
230 return os.path.join(self.project_dir, entry.GradleSubdir()) 259 return os.path.join(self.project_dir, entry.GradleSubdir())
231 260
232 def Srcjars(self, entry): 261 def Srcjars(self, entry):
233 srcjars = _RebasePath(entry.Gradle().get('bundled_srcjars', [])) 262 srcjars = _RebasePath(entry.Gradle().get('bundled_srcjars', []))
234 if not self.use_gradle_process_resources: 263 if not self.use_gradle_process_resources:
235 srcjars += _RebasePath(entry.BuildConfig()['javac']['srcjars']) 264 srcjars += _RebasePath(entry.BuildConfig()['javac']['srcjars'])
236 return srcjars 265 return srcjars
237 266
238 def GeneratedInputs(self, entry): 267 def GeneratedInputs(self, entry):
239 generated_inputs = [] 268 generated_inputs = []
240 generated_inputs.extend(self.Srcjars(entry)) 269 generated_inputs.extend(self.Srcjars(entry))
241 generated_inputs.extend(_RebasePath(entry.ResZips())) 270 generated_inputs.extend(_RebasePath(entry.ResZips()))
242 generated_inputs.extend( 271 generated_inputs.extend(
243 p for p in entry.JavaFiles() if not p.startswith('..')) 272 p for p in entry.JavaFiles() if not p.startswith('..'))
244 generated_inputs.extend(entry.Gradle()['dependent_prebuilt_jars']) 273 generated_inputs.extend(entry.Gradle()['dependent_prebuilt_jars'])
245 return generated_inputs 274 return generated_inputs
246 275
247 def Generate(self, entry): 276 def Generate(self, entry):
248 variables = {} 277 variables = {}
249 android_test_manifest = entry.Gradle().get(
250 'android_manifest', _DEFAULT_ANDROID_MANIFEST_PATH)
251 variables['android_manifest'] = self._Relativize(
252 entry, android_test_manifest)
253 java_dirs, excludes = self._GenJavaDirs(entry) 278 java_dirs, excludes = self._GenJavaDirs(entry)
254 variables['java_dirs'] = self._Relativize(entry, java_dirs) 279 variables['java_dirs'] = self._Relativize(entry, java_dirs)
255 variables['java_excludes'] = excludes 280 variables['java_excludes'] = excludes
256 variables['jni_libs'] = self._Relativize(entry, self._GenJniLibs(entry)) 281 variables['jni_libs'] = self._Relativize(entry, self._GenJniLibs(entry))
257 variables['res_dirs'] = self._Relativize(entry, self._GenResDirs(entry)) 282 variables['res_dirs'] = self._Relativize(entry, self._GenResDirs(entry))
283 android_manifest = entry.Gradle().get('android_manifest')
284 if not android_manifest:
285 # Gradle uses package id from manifest when generating R.class. So, we
286 # need to generate a custom manifest if we let gradle process resources.
agrieve 2017/02/16 15:28:01 nit: can you add a note that applicationId doesn't
sakal-chromium 2017/02/16 15:47:37 Done.
287 if self.use_gradle_process_resources and variables['res_dirs']:
agrieve 2017/02/16 15:28:01 nit: I think we'll want to do this regardless of u
sakal-chromium 2017/02/16 15:47:37 Done.
288 android_manifest = self._GenCustomManifest(entry)
289 else:
290 android_manifest = _DEFAULT_ANDROID_MANIFEST_PATH
291 variables['android_manifest'] = self._Relativize(entry, android_manifest)
258 deps = [_ProjectEntry.FromBuildConfigPath(p) 292 deps = [_ProjectEntry.FromBuildConfigPath(p)
259 for p in entry.Gradle()['dependent_android_projects']] 293 for p in entry.Gradle()['dependent_android_projects']]
260 variables['android_project_deps'] = [d.ProjectName() for d in deps] 294 variables['android_project_deps'] = [d.ProjectName() for d in deps]
261 # TODO(agrieve): Add an option to use interface jars and see if that speeds 295 # TODO(agrieve): Add an option to use interface jars and see if that speeds
262 # things up at all. 296 # things up at all.
263 variables['prebuilts'] = self._Relativize( 297 variables['prebuilts'] = self._Relativize(
264 entry, entry.Gradle()['dependent_prebuilt_jars']) 298 entry, entry.Gradle()['dependent_prebuilt_jars'])
265 deps = [_ProjectEntry.FromBuildConfigPath(p) 299 deps = [_ProjectEntry.FromBuildConfigPath(p)
266 for p in entry.Gradle()['dependent_java_projects']] 300 for p in entry.Gradle()['dependent_java_projects']]
267 variables['java_project_deps'] = [d.ProjectName() for d in deps] 301 variables['java_project_deps'] = [d.ProjectName() for d in deps]
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 args = parser.parse_args() 571 args = parser.parse_args()
538 if args.output_directory: 572 if args.output_directory:
539 constants.SetOutputDirectory(args.output_directory) 573 constants.SetOutputDirectory(args.output_directory)
540 constants.CheckOutputDirectory() 574 constants.CheckOutputDirectory()
541 output_dir = constants.GetOutDirectory() 575 output_dir = constants.GetOutDirectory()
542 devil_chromium.Initialize(output_directory=output_dir) 576 devil_chromium.Initialize(output_directory=output_dir)
543 run_tests_helper.SetLogLevel(args.verbose_count) 577 run_tests_helper.SetLogLevel(args.verbose_count)
544 578
545 _gradle_output_dir = os.path.abspath( 579 _gradle_output_dir = os.path.abspath(
546 args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir)) 580 args.project_dir.replace('$CHROMIUM_OUTPUT_DIR', output_dir))
581 jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR)
547 generator = _ProjectContextGenerator( 582 generator = _ProjectContextGenerator(
548 _gradle_output_dir, args.use_gradle_process_resources) 583 _gradle_output_dir, args.use_gradle_process_resources, jinja_processor)
549 logging.warning('Creating project at: %s', generator.project_dir) 584 logging.warning('Creating project at: %s', generator.project_dir)
550 585
551 if args.all: 586 if args.all:
552 # Run GN gen if necessary (faster than running "gn gen" in the no-op case). 587 # Run GN gen if necessary (faster than running "gn gen" in the no-op case).
553 _RunNinja(constants.GetOutDirectory(), ['build.ninja']) 588 _RunNinja(constants.GetOutDirectory(), ['build.ninja'])
554 # Query ninja for all __build_config targets. 589 # Query ninja for all __build_config targets.
555 targets = _QueryForAllGnTargets(output_dir) 590 targets = _QueryForAllGnTargets(output_dir)
556 else: 591 else:
557 targets = args.targets or _DEFAULT_TARGETS 592 targets = args.targets or _DEFAULT_TARGETS
558 targets = [re.sub(r'_test_apk$', '_test_apk__apk', t) for t in targets] 593 targets = [re.sub(r'_test_apk$', '_test_apk__apk', t) for t in targets]
(...skipping 10 matching lines...) Expand all
569 # when using --all. 604 # when using --all.
570 if args.all: 605 if args.all:
571 main_entries = [e for e in main_entries if e.GetType() == 'android_apk'] 606 main_entries = [e for e in main_entries if e.GetType() == 'android_apk']
572 607
573 all_entries = _FindAllProjectEntries(main_entries) 608 all_entries = _FindAllProjectEntries(main_entries)
574 logging.info('Found %d dependent build_config targets.', len(all_entries)) 609 logging.info('Found %d dependent build_config targets.', len(all_entries))
575 entries = _CombineTestEntries(all_entries) 610 entries = _CombineTestEntries(all_entries)
576 logging.info('Creating %d projects for targets.', len(entries)) 611 logging.info('Creating %d projects for targets.', len(entries))
577 612
578 logging.warning('Writing .gradle files...') 613 logging.warning('Writing .gradle files...')
579 jinja_processor = jinja_template.JinjaProcessor(_FILE_DIR)
580 build_vars = _ReadBuildVars(output_dir) 614 build_vars = _ReadBuildVars(output_dir)
581 project_entries = [] 615 project_entries = []
582 zip_tuples = [] 616 zip_tuples = []
583 generated_inputs = [] 617 generated_inputs = []
584 for entry in entries: 618 for entry in entries:
585 if entry.GetType() not in ('android_apk', 'java_library', 'java_binary'): 619 if entry.GetType() not in ('android_apk', 'java_library', 'java_binary'):
586 continue 620 continue
587 621
588 data = _GenerateGradleFile(entry, generator, build_vars, jinja_processor) 622 data = _GenerateGradleFile(entry, generator, build_vars, jinja_processor)
589 if data: 623 if data:
(...skipping 28 matching lines...) Expand all
618 _ExtractZips(generator.project_dir, zip_tuples) 652 _ExtractZips(generator.project_dir, zip_tuples)
619 653
620 logging.warning('Project created! (%d subprojects)', len(project_entries)) 654 logging.warning('Project created! (%d subprojects)', len(project_entries))
621 logging.warning('Generated projects work best with Android Studio 2.2') 655 logging.warning('Generated projects work best with Android Studio 2.2')
622 logging.warning('For more tips: https://chromium.googlesource.com/chromium' 656 logging.warning('For more tips: https://chromium.googlesource.com/chromium'
623 '/src.git/+/master/docs/android_studio.md') 657 '/src.git/+/master/docs/android_studio.md')
624 658
625 659
626 if __name__ == '__main__': 660 if __name__ == '__main__':
627 main() 661 main()
OLDNEW
« no previous file with comments | « no previous file | build/android/gradle/manifest.jinja » ('j') | build/android/gradle/manifest.jinja » ('J')

Powered by Google App Engine
This is Rietveld 408576698