1// Copyright 2015 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package java 16 17// This file contains the module types for compiling Java for Android, and converts the properties 18// into the flags and filenames necessary to pass to the Module. The final creation of the rules 19// is handled in builder.go 20 21import ( 22 "fmt" 23 "path/filepath" 24 "strconv" 25 "strings" 26 27 "github.com/google/blueprint" 28 "github.com/google/blueprint/pathtools" 29 "github.com/google/blueprint/proptools" 30 31 "android/soong/android" 32 "android/soong/java/config" 33 "android/soong/tradefed" 34) 35 36func init() { 37 RegisterJavaBuildComponents(android.InitRegistrationContext) 38 39 // Register sdk member types. 40 android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) 41 42 android.RegisterSdkMemberType(&librarySdkMemberType{ 43 android.SdkMemberTypeBase{ 44 PropertyName: "java_libs", 45 }, 46 func(j *Library) android.Path { 47 implementationJars := j.ImplementationAndResourcesJars() 48 if len(implementationJars) != 1 { 49 panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) 50 } 51 52 return implementationJars[0] 53 }, 54 }) 55 56 android.RegisterSdkMemberType(&testSdkMemberType{ 57 SdkMemberTypeBase: android.SdkMemberTypeBase{ 58 PropertyName: "java_tests", 59 }, 60 }) 61} 62 63func RegisterJavaBuildComponents(ctx android.RegistrationContext) { 64 ctx.RegisterModuleType("java_defaults", DefaultsFactory) 65 66 ctx.RegisterModuleType("java_library", LibraryFactory) 67 ctx.RegisterModuleType("java_library_static", LibraryStaticFactory) 68 ctx.RegisterModuleType("java_library_host", LibraryHostFactory) 69 ctx.RegisterModuleType("java_binary", BinaryFactory) 70 ctx.RegisterModuleType("java_binary_host", BinaryHostFactory) 71 ctx.RegisterModuleType("java_test", TestFactory) 72 ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory) 73 ctx.RegisterModuleType("java_test_host", TestHostFactory) 74 ctx.RegisterModuleType("java_test_import", JavaTestImportFactory) 75 ctx.RegisterModuleType("java_import", ImportFactory) 76 ctx.RegisterModuleType("java_import_host", ImportFactoryHost) 77 ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory) 78 ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory) 79 ctx.RegisterModuleType("dex_import", DexImportFactory) 80 81 ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { 82 ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel() 83 }) 84 85 ctx.RegisterSingletonType("logtags", LogtagsSingleton) 86 ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) 87} 88 89func (j *Module) CheckStableSdkVersion() error { 90 sdkVersion := j.sdkVersion() 91 if sdkVersion.stable() { 92 return nil 93 } 94 return fmt.Errorf("non stable SDK %v", sdkVersion) 95} 96 97func (j *Module) checkSdkVersions(ctx android.ModuleContext) { 98 if j.RequiresStableAPIs(ctx) { 99 if sc, ok := ctx.Module().(sdkContext); ok { 100 if !sc.sdkVersion().specified() { 101 ctx.PropertyErrorf("sdk_version", 102 "sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).") 103 } 104 } 105 } 106 107 ctx.VisitDirectDeps(func(module android.Module) { 108 tag := ctx.OtherModuleDependencyTag(module) 109 switch module.(type) { 110 // TODO(satayev): cover other types as well, e.g. imports 111 case *Library, *AndroidLibrary: 112 switch tag { 113 case bootClasspathTag, libTag, staticLibTag, java9LibTag: 114 checkLinkType(ctx, j, module.(linkTypeContext), tag.(dependencyTag)) 115 } 116 } 117 }) 118} 119 120func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { 121 if sc, ok := ctx.Module().(sdkContext); ok { 122 usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis) 123 sdkVersionSpecified := sc.sdkVersion().specified() 124 if usePlatformAPI && sdkVersionSpecified { 125 ctx.PropertyErrorf("platform_apis", "platform_apis must be false when sdk_version is not empty.") 126 } else if !usePlatformAPI && !sdkVersionSpecified { 127 ctx.PropertyErrorf("platform_apis", "platform_apis must be true when sdk_version is empty.") 128 } 129 130 } 131} 132 133// TODO: 134// Autogenerated files: 135// Renderscript 136// Post-jar passes: 137// Proguard 138// Rmtypedefs 139// DroidDoc 140// Findbugs 141 142type CompilerProperties struct { 143 // list of source files used to compile the Java module. May be .java, .kt, .logtags, .proto, 144 // or .aidl files. 145 Srcs []string `android:"path,arch_variant"` 146 147 // list Kotlin of source files containing Kotlin code that should be treated as common code in 148 // a codebase that supports Kotlin multiplatform. See 149 // https://kotlinlang.org/docs/reference/multiplatform.html. May be only be .kt files. 150 Common_srcs []string `android:"path,arch_variant"` 151 152 // list of source files that should not be used to build the Java module. 153 // This is most useful in the arch/multilib variants to remove non-common files 154 Exclude_srcs []string `android:"path,arch_variant"` 155 156 // list of directories containing Java resources 157 Java_resource_dirs []string `android:"arch_variant"` 158 159 // list of directories that should be excluded from java_resource_dirs 160 Exclude_java_resource_dirs []string `android:"arch_variant"` 161 162 // list of files to use as Java resources 163 Java_resources []string `android:"path,arch_variant"` 164 165 // list of files that should be excluded from java_resources and java_resource_dirs 166 Exclude_java_resources []string `android:"path,arch_variant"` 167 168 // list of module-specific flags that will be used for javac compiles 169 Javacflags []string `android:"arch_variant"` 170 171 // list of module-specific flags that will be used for kotlinc compiles 172 Kotlincflags []string `android:"arch_variant"` 173 174 // list of of java libraries that will be in the classpath 175 Libs []string `android:"arch_variant"` 176 177 // list of java libraries that will be compiled into the resulting jar 178 Static_libs []string `android:"arch_variant"` 179 180 // manifest file to be included in resulting jar 181 Manifest *string `android:"path"` 182 183 // if not blank, run jarjar using the specified rules file 184 Jarjar_rules *string `android:"path,arch_variant"` 185 186 // If not blank, set the java version passed to javac as -source and -target 187 Java_version *string 188 189 // If set to true, allow this module to be dexed and installed on devices. Has no 190 // effect on host modules, which are always considered installable. 191 Installable *bool 192 193 // If set to true, include sources used to compile the module in to the final jar 194 Include_srcs *bool 195 196 // If not empty, classes are restricted to the specified packages and their sub-packages. 197 // This restriction is checked after applying jarjar rules and including static libs. 198 Permitted_packages []string 199 200 // List of modules to use as annotation processors 201 Plugins []string 202 203 // List of modules to export to libraries that directly depend on this library as annotation processors 204 Exported_plugins []string 205 206 // The number of Java source entries each Javac instance can process 207 Javac_shard_size *int64 208 209 // Add host jdk tools.jar to bootclasspath 210 Use_tools_jar *bool 211 212 Openjdk9 struct { 213 // List of source files that should only be used when passing -source 1.9 or higher 214 Srcs []string `android:"path"` 215 216 // List of javac flags that should only be used when passing -source 1.9 or higher 217 Javacflags []string 218 } 219 220 // When compiling language level 9+ .java code in packages that are part of 221 // a system module, patch_module names the module that your sources and 222 // dependencies should be patched into. The Android runtime currently 223 // doesn't implement the JEP 261 module system so this option is only 224 // supported at compile time. It should only be needed to compile tests in 225 // packages that exist in libcore and which are inconvenient to move 226 // elsewhere. 227 Patch_module *string `android:"arch_variant"` 228 229 Jacoco struct { 230 // List of classes to include for instrumentation with jacoco to collect coverage 231 // information at runtime when building with coverage enabled. If unset defaults to all 232 // classes. 233 // Supports '*' as the last character of an entry in the list as a wildcard match. 234 // If preceded by '.' it matches all classes in the package and subpackages, otherwise 235 // it matches classes in the package that have the class name as a prefix. 236 Include_filter []string 237 238 // List of classes to exclude from instrumentation with jacoco to collect coverage 239 // information at runtime when building with coverage enabled. Overrides classes selected 240 // by the include_filter property. 241 // Supports '*' as the last character of an entry in the list as a wildcard match. 242 // If preceded by '.' it matches all classes in the package and subpackages, otherwise 243 // it matches classes in the package that have the class name as a prefix. 244 Exclude_filter []string 245 } 246 247 Errorprone struct { 248 // List of javac flags that should only be used when running errorprone. 249 Javacflags []string 250 } 251 252 Proto struct { 253 // List of extra options that will be passed to the proto generator. 254 Output_params []string 255 } 256 257 Instrument bool `blueprint:"mutated"` 258 259 // List of files to include in the META-INF/services folder of the resulting jar. 260 Services []string `android:"path,arch_variant"` 261 262 // If true, package the kotlin stdlib into the jar. Defaults to true. 263 Static_kotlin_stdlib *bool `android:"arch_variant"` 264} 265 266type CompilerDeviceProperties struct { 267 // list of module-specific flags that will be used for dex compiles 268 Dxflags []string `android:"arch_variant"` 269 270 // if not blank, set to the version of the sdk to compile against. 271 // Defaults to compiling against the current platform. 272 Sdk_version *string 273 274 // if not blank, set the minimum version of the sdk that the compiled artifacts will run against. 275 // Defaults to sdk_version if not set. 276 Min_sdk_version *string 277 278 // if not blank, set the targetSdkVersion in the AndroidManifest.xml. 279 // Defaults to sdk_version if not set. 280 Target_sdk_version *string 281 282 // Whether to compile against the platform APIs instead of an SDK. 283 // If true, then sdk_version must be empty. The value of this field 284 // is ignored when module's type isn't android_app. 285 Platform_apis *bool 286 287 Aidl struct { 288 // Top level directories to pass to aidl tool 289 Include_dirs []string 290 291 // Directories rooted at the Android.bp file to pass to aidl tool 292 Local_include_dirs []string 293 294 // directories that should be added as include directories for any aidl sources of modules 295 // that depend on this module, as well as to aidl for this module. 296 Export_include_dirs []string 297 298 // whether to generate traces (for systrace) for this interface 299 Generate_traces *bool 300 301 // whether to generate Binder#GetTransaction name method. 302 Generate_get_transaction_name *bool 303 } 304 305 // If true, export a copy of the module as a -hostdex module for host testing. 306 Hostdex *bool 307 308 Target struct { 309 Hostdex struct { 310 // Additional required dependencies to add to -hostdex modules. 311 Required []string 312 } 313 } 314 315 // If set to true, compile dex regardless of installable. Defaults to false. 316 Compile_dex *bool 317 318 Optimize struct { 319 // If false, disable all optimization. Defaults to true for android_app and android_test 320 // modules, false for java_library and java_test modules. 321 Enabled *bool 322 // True if the module containing this has it set by default. 323 EnabledByDefault bool `blueprint:"mutated"` 324 325 // If true, optimize for size by removing unused code. Defaults to true for apps, 326 // false for libraries and tests. 327 Shrink *bool 328 329 // If true, optimize bytecode. Defaults to false. 330 Optimize *bool 331 332 // If true, obfuscate bytecode. Defaults to false. 333 Obfuscate *bool 334 335 // If true, do not use the flag files generated by aapt that automatically keep 336 // classes referenced by the app manifest. Defaults to false. 337 No_aapt_flags *bool 338 339 // Flags to pass to proguard. 340 Proguard_flags []string 341 342 // Specifies the locations of files containing proguard flags. 343 Proguard_flags_files []string `android:"path"` 344 } 345 346 // When targeting 1.9 and above, override the modules to use with --system, 347 // otherwise provides defaults libraries to add to the bootclasspath. 348 System_modules *string 349 350 // The name of the module as used in build configuration. 351 // 352 // Allows a library to separate its actual name from the name used in 353 // build configuration, e.g.ctx.Config().BootJars(). 354 ConfigurationName *string `blueprint:"mutated"` 355 356 // set the name of the output 357 Stem *string 358 359 // Keep the data uncompressed. We always need uncompressed dex for execution, 360 // so this might actually save space by avoiding storing the same data twice. 361 // This defaults to reasonable value based on module and should not be set. 362 // It exists only to support ART tests. 363 Uncompress_dex *bool 364 365 IsSDKLibrary bool `blueprint:"mutated"` 366} 367 368func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool { 369 return BoolDefault(me.Optimize.Enabled, me.Optimize.EnabledByDefault) 370} 371 372// Functionality common to Module and Import 373// 374// It is embedded in Module so its functionality can be used by methods in Module 375// but it is currently only initialized by Import and Library. 376type embeddableInModuleAndImport struct { 377 378 // Functionality related to this being used as a component of a java_sdk_library. 379 EmbeddableSdkLibraryComponent 380} 381 382func (e *embeddableInModuleAndImport) initModuleAndImport(moduleBase *android.ModuleBase) { 383 e.initSdkLibraryComponent(moduleBase) 384} 385 386// Module/Import's DepIsInSameApex(...) delegates to this method. 387// 388// This cannot implement DepIsInSameApex(...) directly as that leads to ambiguity with 389// the one provided by ApexModuleBase. 390func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 391 // dependencies other than the static linkage are all considered crossing APEX boundary 392 if staticLibTag == ctx.OtherModuleDependencyTag(dep) { 393 return true 394 } 395 return false 396} 397 398// Module contains the properties and members used by all java module types 399type Module struct { 400 android.ModuleBase 401 android.DefaultableModuleBase 402 android.ApexModuleBase 403 android.SdkBase 404 405 // Functionality common to Module and Import. 406 embeddableInModuleAndImport 407 408 properties CompilerProperties 409 protoProperties android.ProtoProperties 410 deviceProperties CompilerDeviceProperties 411 412 // jar file containing header classes including static library dependencies, suitable for 413 // inserting into the bootclasspath/classpath of another compile 414 headerJarFile android.Path 415 416 // jar file containing implementation classes including static library dependencies but no 417 // resources 418 implementationJarFile android.Path 419 420 // jar file containing only resources including from static library dependencies 421 resourceJar android.Path 422 423 // args and dependencies to package source files into a srcjar 424 srcJarArgs []string 425 srcJarDeps android.Paths 426 427 // jar file containing implementation classes and resources including static library 428 // dependencies 429 implementationAndResourcesJar android.Path 430 431 // output file containing classes.dex and resources 432 dexJarFile android.Path 433 434 // output file that contains classes.dex if it should be in the output file 435 maybeStrippedDexJarFile android.Path 436 437 // output file containing uninstrumented classes that will be instrumented by jacoco 438 jacocoReportClassesFile android.Path 439 440 // output file containing mapping of obfuscated names 441 proguardDictionary android.Path 442 443 // output file of the module, which may be a classes jar or a dex jar 444 outputFile android.Path 445 extraOutputFiles android.Paths 446 447 exportAidlIncludeDirs android.Paths 448 449 logtagsSrcs android.Paths 450 451 // installed file for binary dependency 452 installFile android.Path 453 454 // list of .java files and srcjars that was passed to javac 455 compiledJavaSrcs android.Paths 456 compiledSrcJars android.Paths 457 458 // list of extra progurad flag files 459 extraProguardFlagFiles android.Paths 460 461 // manifest file to use instead of properties.Manifest 462 overrideManifest android.OptionalPath 463 464 // list of SDK lib names that this java module is exporting 465 exportedSdkLibs []string 466 467 // list of plugins that this java module is exporting 468 exportedPluginJars android.Paths 469 470 // list of plugins that this java module is exporting 471 exportedPluginClasses []string 472 473 // list of source files, collected from srcFiles with unique java and all kt files, 474 // will be used by android.IDEInfo struct 475 expandIDEInfoCompiledSrcs []string 476 477 // expanded Jarjar_rules 478 expandJarjarRules android.Path 479 480 // list of additional targets for checkbuild 481 additionalCheckedModules android.Paths 482 483 // Extra files generated by the module type to be added as java resources. 484 extraResources android.Paths 485 486 hiddenAPI 487 dexpreopter 488 linter 489 490 // list of the xref extraction files 491 kytheFiles android.Paths 492 493 distFiles android.TaggedDistFiles 494 495 // Collect the module directory for IDE info in java/jdeps.go. 496 modulePaths []string 497} 498 499func (j *Module) addHostProperties() { 500 j.AddProperties( 501 &j.properties, 502 &j.protoProperties, 503 ) 504} 505 506func (j *Module) addHostAndDeviceProperties() { 507 j.addHostProperties() 508 j.AddProperties( 509 &j.deviceProperties, 510 &j.dexpreoptProperties, 511 &j.linter.properties, 512 ) 513} 514 515func (j *Module) OutputFiles(tag string) (android.Paths, error) { 516 switch tag { 517 case "": 518 return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil 519 case ".jar": 520 return android.Paths{j.implementationAndResourcesJar}, nil 521 case ".proguard_map": 522 return android.Paths{j.proguardDictionary}, nil 523 default: 524 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 525 } 526} 527 528var _ android.OutputFileProducer = (*Module)(nil) 529 530// Methods that need to be implemented for a module that is added to apex java_libs property. 531type ApexDependency interface { 532 HeaderJars() android.Paths 533 ImplementationAndResourcesJars() android.Paths 534} 535 536type Dependency interface { 537 ApexDependency 538 ImplementationJars() android.Paths 539 ResourceJars() android.Paths 540 DexJarBuildPath() android.Path 541 DexJarInstallPath() android.Path 542 AidlIncludeDirs() android.Paths 543 ExportedSdkLibs() []string 544 ExportedPlugins() (android.Paths, []string) 545 SrcJarArgs() ([]string, android.Paths) 546 BaseModuleName() string 547 JacocoReportClassesFile() android.Path 548} 549 550type xref interface { 551 XrefJavaFiles() android.Paths 552} 553 554func (j *Module) XrefJavaFiles() android.Paths { 555 return j.kytheFiles 556} 557 558func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) { 559 initJavaModule(module, hod, false) 560} 561 562func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) { 563 initJavaModule(module, hod, true) 564} 565 566func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) { 567 multilib := android.MultilibCommon 568 if multiTargets { 569 android.InitAndroidMultiTargetsArchModule(module, hod, multilib) 570 } else { 571 android.InitAndroidArchModule(module, hod, multilib) 572 } 573 android.InitDefaultableModule(module) 574} 575 576type dependencyTag struct { 577 blueprint.BaseDependencyTag 578 name string 579} 580 581type jniDependencyTag struct { 582 blueprint.BaseDependencyTag 583} 584 585func IsJniDepTag(depTag blueprint.DependencyTag) bool { 586 _, ok := depTag.(*jniDependencyTag) 587 return ok 588} 589 590var ( 591 dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} 592 staticLibTag = dependencyTag{name: "staticlib"} 593 libTag = dependencyTag{name: "javalib"} 594 java9LibTag = dependencyTag{name: "java9lib"} 595 pluginTag = dependencyTag{name: "plugin"} 596 exportedPluginTag = dependencyTag{name: "exported-plugin"} 597 bootClasspathTag = dependencyTag{name: "bootclasspath"} 598 systemModulesTag = dependencyTag{name: "system modules"} 599 frameworkResTag = dependencyTag{name: "framework-res"} 600 frameworkApkTag = dependencyTag{name: "framework-apk"} 601 kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"} 602 kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations"} 603 proguardRaiseTag = dependencyTag{name: "proguard-raise"} 604 certificateTag = dependencyTag{name: "certificate"} 605 instrumentationForTag = dependencyTag{name: "instrumentation_for"} 606 usesLibTag = dependencyTag{name: "uses-library"} 607 extraLintCheckTag = dependencyTag{name: "extra-lint-check"} 608) 609 610func IsLibDepTag(depTag blueprint.DependencyTag) bool { 611 return depTag == libTag 612} 613 614func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool { 615 return depTag == staticLibTag 616} 617 618type sdkDep struct { 619 useModule, useFiles, invalidVersion bool 620 621 // The modules that will be added to the bootclasspath when targeting 1.8 or lower 622 bootclasspath []string 623 624 // The default system modules to use. Will be an empty string if no system 625 // modules are to be used. 626 systemModules string 627 628 // The modules that will be added to the classpath regardless of the Java language level targeted 629 classpath []string 630 631 // The modules that will be added ot the classpath when targeting 1.9 or higher 632 // (normally these will be on the bootclasspath when targeting 1.8 or lower) 633 java9Classpath []string 634 635 frameworkResModule string 636 637 jars android.Paths 638 aidl android.OptionalPath 639 640 noStandardLibs, noFrameworksLibs bool 641} 642 643func (s sdkDep) hasStandardLibs() bool { 644 return !s.noStandardLibs 645} 646 647func (s sdkDep) hasFrameworkLibs() bool { 648 return !s.noStandardLibs && !s.noFrameworksLibs 649} 650 651type jniLib struct { 652 name string 653 path android.Path 654 target android.Target 655 coverageFile android.OptionalPath 656 unstrippedFile android.Path 657} 658 659func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool { 660 return j.properties.Instrument && 661 ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") && 662 ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir()) 663} 664 665func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool { 666 return j.shouldInstrument(ctx) && 667 (ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") || 668 ctx.Config().UnbundledBuild()) 669} 670 671func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool { 672 // Force enable the instrumentation for java code that is built for APEXes ... 673 // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent 674 // doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true. 675 isJacocoAgent := ctx.ModuleName() == "jacocoagent" 676 if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() { 677 if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { 678 return true 679 } else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { 680 return true 681 } 682 } 683 return false 684} 685 686func (j *Module) sdkVersion() sdkSpec { 687 return sdkSpecFrom(String(j.deviceProperties.Sdk_version)) 688} 689 690func (j *Module) systemModules() string { 691 return proptools.String(j.deviceProperties.System_modules) 692} 693 694func (j *Module) minSdkVersion() sdkSpec { 695 if j.deviceProperties.Min_sdk_version != nil { 696 return sdkSpecFrom(*j.deviceProperties.Min_sdk_version) 697 } 698 return j.sdkVersion() 699} 700 701func (j *Module) targetSdkVersion() sdkSpec { 702 if j.deviceProperties.Target_sdk_version != nil { 703 return sdkSpecFrom(*j.deviceProperties.Target_sdk_version) 704 } 705 return j.sdkVersion() 706} 707 708func (j *Module) MinSdkVersion() string { 709 return j.minSdkVersion().version.String() 710} 711 712func (j *Module) AvailableFor(what string) bool { 713 if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) { 714 // Exception: for hostdex: true libraries, the platform variant is created 715 // even if it's not marked as available to platform. In that case, the platform 716 // variant is used only for the hostdex and not installed to the device. 717 return true 718 } 719 return j.ApexModuleBase.AvailableFor(what) 720} 721 722func (j *Module) deps(ctx android.BottomUpMutatorContext) { 723 if ctx.Device() { 724 j.linter.deps(ctx) 725 726 sdkDep := decodeSdkDep(ctx, sdkContext(j)) 727 if sdkDep.useModule { 728 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) 729 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) 730 ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...) 731 if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { 732 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...) 733 } 734 if j.deviceProperties.EffectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() { 735 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...) 736 } 737 } 738 if sdkDep.systemModules != "" { 739 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) 740 } 741 742 if ctx.ModuleName() == "android_stubs_current" || 743 ctx.ModuleName() == "android_system_stubs_current" || 744 ctx.ModuleName() == "android_test_stubs_current" { 745 ctx.AddVariationDependencies(nil, frameworkApkTag, "framework-res") 746 } 747 } 748 749 syspropPublicStubs := syspropPublicStubs(ctx.Config()) 750 751 // rewriteSyspropLibs validates if a java module can link against platform's sysprop_library, 752 // and redirects dependency to public stub depending on the link type. 753 rewriteSyspropLibs := func(libs []string, prop string) []string { 754 // make a copy 755 ret := android.CopyOf(libs) 756 757 for idx, lib := range libs { 758 stub, ok := syspropPublicStubs[lib] 759 760 if !ok { 761 continue 762 } 763 764 linkType, _ := j.getLinkType(ctx.ModuleName()) 765 // only platform modules can use internal props 766 if linkType != javaPlatform { 767 ret[idx] = stub 768 } 769 } 770 771 return ret 772 } 773 774 ctx.AddVariationDependencies(nil, libTag, rewriteSyspropLibs(j.properties.Libs, "libs")...) 775 ctx.AddVariationDependencies(nil, staticLibTag, rewriteSyspropLibs(j.properties.Static_libs, "static_libs")...) 776 777 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...) 778 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...) 779 780 android.ProtoDeps(ctx, &j.protoProperties) 781 if j.hasSrcExt(".proto") { 782 protoDeps(ctx, &j.protoProperties) 783 } 784 785 if j.hasSrcExt(".kt") { 786 // TODO(ccross): move this to a mutator pass that can tell if generated sources contain 787 // Kotlin files 788 ctx.AddVariationDependencies(nil, kotlinStdlibTag, 789 "kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8") 790 if len(j.properties.Plugins) > 0 { 791 ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations") 792 } 793 } 794 795 // Framework libraries need special handling in static coverage builds: they should not have 796 // static dependency on jacoco, otherwise there would be multiple conflicting definitions of 797 // the same jacoco classes coming from different bootclasspath jars. 798 if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { 799 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { 800 j.properties.Instrument = true 801 } 802 } else if j.shouldInstrumentStatic(ctx) { 803 ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent") 804 } 805} 806 807func hasSrcExt(srcs []string, ext string) bool { 808 for _, src := range srcs { 809 if filepath.Ext(src) == ext { 810 return true 811 } 812 } 813 814 return false 815} 816 817func (j *Module) hasSrcExt(ext string) bool { 818 return hasSrcExt(j.properties.Srcs, ext) 819} 820 821func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath, 822 aidlIncludeDirs android.Paths) (string, android.Paths) { 823 824 aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs) 825 aidlIncludes = append(aidlIncludes, 826 android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...) 827 aidlIncludes = append(aidlIncludes, 828 android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...) 829 830 var flags []string 831 var deps android.Paths 832 833 if aidlPreprocess.Valid() { 834 flags = append(flags, "-p"+aidlPreprocess.String()) 835 deps = append(deps, aidlPreprocess.Path()) 836 } else if len(aidlIncludeDirs) > 0 { 837 flags = append(flags, android.JoinWithPrefix(aidlIncludeDirs.Strings(), "-I")) 838 } 839 840 if len(j.exportAidlIncludeDirs) > 0 { 841 flags = append(flags, android.JoinWithPrefix(j.exportAidlIncludeDirs.Strings(), "-I")) 842 } 843 844 if len(aidlIncludes) > 0 { 845 flags = append(flags, android.JoinWithPrefix(aidlIncludes.Strings(), "-I")) 846 } 847 848 flags = append(flags, "-I"+android.PathForModuleSrc(ctx).String()) 849 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() { 850 flags = append(flags, "-I"+src.String()) 851 } 852 853 if Bool(j.deviceProperties.Aidl.Generate_traces) { 854 flags = append(flags, "-t") 855 } 856 857 if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) { 858 flags = append(flags, "--transaction_names") 859 } 860 861 return strings.Join(flags, " "), deps 862} 863 864type deps struct { 865 classpath classpath 866 java9Classpath classpath 867 bootClasspath classpath 868 processorPath classpath 869 processorClasses []string 870 staticJars android.Paths 871 staticHeaderJars android.Paths 872 staticResourceJars android.Paths 873 aidlIncludeDirs android.Paths 874 srcs android.Paths 875 srcJars android.Paths 876 systemModules *systemModules 877 aidlPreprocess android.OptionalPath 878 kotlinStdlib android.Paths 879 kotlinAnnotations android.Paths 880 881 disableTurbine bool 882} 883 884func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) { 885 for _, f := range dep.Srcs() { 886 if f.Ext() != ".jar" { 887 ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency", 888 ctx.OtherModuleName(dep.(blueprint.Module))) 889 } 890 } 891} 892 893type linkType int 894 895const ( 896 // TODO(jiyong) rename these for better readability. Make the allowed 897 // and disallowed link types explicit 898 javaCore linkType = iota 899 javaSdk 900 javaSystem 901 javaModule 902 javaSystemServer 903 javaPlatform 904) 905 906type linkTypeContext interface { 907 android.Module 908 getLinkType(name string) (ret linkType, stubs bool) 909} 910 911func (m *Module) getLinkType(name string) (ret linkType, stubs bool) { 912 switch name { 913 case "core.current.stubs", "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs", 914 "stub-annotations", "private-stub-annotations-jar", 915 "core-lambda-stubs", "core-generated-annotation-stubs": 916 return javaCore, true 917 case "android_stubs_current": 918 return javaSdk, true 919 case "android_system_stubs_current": 920 return javaSystem, true 921 case "android_module_lib_stubs_current": 922 return javaModule, true 923 case "android_system_server_stubs_current": 924 return javaSystemServer, true 925 case "android_test_stubs_current": 926 return javaSystem, true 927 } 928 929 if stub, linkType := moduleStubLinkType(name); stub { 930 return linkType, true 931 } 932 933 ver := m.sdkVersion() 934 switch ver.kind { 935 case sdkCore: 936 return javaCore, false 937 case sdkSystem: 938 return javaSystem, false 939 case sdkPublic: 940 return javaSdk, false 941 case sdkModule: 942 return javaModule, false 943 case sdkSystemServer: 944 return javaSystemServer, false 945 case sdkPrivate, sdkNone, sdkCorePlatform, sdkTest: 946 return javaPlatform, false 947 } 948 949 if !ver.valid() { 950 panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw)) 951 } 952 return javaSdk, false 953} 954 955func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, tag dependencyTag) { 956 if ctx.Host() { 957 return 958 } 959 960 myLinkType, stubs := from.getLinkType(ctx.ModuleName()) 961 if stubs { 962 return 963 } 964 otherLinkType, _ := to.getLinkType(ctx.OtherModuleName(to)) 965 commonMessage := "Adjust sdk_version: property of the source or target module so that target module is built with the same or smaller API set than the source." 966 967 switch myLinkType { 968 case javaCore: 969 if otherLinkType != javaCore { 970 ctx.ModuleErrorf("compiles against core Java API, but dependency %q is compiling against non-core Java APIs."+commonMessage, 971 ctx.OtherModuleName(to)) 972 } 973 break 974 case javaSdk: 975 if otherLinkType != javaCore && otherLinkType != javaSdk { 976 ctx.ModuleErrorf("compiles against Android API, but dependency %q is compiling against non-public Android API."+commonMessage, 977 ctx.OtherModuleName(to)) 978 } 979 break 980 case javaSystem: 981 if otherLinkType == javaPlatform || otherLinkType == javaModule || otherLinkType == javaSystemServer { 982 ctx.ModuleErrorf("compiles against system API, but dependency %q is compiling against private API."+commonMessage, 983 ctx.OtherModuleName(to)) 984 } 985 break 986 case javaModule: 987 if otherLinkType == javaPlatform || otherLinkType == javaSystemServer { 988 ctx.ModuleErrorf("compiles against module API, but dependency %q is compiling against private API."+commonMessage, 989 ctx.OtherModuleName(to)) 990 } 991 break 992 case javaSystemServer: 993 if otherLinkType == javaPlatform { 994 ctx.ModuleErrorf("compiles against system server API, but dependency %q is compiling against private API."+commonMessage, 995 ctx.OtherModuleName(to)) 996 } 997 break 998 case javaPlatform: 999 // no restriction on link-type 1000 break 1001 } 1002} 1003 1004func (j *Module) collectDeps(ctx android.ModuleContext) deps { 1005 var deps deps 1006 1007 if ctx.Device() { 1008 sdkDep := decodeSdkDep(ctx, sdkContext(j)) 1009 if sdkDep.invalidVersion { 1010 ctx.AddMissingDependencies(sdkDep.bootclasspath) 1011 ctx.AddMissingDependencies(sdkDep.java9Classpath) 1012 } else if sdkDep.useFiles { 1013 // sdkDep.jar is actually equivalent to turbine header.jar. 1014 deps.classpath = append(deps.classpath, sdkDep.jars...) 1015 deps.aidlPreprocess = sdkDep.aidl 1016 } else { 1017 deps.aidlPreprocess = sdkDep.aidl 1018 } 1019 } 1020 1021 // If this is a component library (stubs, etc.) for a java_sdk_library then 1022 // add the name of that java_sdk_library to the exported sdk libs to make sure 1023 // that, if necessary, a <uses-library> element for that java_sdk_library is 1024 // added to the Android manifest. 1025 j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...) 1026 1027 ctx.VisitDirectDeps(func(module android.Module) { 1028 otherName := ctx.OtherModuleName(module) 1029 tag := ctx.OtherModuleDependencyTag(module) 1030 1031 if _, ok := tag.(*jniDependencyTag); ok { 1032 // Handled by AndroidApp.collectAppDeps 1033 return 1034 } 1035 if tag == certificateTag { 1036 // Handled by AndroidApp.collectAppDeps 1037 return 1038 } 1039 1040 switch dep := module.(type) { 1041 case SdkLibraryDependency: 1042 switch tag { 1043 case libTag: 1044 deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...) 1045 // names of sdk libs that are directly depended are exported 1046 j.exportedSdkLibs = append(j.exportedSdkLibs, dep.OptionalImplicitSdkLibrary()...) 1047 case staticLibTag: 1048 ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName) 1049 } 1050 case Dependency: 1051 switch tag { 1052 case bootClasspathTag: 1053 deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...) 1054 case libTag, instrumentationForTag: 1055 deps.classpath = append(deps.classpath, dep.HeaderJars()...) 1056 // sdk lib names from dependencies are re-exported 1057 j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...) 1058 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) 1059 pluginJars, pluginClasses := dep.ExportedPlugins() 1060 addPlugins(&deps, pluginJars, pluginClasses...) 1061 case java9LibTag: 1062 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars()...) 1063 case staticLibTag: 1064 deps.classpath = append(deps.classpath, dep.HeaderJars()...) 1065 deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...) 1066 deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...) 1067 deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...) 1068 // sdk lib names from dependencies are re-exported 1069 j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...) 1070 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...) 1071 pluginJars, pluginClasses := dep.ExportedPlugins() 1072 addPlugins(&deps, pluginJars, pluginClasses...) 1073 case pluginTag: 1074 if plugin, ok := dep.(*Plugin); ok { 1075 if plugin.pluginProperties.Processor_class != nil { 1076 addPlugins(&deps, plugin.ImplementationAndResourcesJars(), *plugin.pluginProperties.Processor_class) 1077 } else { 1078 addPlugins(&deps, plugin.ImplementationAndResourcesJars()) 1079 } 1080 deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api) 1081 } else { 1082 ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName) 1083 } 1084 case exportedPluginTag: 1085 if plugin, ok := dep.(*Plugin); ok { 1086 if plugin.pluginProperties.Generates_api != nil && *plugin.pluginProperties.Generates_api { 1087 ctx.PropertyErrorf("exported_plugins", "Cannot export plugins with generates_api = true, found %v", otherName) 1088 } 1089 j.exportedPluginJars = append(j.exportedPluginJars, plugin.ImplementationAndResourcesJars()...) 1090 if plugin.pluginProperties.Processor_class != nil { 1091 j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class) 1092 } 1093 } else { 1094 ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName) 1095 } 1096 case frameworkApkTag: 1097 if ctx.ModuleName() == "android_stubs_current" || 1098 ctx.ModuleName() == "android_system_stubs_current" || 1099 ctx.ModuleName() == "android_test_stubs_current" { 1100 // framework stubs.jar need to depend on framework-res.apk, in order to pull the 1101 // resource files out of there for aapt. 1102 // 1103 // Normally the package rule runs aapt, which includes the resource, 1104 // but we're not running that in our package rule so just copy in the 1105 // resource files here. 1106 deps.staticResourceJars = append(deps.staticResourceJars, dep.(*AndroidApp).exportPackage) 1107 } 1108 case kotlinStdlibTag: 1109 deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars()...) 1110 case kotlinAnnotationsTag: 1111 deps.kotlinAnnotations = dep.HeaderJars() 1112 } 1113 1114 case android.SourceFileProducer: 1115 switch tag { 1116 case libTag: 1117 checkProducesJars(ctx, dep) 1118 deps.classpath = append(deps.classpath, dep.Srcs()...) 1119 case staticLibTag: 1120 checkProducesJars(ctx, dep) 1121 deps.classpath = append(deps.classpath, dep.Srcs()...) 1122 deps.staticJars = append(deps.staticJars, dep.Srcs()...) 1123 deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...) 1124 } 1125 default: 1126 switch tag { 1127 case bootClasspathTag: 1128 // If a system modules dependency has been added to the bootclasspath 1129 // then add its libs to the bootclasspath. 1130 sm := module.(SystemModulesProvider) 1131 deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...) 1132 1133 case systemModulesTag: 1134 if deps.systemModules != nil { 1135 panic("Found two system module dependencies") 1136 } 1137 sm := module.(SystemModulesProvider) 1138 outputDir, outputDeps := sm.OutputDirAndDeps() 1139 deps.systemModules = &systemModules{outputDir, outputDeps} 1140 } 1141 } 1142 }) 1143 1144 j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs) 1145 1146 return deps 1147} 1148 1149func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) { 1150 deps.processorPath = append(deps.processorPath, pluginJars...) 1151 deps.processorClasses = append(deps.processorClasses, pluginClasses...) 1152} 1153 1154func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext sdkContext) javaVersion { 1155 if javaVersion != "" { 1156 return normalizeJavaVersion(ctx, javaVersion) 1157 } else if ctx.Device() { 1158 return sdkContext.sdkVersion().defaultJavaLanguageVersion(ctx) 1159 } else { 1160 return JAVA_VERSION_9 1161 } 1162} 1163 1164type javaVersion int 1165 1166const ( 1167 JAVA_VERSION_UNSUPPORTED = 0 1168 JAVA_VERSION_6 = 6 1169 JAVA_VERSION_7 = 7 1170 JAVA_VERSION_8 = 8 1171 JAVA_VERSION_9 = 9 1172) 1173 1174func (v javaVersion) String() string { 1175 switch v { 1176 case JAVA_VERSION_6: 1177 return "1.6" 1178 case JAVA_VERSION_7: 1179 return "1.7" 1180 case JAVA_VERSION_8: 1181 return "1.8" 1182 case JAVA_VERSION_9: 1183 return "1.9" 1184 default: 1185 return "unsupported" 1186 } 1187} 1188 1189// Returns true if javac targeting this version uses system modules instead of a bootclasspath. 1190func (v javaVersion) usesJavaModules() bool { 1191 return v >= 9 1192} 1193 1194func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion { 1195 switch javaVersion { 1196 case "1.6", "6": 1197 return JAVA_VERSION_6 1198 case "1.7", "7": 1199 return JAVA_VERSION_7 1200 case "1.8", "8": 1201 return JAVA_VERSION_8 1202 case "1.9", "9": 1203 return JAVA_VERSION_9 1204 case "10", "11": 1205 ctx.PropertyErrorf("java_version", "Java language levels above 9 are not supported") 1206 return JAVA_VERSION_UNSUPPORTED 1207 default: 1208 ctx.PropertyErrorf("java_version", "Unrecognized Java language level") 1209 return JAVA_VERSION_UNSUPPORTED 1210 } 1211} 1212 1213func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags { 1214 1215 var flags javaBuilderFlags 1216 1217 // javaVersion flag. 1218 flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), sdkContext(j)) 1219 1220 // javac flags. 1221 javacFlags := j.properties.Javacflags 1222 if flags.javaVersion.usesJavaModules() { 1223 javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...) 1224 } 1225 if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() { 1226 // For non-host binaries, override the -g flag passed globally to remove 1227 // local variable debug info to reduce disk and memory usage. 1228 javacFlags = append(javacFlags, "-g:source,lines") 1229 } 1230 javacFlags = append(javacFlags, "-Xlint:-dep-ann") 1231 1232 if ctx.Config().RunErrorProne() { 1233 if config.ErrorProneClasspath == nil { 1234 ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?") 1235 } 1236 1237 errorProneFlags := []string{ 1238 "-Xplugin:ErrorProne", 1239 "${config.ErrorProneChecks}", 1240 } 1241 errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...) 1242 1243 flags.errorProneExtraJavacFlags = "${config.ErrorProneFlags} " + 1244 "'" + strings.Join(errorProneFlags, " ") + "'" 1245 flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath)) 1246 } 1247 1248 // classpath 1249 flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...) 1250 flags.classpath = append(flags.classpath, deps.classpath...) 1251 flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...) 1252 flags.processorPath = append(flags.processorPath, deps.processorPath...) 1253 1254 flags.processors = append(flags.processors, deps.processorClasses...) 1255 flags.processors = android.FirstUniqueStrings(flags.processors) 1256 1257 if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() && 1258 decodeSdkDep(ctx, sdkContext(j)).hasStandardLibs() { 1259 // Give host-side tools a version of OpenJDK's standard libraries 1260 // close to what they're targeting. As of Dec 2017, AOSP is only 1261 // bundling OpenJDK 8 and 9, so nothing < 8 is available. 1262 // 1263 // When building with OpenJDK 8, the following should have no 1264 // effect since those jars would be available by default. 1265 // 1266 // When building with OpenJDK 9 but targeting a version < 1.8, 1267 // putting them on the bootclasspath means that: 1268 // a) code can't (accidentally) refer to OpenJDK 9 specific APIs 1269 // b) references to existing APIs are not reinterpreted in an 1270 // OpenJDK 9-specific way, eg. calls to subclasses of 1271 // java.nio.Buffer as in http://b/70862583 1272 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME") 1273 flags.bootClasspath = append(flags.bootClasspath, 1274 android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"), 1275 android.PathForSource(ctx, java8Home, "jre/lib/rt.jar")) 1276 if Bool(j.properties.Use_tools_jar) { 1277 flags.bootClasspath = append(flags.bootClasspath, 1278 android.PathForSource(ctx, java8Home, "lib/tools.jar")) 1279 } 1280 } 1281 1282 if j.properties.Patch_module != nil && flags.javaVersion.usesJavaModules() { 1283 // Manually specify build directory in case it is not under the repo root. 1284 // (javac doesn't seem to expand into symbolc links when searching for patch-module targets, so 1285 // just adding a symlink under the root doesn't help.) 1286 patchPaths := ".:" + ctx.Config().BuildDir() 1287 classPath := flags.classpath.FormJavaClassPath("") 1288 if classPath != "" { 1289 patchPaths += ":" + classPath 1290 } 1291 javacFlags = append(javacFlags, "--patch-module="+String(j.properties.Patch_module)+"="+patchPaths) 1292 } 1293 1294 // systemModules 1295 flags.systemModules = deps.systemModules 1296 1297 // aidl flags. 1298 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs) 1299 1300 if len(javacFlags) > 0 { 1301 // optimization. 1302 ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " ")) 1303 flags.javacFlags = "$javacFlags" 1304 } 1305 1306 return flags 1307} 1308 1309func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { 1310 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs) 1311 1312 deps := j.collectDeps(ctx) 1313 flags := j.collectBuilderFlags(ctx, deps) 1314 1315 if flags.javaVersion.usesJavaModules() { 1316 j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...) 1317 } 1318 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) 1319 if hasSrcExt(srcFiles.Strings(), ".proto") { 1320 flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags) 1321 } 1322 1323 kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil) 1324 if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 { 1325 ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files") 1326 } 1327 1328 srcFiles = j.genSources(ctx, srcFiles, flags) 1329 1330 srcJars := srcFiles.FilterByExt(".srcjar") 1331 srcJars = append(srcJars, deps.srcJars...) 1332 if aaptSrcJar != nil { 1333 srcJars = append(srcJars, aaptSrcJar) 1334 } 1335 1336 if j.properties.Jarjar_rules != nil { 1337 j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules) 1338 } 1339 1340 jarName := ctx.ModuleName() + ".jar" 1341 1342 javaSrcFiles := srcFiles.FilterByExt(".java") 1343 var uniqueSrcFiles android.Paths 1344 set := make(map[string]bool) 1345 for _, v := range javaSrcFiles { 1346 if _, found := set[v.String()]; !found { 1347 set[v.String()] = true 1348 uniqueSrcFiles = append(uniqueSrcFiles, v) 1349 } 1350 } 1351 1352 // Collect .java files for AIDEGen 1353 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...) 1354 1355 var kotlinJars android.Paths 1356 1357 if srcFiles.HasExt(".kt") { 1358 // user defined kotlin flags. 1359 kotlincFlags := j.properties.Kotlincflags 1360 CheckKotlincFlags(ctx, kotlincFlags) 1361 1362 // If there are kotlin files, compile them first but pass all the kotlin and java files 1363 // kotlinc will use the java files to resolve types referenced by the kotlin files, but 1364 // won't emit any classes for them. 1365 kotlincFlags = append(kotlincFlags, "-no-stdlib") 1366 if ctx.Device() { 1367 kotlincFlags = append(kotlincFlags, "-no-jdk") 1368 } 1369 if len(kotlincFlags) > 0 { 1370 // optimization. 1371 ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " ")) 1372 flags.kotlincFlags += "$kotlincFlags" 1373 } 1374 1375 var kotlinSrcFiles android.Paths 1376 kotlinSrcFiles = append(kotlinSrcFiles, uniqueSrcFiles...) 1377 kotlinSrcFiles = append(kotlinSrcFiles, srcFiles.FilterByExt(".kt")...) 1378 1379 // Collect .kt files for AIDEGen 1380 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, srcFiles.FilterByExt(".kt").Strings()...) 1381 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...) 1382 1383 flags.classpath = append(flags.classpath, deps.kotlinStdlib...) 1384 flags.classpath = append(flags.classpath, deps.kotlinAnnotations...) 1385 1386 flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...) 1387 flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...) 1388 1389 if len(flags.processorPath) > 0 { 1390 // Use kapt for annotation processing 1391 kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar") 1392 kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar") 1393 kotlinKapt(ctx, kaptSrcJar, kaptResJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags) 1394 srcJars = append(srcJars, kaptSrcJar) 1395 kotlinJars = append(kotlinJars, kaptResJar) 1396 // Disable annotation processing in javac, it's already been handled by kapt 1397 flags.processorPath = nil 1398 flags.processors = nil 1399 } 1400 1401 kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName) 1402 kotlinCompile(ctx, kotlinJar, kotlinSrcFiles, kotlinCommonSrcFiles, srcJars, flags) 1403 if ctx.Failed() { 1404 return 1405 } 1406 1407 // Make javac rule depend on the kotlinc rule 1408 flags.classpath = append(flags.classpath, kotlinJar) 1409 1410 kotlinJars = append(kotlinJars, kotlinJar) 1411 // Jar kotlin classes into the final jar after javac 1412 if BoolDefault(j.properties.Static_kotlin_stdlib, true) { 1413 kotlinJars = append(kotlinJars, deps.kotlinStdlib...) 1414 } 1415 } 1416 1417 jars := append(android.Paths(nil), kotlinJars...) 1418 1419 // Store the list of .java files that was passed to javac 1420 j.compiledJavaSrcs = uniqueSrcFiles 1421 j.compiledSrcJars = srcJars 1422 1423 enable_sharding := false 1424 var headerJarFileWithoutJarjar android.Path 1425 if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !deps.disableTurbine { 1426 if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 { 1427 enable_sharding = true 1428 // Formerly, there was a check here that prevented annotation processors 1429 // from being used when sharding was enabled, as some annotation processors 1430 // do not function correctly in sharded environments. It was removed to 1431 // allow for the use of annotation processors that do function correctly 1432 // with sharding enabled. See: b/77284273. 1433 } 1434 headerJarFileWithoutJarjar, j.headerJarFile = 1435 j.compileJavaHeader(ctx, uniqueSrcFiles, srcJars, deps, flags, jarName, kotlinJars) 1436 if ctx.Failed() { 1437 return 1438 } 1439 } 1440 if len(uniqueSrcFiles) > 0 || len(srcJars) > 0 { 1441 var extraJarDeps android.Paths 1442 if ctx.Config().RunErrorProne() { 1443 // If error-prone is enabled, add an additional rule to compile the java files into 1444 // a separate set of classes (so that they don't overwrite the normal ones and require 1445 // a rebuild when error-prone is turned off). 1446 // TODO(ccross): Once we always compile with javac9 we may be able to conditionally 1447 // enable error-prone without affecting the output class files. 1448 errorprone := android.PathForModuleOut(ctx, "errorprone", jarName) 1449 RunErrorProne(ctx, errorprone, uniqueSrcFiles, srcJars, flags) 1450 extraJarDeps = append(extraJarDeps, errorprone) 1451 } 1452 1453 if enable_sharding { 1454 flags.classpath = append(flags.classpath, headerJarFileWithoutJarjar) 1455 shardSize := int(*(j.properties.Javac_shard_size)) 1456 var shardSrcs []android.Paths 1457 if len(uniqueSrcFiles) > 0 { 1458 shardSrcs = android.ShardPaths(uniqueSrcFiles, shardSize) 1459 for idx, shardSrc := range shardSrcs { 1460 classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc, 1461 nil, flags, extraJarDeps) 1462 jars = append(jars, classes) 1463 } 1464 } 1465 if len(srcJars) > 0 { 1466 classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs), 1467 nil, srcJars, flags, extraJarDeps) 1468 jars = append(jars, classes) 1469 } 1470 } else { 1471 classes := j.compileJavaClasses(ctx, jarName, -1, uniqueSrcFiles, srcJars, flags, extraJarDeps) 1472 jars = append(jars, classes) 1473 } 1474 if ctx.Failed() { 1475 return 1476 } 1477 } 1478 1479 j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles 1480 1481 var includeSrcJar android.WritablePath 1482 if Bool(j.properties.Include_srcs) { 1483 includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar") 1484 TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps) 1485 } 1486 1487 dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs, 1488 j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources) 1489 fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources) 1490 extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources 1491 1492 var resArgs []string 1493 var resDeps android.Paths 1494 1495 resArgs = append(resArgs, dirArgs...) 1496 resDeps = append(resDeps, dirDeps...) 1497 1498 resArgs = append(resArgs, fileArgs...) 1499 resDeps = append(resDeps, fileDeps...) 1500 1501 resArgs = append(resArgs, extraArgs...) 1502 resDeps = append(resDeps, extraDeps...) 1503 1504 if len(resArgs) > 0 { 1505 resourceJar := android.PathForModuleOut(ctx, "res", jarName) 1506 TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps) 1507 j.resourceJar = resourceJar 1508 if ctx.Failed() { 1509 return 1510 } 1511 } 1512 1513 var resourceJars android.Paths 1514 if j.resourceJar != nil { 1515 resourceJars = append(resourceJars, j.resourceJar) 1516 } 1517 if Bool(j.properties.Include_srcs) { 1518 resourceJars = append(resourceJars, includeSrcJar) 1519 } 1520 resourceJars = append(resourceJars, deps.staticResourceJars...) 1521 1522 if len(resourceJars) > 1 { 1523 combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName) 1524 TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{}, 1525 false, nil, nil) 1526 j.resourceJar = combinedJar 1527 } else if len(resourceJars) == 1 { 1528 j.resourceJar = resourceJars[0] 1529 } 1530 1531 if len(deps.staticJars) > 0 { 1532 jars = append(jars, deps.staticJars...) 1533 } 1534 1535 manifest := j.overrideManifest 1536 if !manifest.Valid() && j.properties.Manifest != nil { 1537 manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest)) 1538 } 1539 1540 services := android.PathsForModuleSrc(ctx, j.properties.Services) 1541 if len(services) > 0 { 1542 servicesJar := android.PathForModuleOut(ctx, "services", jarName) 1543 var zipargs []string 1544 for _, file := range services { 1545 serviceFile := file.String() 1546 zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile) 1547 } 1548 rule := zip 1549 args := map[string]string{ 1550 "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "), 1551 } 1552 if ctx.Config().IsEnvTrue("RBE_ZIP") { 1553 rule = zipRE 1554 args["implicits"] = strings.Join(services.Strings(), ",") 1555 } 1556 ctx.Build(pctx, android.BuildParams{ 1557 Rule: rule, 1558 Output: servicesJar, 1559 Implicits: services, 1560 Args: args, 1561 }) 1562 jars = append(jars, servicesJar) 1563 } 1564 1565 // Combine the classes built from sources, any manifests, and any static libraries into 1566 // classes.jar. If there is only one input jar this step will be skipped. 1567 var outputFile android.ModuleOutPath 1568 1569 if len(jars) == 1 && !manifest.Valid() { 1570 if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok { 1571 // Optimization: skip the combine step if there is nothing to do 1572 // TODO(ccross): this leaves any module-info.class files, but those should only come from 1573 // prebuilt dependencies until we support modules in the platform build, so there shouldn't be 1574 // any if len(jars) == 1. 1575 outputFile = moduleOutPath 1576 } else { 1577 combinedJar := android.PathForModuleOut(ctx, "combined", jarName) 1578 ctx.Build(pctx, android.BuildParams{ 1579 Rule: android.Cp, 1580 Input: jars[0], 1581 Output: combinedJar, 1582 }) 1583 outputFile = combinedJar 1584 } 1585 } else { 1586 combinedJar := android.PathForModuleOut(ctx, "combined", jarName) 1587 TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest, 1588 false, nil, nil) 1589 outputFile = combinedJar 1590 } 1591 1592 // jarjar implementation jar if necessary 1593 if j.expandJarjarRules != nil { 1594 // Transform classes.jar into classes-jarjar.jar 1595 jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName) 1596 TransformJarJar(ctx, jarjarFile, outputFile, j.expandJarjarRules) 1597 outputFile = jarjarFile 1598 1599 // jarjar resource jar if necessary 1600 if j.resourceJar != nil { 1601 resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName) 1602 TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, j.expandJarjarRules) 1603 j.resourceJar = resourceJarJarFile 1604 } 1605 1606 if ctx.Failed() { 1607 return 1608 } 1609 } 1610 1611 // Check package restrictions if necessary. 1612 if len(j.properties.Permitted_packages) > 0 { 1613 // Check packages and copy to package-checked file. 1614 pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp") 1615 CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages) 1616 j.additionalCheckedModules = append(j.additionalCheckedModules, pkgckFile) 1617 1618 if ctx.Failed() { 1619 return 1620 } 1621 } 1622 1623 j.implementationJarFile = outputFile 1624 if j.headerJarFile == nil { 1625 j.headerJarFile = j.implementationJarFile 1626 } 1627 1628 if j.shouldInstrumentInApex(ctx) { 1629 j.properties.Instrument = true 1630 } 1631 1632 if j.shouldInstrument(ctx) { 1633 outputFile = j.instrument(ctx, flags, outputFile, jarName) 1634 } 1635 1636 // merge implementation jar with resources if necessary 1637 implementationAndResourcesJar := outputFile 1638 if j.resourceJar != nil { 1639 jars := android.Paths{j.resourceJar, implementationAndResourcesJar} 1640 combinedJar := android.PathForModuleOut(ctx, "withres", jarName) 1641 TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest, 1642 false, nil, nil) 1643 implementationAndResourcesJar = combinedJar 1644 } 1645 1646 j.implementationAndResourcesJar = implementationAndResourcesJar 1647 1648 // Enable dex compilation for the APEX variants, unless it is disabled explicitly 1649 if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !j.IsForPlatform() { 1650 if j.deviceProperties.Compile_dex == nil { 1651 j.deviceProperties.Compile_dex = proptools.BoolPtr(true) 1652 } 1653 if j.deviceProperties.Hostdex == nil { 1654 j.deviceProperties.Hostdex = proptools.BoolPtr(true) 1655 } 1656 } 1657 1658 if ctx.Device() && j.hasCode(ctx) && 1659 (Bool(j.properties.Installable) || Bool(j.deviceProperties.Compile_dex)) { 1660 // Dex compilation 1661 var dexOutputFile android.ModuleOutPath 1662 dexOutputFile = j.compileDex(ctx, flags, outputFile, jarName) 1663 if ctx.Failed() { 1664 return 1665 } 1666 1667 configurationName := j.ConfigurationName() 1668 primary := configurationName == ctx.ModuleName() 1669 1670 // Hidden API CSV generation and dex encoding 1671 dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, configurationName, primary, dexOutputFile, j.implementationJarFile, 1672 proptools.Bool(j.deviceProperties.Uncompress_dex)) 1673 1674 // merge dex jar with resources if necessary 1675 if j.resourceJar != nil { 1676 jars := android.Paths{dexOutputFile, j.resourceJar} 1677 combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName) 1678 TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{}, 1679 false, nil, nil) 1680 if *j.deviceProperties.Uncompress_dex { 1681 combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName) 1682 TransformZipAlign(ctx, combinedAlignedJar, combinedJar) 1683 dexOutputFile = combinedAlignedJar 1684 } else { 1685 dexOutputFile = combinedJar 1686 } 1687 } 1688 1689 j.dexJarFile = dexOutputFile 1690 1691 // Dexpreopting 1692 dexOutputFile = j.dexpreopt(ctx, dexOutputFile) 1693 1694 j.maybeStrippedDexJarFile = dexOutputFile 1695 1696 outputFile = dexOutputFile 1697 1698 if ctx.Failed() { 1699 return 1700 } 1701 } else { 1702 outputFile = implementationAndResourcesJar 1703 } 1704 1705 if ctx.Device() { 1706 lintSDKVersionString := func(sdkSpec sdkSpec) string { 1707 if v := sdkSpec.version; v.isNumbered() { 1708 return v.String() 1709 } else { 1710 return ctx.Config().DefaultAppTargetSdk() 1711 } 1712 } 1713 1714 j.linter.name = ctx.ModuleName() 1715 j.linter.srcs = srcFiles 1716 j.linter.srcJars = srcJars 1717 j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...) 1718 j.linter.classes = j.implementationJarFile 1719 j.linter.minSdkVersion = lintSDKVersionString(j.minSdkVersion()) 1720 j.linter.targetSdkVersion = lintSDKVersionString(j.targetSdkVersion()) 1721 j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion()) 1722 j.linter.javaLanguageLevel = flags.javaVersion.String() 1723 j.linter.kotlinLanguageLevel = "1.3" 1724 if j.ApexName() != "" && ctx.Config().UnbundledBuildApps() { 1725 j.linter.buildModuleReportZip = true 1726 } 1727 j.linter.lint(ctx) 1728 } 1729 1730 ctx.CheckbuildFile(outputFile) 1731 1732 // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource 1733 j.outputFile = outputFile.WithoutRel() 1734} 1735 1736func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int, 1737 srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath { 1738 1739 kzipName := pathtools.ReplaceExtension(jarName, "kzip") 1740 if idx >= 0 { 1741 kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip" 1742 jarName += strconv.Itoa(idx) 1743 } 1744 1745 classes := android.PathForModuleOut(ctx, "javac", jarName) 1746 TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, flags, extraJarDeps) 1747 1748 if ctx.Config().EmitXrefRules() { 1749 extractionFile := android.PathForModuleOut(ctx, kzipName) 1750 emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps) 1751 j.kytheFiles = append(j.kytheFiles, extractionFile) 1752 } 1753 1754 return classes 1755} 1756 1757// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user, 1758// since some of these flags may be used internally. 1759func CheckKotlincFlags(ctx android.ModuleContext, flags []string) { 1760 for _, flag := range flags { 1761 flag = strings.TrimSpace(flag) 1762 1763 if !strings.HasPrefix(flag, "-") { 1764 ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag) 1765 } else if strings.HasPrefix(flag, "-Xintellij-plugin-root") { 1766 ctx.PropertyErrorf("kotlincflags", 1767 "Bad flag: `%s`, only use internal compiler for consistency.", flag) 1768 } else if inList(flag, config.KotlincIllegalFlags) { 1769 ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag) 1770 } else if flag == "-include-runtime" { 1771 ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag) 1772 } else { 1773 args := strings.Split(flag, " ") 1774 if args[0] == "-kotlin-home" { 1775 ctx.PropertyErrorf("kotlincflags", 1776 "Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag) 1777 } 1778 } 1779 } 1780} 1781 1782func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths, 1783 deps deps, flags javaBuilderFlags, jarName string, 1784 extraJars android.Paths) (headerJar, jarjarHeaderJar android.Path) { 1785 1786 var jars android.Paths 1787 if len(srcFiles) > 0 || len(srcJars) > 0 { 1788 // Compile java sources into turbine.jar. 1789 turbineJar := android.PathForModuleOut(ctx, "turbine", jarName) 1790 TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags) 1791 if ctx.Failed() { 1792 return nil, nil 1793 } 1794 jars = append(jars, turbineJar) 1795 } 1796 1797 jars = append(jars, extraJars...) 1798 1799 // Combine any static header libraries into classes-header.jar. If there is only 1800 // one input jar this step will be skipped. 1801 jars = append(jars, deps.staticHeaderJars...) 1802 1803 // we cannot skip the combine step for now if there is only one jar 1804 // since we have to strip META-INF/TRANSITIVE dir from turbine.jar 1805 combinedJar := android.PathForModuleOut(ctx, "turbine-combined", jarName) 1806 TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{}, 1807 false, nil, []string{"META-INF/TRANSITIVE"}) 1808 headerJar = combinedJar 1809 jarjarHeaderJar = combinedJar 1810 1811 if j.expandJarjarRules != nil { 1812 // Transform classes.jar into classes-jarjar.jar 1813 jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName) 1814 TransformJarJar(ctx, jarjarFile, headerJar, j.expandJarjarRules) 1815 jarjarHeaderJar = jarjarFile 1816 if ctx.Failed() { 1817 return nil, nil 1818 } 1819 } 1820 1821 return headerJar, jarjarHeaderJar 1822} 1823 1824func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags, 1825 classesJar android.Path, jarName string) android.ModuleOutPath { 1826 1827 specs := j.jacocoModuleToZipCommand(ctx) 1828 1829 jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName) 1830 instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName) 1831 1832 jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs) 1833 1834 j.jacocoReportClassesFile = jacocoReportClassesFile 1835 1836 return instrumentedJar 1837} 1838 1839var _ Dependency = (*Module)(nil) 1840 1841func (j *Module) HeaderJars() android.Paths { 1842 if j.headerJarFile == nil { 1843 return nil 1844 } 1845 return android.Paths{j.headerJarFile} 1846} 1847 1848func (j *Module) ImplementationJars() android.Paths { 1849 if j.implementationJarFile == nil { 1850 return nil 1851 } 1852 return android.Paths{j.implementationJarFile} 1853} 1854 1855func (j *Module) DexJarBuildPath() android.Path { 1856 return j.dexJarFile 1857} 1858 1859func (j *Module) DexJarInstallPath() android.Path { 1860 return j.installFile 1861} 1862 1863func (j *Module) ResourceJars() android.Paths { 1864 if j.resourceJar == nil { 1865 return nil 1866 } 1867 return android.Paths{j.resourceJar} 1868} 1869 1870func (j *Module) ImplementationAndResourcesJars() android.Paths { 1871 if j.implementationAndResourcesJar == nil { 1872 return nil 1873 } 1874 return android.Paths{j.implementationAndResourcesJar} 1875} 1876 1877func (j *Module) AidlIncludeDirs() android.Paths { 1878 // exportAidlIncludeDirs is type android.Paths already 1879 return j.exportAidlIncludeDirs 1880} 1881 1882func (j *Module) ExportedSdkLibs() []string { 1883 // exportedSdkLibs is type []string 1884 return j.exportedSdkLibs 1885} 1886 1887func (j *Module) ExportedPlugins() (android.Paths, []string) { 1888 return j.exportedPluginJars, j.exportedPluginClasses 1889} 1890 1891func (j *Module) SrcJarArgs() ([]string, android.Paths) { 1892 return j.srcJarArgs, j.srcJarDeps 1893} 1894 1895var _ logtagsProducer = (*Module)(nil) 1896 1897func (j *Module) logtags() android.Paths { 1898 return j.logtagsSrcs 1899} 1900 1901// Collect information for opening IDE project files in java/jdeps.go. 1902func (j *Module) IDEInfo(dpInfo *android.IdeInfo) { 1903 dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...) 1904 dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) 1905 dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) 1906 dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...) 1907 if j.expandJarjarRules != nil { 1908 dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String()) 1909 } 1910 dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...) 1911} 1912 1913func (j *Module) CompilerDeps() []string { 1914 jdeps := []string{} 1915 jdeps = append(jdeps, j.properties.Libs...) 1916 jdeps = append(jdeps, j.properties.Static_libs...) 1917 return jdeps 1918} 1919 1920func (j *Module) hasCode(ctx android.ModuleContext) bool { 1921 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) 1922 return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0 1923} 1924 1925func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 1926 return j.depIsInSameApex(ctx, dep) 1927} 1928 1929func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error { 1930 sdkSpec := j.minSdkVersion() 1931 if !sdkSpec.specified() { 1932 return fmt.Errorf("min_sdk_version is not specified") 1933 } 1934 if sdkSpec.kind == sdkCore { 1935 return nil 1936 } 1937 ver, err := sdkSpec.effectiveVersion(ctx) 1938 if err != nil { 1939 return err 1940 } 1941 if int(ver) > sdkVersion { 1942 return fmt.Errorf("newer SDK(%v)", ver) 1943 } 1944 return nil 1945} 1946 1947func (j *Module) Stem() string { 1948 return proptools.StringDefault(j.deviceProperties.Stem, j.Name()) 1949} 1950 1951func (j *Module) ConfigurationName() string { 1952 return proptools.StringDefault(j.deviceProperties.ConfigurationName, j.BaseModuleName()) 1953} 1954 1955func (j *Module) JacocoReportClassesFile() android.Path { 1956 return j.jacocoReportClassesFile 1957} 1958 1959func (j *Module) IsInstallable() bool { 1960 return Bool(j.properties.Installable) 1961} 1962 1963// 1964// Java libraries (.jar file) 1965// 1966 1967type Library struct { 1968 Module 1969 1970 InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) 1971} 1972 1973// Provides access to the list of permitted packages from updatable boot jars. 1974type PermittedPackagesForUpdatableBootJars interface { 1975 PermittedPackagesForUpdatableBootJars() []string 1976} 1977 1978var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil) 1979 1980func (j *Library) PermittedPackagesForUpdatableBootJars() []string { 1981 return j.properties.Permitted_packages 1982} 1983 1984func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { 1985 // Store uncompressed (and aligned) any dex files from jars in APEXes. 1986 if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() { 1987 return true 1988 } 1989 1990 // Store uncompressed (and do not strip) dex files from boot class path jars. 1991 if inList(ctx.ModuleName(), ctx.Config().BootJars()) { 1992 return true 1993 } 1994 1995 // Store uncompressed dex files that are preopted on /system. 1996 if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) { 1997 return true 1998 } 1999 if ctx.Config().UncompressPrivAppDex() && 2000 inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) { 2001 return true 2002 } 2003 2004 return false 2005} 2006 2007func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2008 j.checkSdkVersions(ctx) 2009 j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") 2010 j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary 2011 if j.deviceProperties.Uncompress_dex == nil { 2012 // If the value was not force-set by the user, use reasonable default based on the module. 2013 j.deviceProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter)) 2014 } 2015 j.dexpreopter.uncompressedDex = *j.deviceProperties.Uncompress_dex 2016 j.compile(ctx, nil) 2017 2018 // Collect the module directory for IDE info in java/jdeps.go. 2019 j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) 2020 2021 exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform() 2022 if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex { 2023 var extraInstallDeps android.Paths 2024 if j.InstallMixin != nil { 2025 extraInstallDeps = j.InstallMixin(ctx, j.outputFile) 2026 } 2027 j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 2028 j.Stem()+".jar", j.outputFile, extraInstallDeps...) 2029 } 2030 2031 j.distFiles = j.GenerateTaggedDistFiles(ctx) 2032} 2033 2034func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { 2035 j.deps(ctx) 2036} 2037 2038const ( 2039 aidlIncludeDir = "aidl" 2040 javaDir = "java" 2041 jarFileSuffix = ".jar" 2042 testConfigSuffix = "-AndroidTest.xml" 2043) 2044 2045// path to the jar file of a java library. Relative to <sdk_root>/<api_dir> 2046func sdkSnapshotFilePathForJar(osPrefix, name string) string { 2047 return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix) 2048} 2049 2050func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string { 2051 return filepath.Join(javaDir, osPrefix, name+suffix) 2052} 2053 2054type librarySdkMemberType struct { 2055 android.SdkMemberTypeBase 2056 2057 // Function to retrieve the appropriate output jar (implementation or header) from 2058 // the library. 2059 jarToExportGetter func(j *Library) android.Path 2060} 2061 2062func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { 2063 mctx.AddVariationDependencies(nil, dependencyTag, names...) 2064} 2065 2066func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { 2067 _, ok := module.(*Library) 2068 return ok 2069} 2070 2071func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 2072 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import") 2073} 2074 2075func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 2076 return &librarySdkMemberProperties{} 2077} 2078 2079type librarySdkMemberProperties struct { 2080 android.SdkMemberPropertiesBase 2081 2082 JarToExport android.Path `android:"arch_variant"` 2083 AidlIncludeDirs android.Paths 2084} 2085 2086func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 2087 j := variant.(*Library) 2088 2089 p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(j) 2090 p.AidlIncludeDirs = j.AidlIncludeDirs() 2091} 2092 2093func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 2094 builder := ctx.SnapshotBuilder() 2095 2096 exportedJar := p.JarToExport 2097 if exportedJar != nil { 2098 snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name()) 2099 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 2100 2101 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 2102 } 2103 2104 aidlIncludeDirs := p.AidlIncludeDirs 2105 if len(aidlIncludeDirs) != 0 { 2106 sdkModuleContext := ctx.SdkModuleContext() 2107 for _, dir := range aidlIncludeDirs { 2108 // TODO(jiyong): copy parcelable declarations only 2109 aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil) 2110 for _, file := range aidlFiles { 2111 builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file)) 2112 } 2113 } 2114 2115 // TODO(b/151933053) - add aidl include dirs property 2116 } 2117} 2118 2119var javaHeaderLibsSdkMemberType android.SdkMemberType = &librarySdkMemberType{ 2120 android.SdkMemberTypeBase{ 2121 PropertyName: "java_header_libs", 2122 SupportsSdk: true, 2123 }, 2124 func(j *Library) android.Path { 2125 headerJars := j.HeaderJars() 2126 if len(headerJars) != 1 { 2127 panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) 2128 } 2129 2130 return headerJars[0] 2131 }, 2132} 2133 2134// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well. 2135// 2136// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were 2137// compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used 2138// as a `static_libs` dependency of another module. 2139// 2140// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on 2141// a device. 2142// 2143// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 2144// compiled against the host bootclasspath. 2145func LibraryFactory() android.Module { 2146 module := &Library{} 2147 2148 module.addHostAndDeviceProperties() 2149 2150 module.initModuleAndImport(&module.ModuleBase) 2151 2152 android.InitApexModule(module) 2153 android.InitSdkAwareModule(module) 2154 InitJavaModule(module, android.HostAndDeviceSupported) 2155 return module 2156} 2157 2158// java_library_static is an obsolete alias for java_library. 2159func LibraryStaticFactory() android.Module { 2160 return LibraryFactory() 2161} 2162 2163// java_library_host builds and links sources into a `.jar` file for the host. 2164// 2165// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were 2166// compiled against the host bootclasspath. 2167func LibraryHostFactory() android.Module { 2168 module := &Library{} 2169 2170 module.addHostProperties() 2171 2172 module.Module.properties.Installable = proptools.BoolPtr(true) 2173 2174 android.InitApexModule(module) 2175 InitJavaModule(module, android.HostSupported) 2176 return module 2177} 2178 2179// 2180// Java Tests 2181// 2182 2183type testProperties struct { 2184 // list of compatibility suites (for example "cts", "vts") that the module should be 2185 // installed into. 2186 Test_suites []string `android:"arch_variant"` 2187 2188 // the name of the test configuration (for example "AndroidTest.xml") that should be 2189 // installed with the module. 2190 Test_config *string `android:"path,arch_variant"` 2191 2192 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 2193 // should be installed with the module. 2194 Test_config_template *string `android:"path,arch_variant"` 2195 2196 // list of files or filegroup modules that provide data that should be installed alongside 2197 // the test 2198 Data []string `android:"path"` 2199 2200 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 2201 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 2202 // explicitly. 2203 Auto_gen_config *bool 2204 2205 // Add parameterized mainline modules to auto generated test config. The options will be 2206 // handled by TradeFed to do downloading and installing the specified modules on the device. 2207 Test_mainline_modules []string 2208} 2209 2210type hostTestProperties struct { 2211 // list of native binary modules that should be installed alongside the test 2212 Data_native_bins []string `android:"arch_variant"` 2213} 2214 2215type testHelperLibraryProperties struct { 2216 // list of compatibility suites (for example "cts", "vts") that the module should be 2217 // installed into. 2218 Test_suites []string `android:"arch_variant"` 2219} 2220 2221type prebuiltTestProperties struct { 2222 // list of compatibility suites (for example "cts", "vts") that the module should be 2223 // installed into. 2224 Test_suites []string `android:"arch_variant"` 2225 2226 // the name of the test configuration (for example "AndroidTest.xml") that should be 2227 // installed with the module. 2228 Test_config *string `android:"path,arch_variant"` 2229} 2230 2231type Test struct { 2232 Library 2233 2234 testProperties testProperties 2235 2236 testConfig android.Path 2237 data android.Paths 2238} 2239 2240type TestHost struct { 2241 Test 2242 2243 testHostProperties hostTestProperties 2244} 2245 2246type TestHelperLibrary struct { 2247 Library 2248 2249 testHelperLibraryProperties testHelperLibraryProperties 2250} 2251 2252type JavaTestImport struct { 2253 Import 2254 2255 prebuiltTestProperties prebuiltTestProperties 2256 2257 testConfig android.Path 2258} 2259 2260func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { 2261 if len(j.testHostProperties.Data_native_bins) > 0 { 2262 for _, target := range ctx.MultiTargets() { 2263 ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...) 2264 } 2265 } 2266 2267 j.deps(ctx) 2268} 2269 2270func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2271 j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, 2272 j.testProperties.Test_suites, j.testProperties.Auto_gen_config) 2273 2274 j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data) 2275 2276 ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) { 2277 j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) 2278 }) 2279 2280 j.Library.GenerateAndroidBuildActions(ctx) 2281} 2282 2283func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2284 j.Library.GenerateAndroidBuildActions(ctx) 2285} 2286 2287func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2288 j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil, 2289 j.prebuiltTestProperties.Test_suites, nil) 2290 2291 j.Import.GenerateAndroidBuildActions(ctx) 2292} 2293 2294type testSdkMemberType struct { 2295 android.SdkMemberTypeBase 2296} 2297 2298func (mt *testSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { 2299 mctx.AddVariationDependencies(nil, dependencyTag, names...) 2300} 2301 2302func (mt *testSdkMemberType) IsInstance(module android.Module) bool { 2303 _, ok := module.(*Test) 2304 return ok 2305} 2306 2307func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 2308 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import") 2309} 2310 2311func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 2312 return &testSdkMemberProperties{} 2313} 2314 2315type testSdkMemberProperties struct { 2316 android.SdkMemberPropertiesBase 2317 2318 JarToExport android.Path 2319 TestConfig android.Path 2320} 2321 2322func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 2323 test := variant.(*Test) 2324 2325 implementationJars := test.ImplementationJars() 2326 if len(implementationJars) != 1 { 2327 panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name())) 2328 } 2329 2330 p.JarToExport = implementationJars[0] 2331 p.TestConfig = test.testConfig 2332} 2333 2334func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 2335 builder := ctx.SnapshotBuilder() 2336 2337 exportedJar := p.JarToExport 2338 if exportedJar != nil { 2339 snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name()) 2340 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 2341 2342 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 2343 } 2344 2345 testConfig := p.TestConfig 2346 if testConfig != nil { 2347 snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix) 2348 builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath) 2349 propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath) 2350 } 2351} 2352 2353// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and 2354// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file. 2355// 2356// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were 2357// compiled against the device bootclasspath. 2358// 2359// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 2360// compiled against the host bootclasspath. 2361func TestFactory() android.Module { 2362 module := &Test{} 2363 2364 module.addHostAndDeviceProperties() 2365 module.AddProperties(&module.testProperties) 2366 2367 module.Module.properties.Installable = proptools.BoolPtr(true) 2368 module.Module.dexpreopter.isTest = true 2369 module.Module.linter.test = true 2370 2371 InitJavaModule(module, android.HostAndDeviceSupported) 2372 return module 2373} 2374 2375// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite. 2376func TestHelperLibraryFactory() android.Module { 2377 module := &TestHelperLibrary{} 2378 2379 module.addHostAndDeviceProperties() 2380 module.AddProperties(&module.testHelperLibraryProperties) 2381 2382 module.Module.properties.Installable = proptools.BoolPtr(true) 2383 module.Module.dexpreopter.isTest = true 2384 module.Module.linter.test = true 2385 2386 InitJavaModule(module, android.HostAndDeviceSupported) 2387 return module 2388} 2389 2390// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module 2391// and makes sure that it is added to the appropriate test suite. 2392// 2393// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were 2394// compiled against an Android classpath. 2395// 2396// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 2397// for host modules. 2398func JavaTestImportFactory() android.Module { 2399 module := &JavaTestImport{} 2400 2401 module.AddProperties( 2402 &module.Import.properties, 2403 &module.prebuiltTestProperties) 2404 2405 module.Import.properties.Installable = proptools.BoolPtr(true) 2406 2407 android.InitPrebuiltModule(module, &module.properties.Jars) 2408 android.InitApexModule(module) 2409 android.InitSdkAwareModule(module) 2410 InitJavaModule(module, android.HostAndDeviceSupported) 2411 return module 2412} 2413 2414// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to 2415// allow running the test with `atest` or a `TEST_MAPPING` file. 2416// 2417// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were 2418// compiled against the host bootclasspath. 2419func TestHostFactory() android.Module { 2420 module := &TestHost{} 2421 2422 module.addHostProperties() 2423 module.AddProperties(&module.testProperties) 2424 module.AddProperties(&module.testHostProperties) 2425 2426 module.Module.properties.Installable = proptools.BoolPtr(true) 2427 2428 InitJavaModuleMultiTargets(module, android.HostSupported) 2429 return module 2430} 2431 2432// 2433// Java Binaries (.jar file plus wrapper script) 2434// 2435 2436type binaryProperties struct { 2437 // installable script to execute the resulting jar 2438 Wrapper *string `android:"path"` 2439 2440 // Name of the class containing main to be inserted into the manifest as Main-Class. 2441 Main_class *string 2442} 2443 2444type Binary struct { 2445 Library 2446 2447 binaryProperties binaryProperties 2448 2449 isWrapperVariant bool 2450 2451 wrapperFile android.Path 2452 binaryFile android.InstallPath 2453} 2454 2455func (j *Binary) HostToolPath() android.OptionalPath { 2456 return android.OptionalPathForPath(j.binaryFile) 2457} 2458 2459func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2460 if ctx.Arch().ArchType == android.Common { 2461 // Compile the jar 2462 if j.binaryProperties.Main_class != nil { 2463 if j.properties.Manifest != nil { 2464 ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set") 2465 } 2466 manifestFile := android.PathForModuleOut(ctx, "manifest.txt") 2467 GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class)) 2468 j.overrideManifest = android.OptionalPathForPath(manifestFile) 2469 } 2470 2471 j.Library.GenerateAndroidBuildActions(ctx) 2472 } else { 2473 // Handle the binary wrapper 2474 j.isWrapperVariant = true 2475 2476 if j.binaryProperties.Wrapper != nil { 2477 j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper) 2478 } else { 2479 j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") 2480 } 2481 2482 // Depend on the installed jar so that the wrapper doesn't get executed by 2483 // another build rule before the jar has been installed. 2484 jarFile := ctx.PrimaryModule().(*Binary).installFile 2485 2486 j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), 2487 ctx.ModuleName(), j.wrapperFile, jarFile) 2488 } 2489} 2490 2491func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { 2492 if ctx.Arch().ArchType == android.Common { 2493 j.deps(ctx) 2494 } 2495} 2496 2497// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host 2498// as well. 2499// 2500// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were 2501// compiled against the device bootclasspath. 2502// 2503// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 2504// compiled against the host bootclasspath. 2505func BinaryFactory() android.Module { 2506 module := &Binary{} 2507 2508 module.addHostAndDeviceProperties() 2509 module.AddProperties(&module.binaryProperties) 2510 2511 module.Module.properties.Installable = proptools.BoolPtr(true) 2512 2513 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) 2514 android.InitDefaultableModule(module) 2515 return module 2516} 2517 2518// java_binary_host builds a `.jar` file and a shell script that executes it for the host. 2519// 2520// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were 2521// compiled against the host bootclasspath. 2522func BinaryHostFactory() android.Module { 2523 module := &Binary{} 2524 2525 module.addHostProperties() 2526 module.AddProperties(&module.binaryProperties) 2527 2528 module.Module.properties.Installable = proptools.BoolPtr(true) 2529 2530 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) 2531 android.InitDefaultableModule(module) 2532 return module 2533} 2534 2535// 2536// Java prebuilts 2537// 2538 2539type ImportProperties struct { 2540 Jars []string `android:"path,arch_variant"` 2541 2542 Sdk_version *string 2543 2544 Installable *bool 2545 2546 // List of shared java libs that this module has dependencies to 2547 Libs []string 2548 2549 // List of files to remove from the jar file(s) 2550 Exclude_files []string 2551 2552 // List of directories to remove from the jar file(s) 2553 Exclude_dirs []string 2554 2555 // if set to true, run Jetifier against .jar file. Defaults to false. 2556 Jetifier *bool 2557 2558 // set the name of the output 2559 Stem *string 2560 2561 Aidl struct { 2562 // directories that should be added as include directories for any aidl sources of modules 2563 // that depend on this module, as well as to aidl for this module. 2564 Export_include_dirs []string 2565 } 2566} 2567 2568type Import struct { 2569 android.ModuleBase 2570 android.DefaultableModuleBase 2571 android.ApexModuleBase 2572 prebuilt android.Prebuilt 2573 android.SdkBase 2574 2575 // Functionality common to Module and Import. 2576 embeddableInModuleAndImport 2577 2578 properties ImportProperties 2579 2580 combinedClasspathFile android.Path 2581 exportedSdkLibs []string 2582 exportAidlIncludeDirs android.Paths 2583} 2584 2585func (j *Import) sdkVersion() sdkSpec { 2586 return sdkSpecFrom(String(j.properties.Sdk_version)) 2587} 2588 2589func (j *Import) minSdkVersion() sdkSpec { 2590 return j.sdkVersion() 2591} 2592 2593func (j *Import) MinSdkVersion() string { 2594 return j.minSdkVersion().version.String() 2595} 2596 2597func (j *Import) Prebuilt() *android.Prebuilt { 2598 return &j.prebuilt 2599} 2600 2601func (j *Import) PrebuiltSrcs() []string { 2602 return j.properties.Jars 2603} 2604 2605func (j *Import) Name() string { 2606 return j.prebuilt.Name(j.ModuleBase.Name()) 2607} 2608 2609func (j *Import) Stem() string { 2610 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 2611} 2612 2613func (a *Import) JacocoReportClassesFile() android.Path { 2614 return nil 2615} 2616 2617func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { 2618 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) 2619} 2620 2621func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2622 jars := android.PathsForModuleSrc(ctx, j.properties.Jars) 2623 2624 jarName := j.Stem() + ".jar" 2625 outputFile := android.PathForModuleOut(ctx, "combined", jarName) 2626 TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{}, 2627 false, j.properties.Exclude_files, j.properties.Exclude_dirs) 2628 if Bool(j.properties.Jetifier) { 2629 inputFile := outputFile 2630 outputFile = android.PathForModuleOut(ctx, "jetifier", jarName) 2631 TransformJetifier(ctx, outputFile, inputFile) 2632 } 2633 j.combinedClasspathFile = outputFile 2634 2635 // If this is a component library (impl, stubs, etc.) for a java_sdk_library then 2636 // add the name of that java_sdk_library to the exported sdk libs to make sure 2637 // that, if necessary, a <uses-library> element for that java_sdk_library is 2638 // added to the Android manifest. 2639 j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...) 2640 2641 ctx.VisitDirectDeps(func(module android.Module) { 2642 otherName := ctx.OtherModuleName(module) 2643 tag := ctx.OtherModuleDependencyTag(module) 2644 2645 switch dep := module.(type) { 2646 case Dependency: 2647 switch tag { 2648 case libTag, staticLibTag: 2649 // sdk lib names from dependencies are re-exported 2650 j.exportedSdkLibs = append(j.exportedSdkLibs, dep.ExportedSdkLibs()...) 2651 } 2652 case SdkLibraryDependency: 2653 switch tag { 2654 case libTag: 2655 // names of sdk libs that are directly depended are exported 2656 j.exportedSdkLibs = append(j.exportedSdkLibs, otherName) 2657 } 2658 } 2659 }) 2660 2661 j.exportedSdkLibs = android.FirstUniqueStrings(j.exportedSdkLibs) 2662 if Bool(j.properties.Installable) { 2663 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 2664 jarName, outputFile) 2665 } 2666 2667 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) 2668} 2669 2670var _ Dependency = (*Import)(nil) 2671 2672func (j *Import) HeaderJars() android.Paths { 2673 if j.combinedClasspathFile == nil { 2674 return nil 2675 } 2676 return android.Paths{j.combinedClasspathFile} 2677} 2678 2679func (j *Import) ImplementationJars() android.Paths { 2680 if j.combinedClasspathFile == nil { 2681 return nil 2682 } 2683 return android.Paths{j.combinedClasspathFile} 2684} 2685 2686func (j *Import) ResourceJars() android.Paths { 2687 return nil 2688} 2689 2690func (j *Import) ImplementationAndResourcesJars() android.Paths { 2691 if j.combinedClasspathFile == nil { 2692 return nil 2693 } 2694 return android.Paths{j.combinedClasspathFile} 2695} 2696 2697func (j *Import) DexJarBuildPath() android.Path { 2698 return nil 2699} 2700 2701func (j *Import) DexJarInstallPath() android.Path { 2702 return nil 2703} 2704 2705func (j *Import) AidlIncludeDirs() android.Paths { 2706 return j.exportAidlIncludeDirs 2707} 2708 2709func (j *Import) ExportedSdkLibs() []string { 2710 return j.exportedSdkLibs 2711} 2712 2713func (j *Import) ExportedPlugins() (android.Paths, []string) { 2714 return nil, nil 2715} 2716 2717func (j *Import) SrcJarArgs() ([]string, android.Paths) { 2718 return nil, nil 2719} 2720 2721func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 2722 return j.depIsInSameApex(ctx, dep) 2723} 2724 2725func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error { 2726 // Do not check for prebuilts against the min_sdk_version of enclosing APEX 2727 return nil 2728} 2729 2730// Add compile time check for interface implementation 2731var _ android.IDEInfo = (*Import)(nil) 2732var _ android.IDECustomizedModuleName = (*Import)(nil) 2733 2734// Collect information for opening IDE project files in java/jdeps.go. 2735const ( 2736 removedPrefix = "prebuilt_" 2737) 2738 2739func (j *Import) IDEInfo(dpInfo *android.IdeInfo) { 2740 dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...) 2741} 2742 2743func (j *Import) IDECustomizedModuleName() string { 2744 // TODO(b/113562217): Extract the base module name from the Import name, often the Import name 2745 // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better 2746 // solution to get the Import name. 2747 name := j.Name() 2748 if strings.HasPrefix(name, removedPrefix) { 2749 name = strings.TrimPrefix(name, removedPrefix) 2750 } 2751 return name 2752} 2753 2754var _ android.PrebuiltInterface = (*Import)(nil) 2755 2756// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module. 2757// 2758// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were 2759// compiled against an Android classpath. 2760// 2761// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 2762// for host modules. 2763func ImportFactory() android.Module { 2764 module := &Import{} 2765 2766 module.AddProperties(&module.properties) 2767 2768 module.initModuleAndImport(&module.ModuleBase) 2769 2770 android.InitPrebuiltModule(module, &module.properties.Jars) 2771 android.InitApexModule(module) 2772 android.InitSdkAwareModule(module) 2773 InitJavaModule(module, android.HostAndDeviceSupported) 2774 return module 2775} 2776 2777// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host 2778// module. 2779// 2780// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were 2781// compiled against a host bootclasspath. 2782func ImportFactoryHost() android.Module { 2783 module := &Import{} 2784 2785 module.AddProperties(&module.properties) 2786 2787 android.InitPrebuiltModule(module, &module.properties.Jars) 2788 android.InitApexModule(module) 2789 InitJavaModule(module, android.HostSupported) 2790 return module 2791} 2792 2793// dex_import module 2794 2795type DexImportProperties struct { 2796 Jars []string `android:"path"` 2797 2798 // set the name of the output 2799 Stem *string 2800} 2801 2802type DexImport struct { 2803 android.ModuleBase 2804 android.DefaultableModuleBase 2805 android.ApexModuleBase 2806 prebuilt android.Prebuilt 2807 2808 properties DexImportProperties 2809 2810 dexJarFile android.Path 2811 maybeStrippedDexJarFile android.Path 2812 2813 dexpreopter 2814} 2815 2816func (j *DexImport) Prebuilt() *android.Prebuilt { 2817 return &j.prebuilt 2818} 2819 2820func (j *DexImport) PrebuiltSrcs() []string { 2821 return j.properties.Jars 2822} 2823 2824func (j *DexImport) Name() string { 2825 return j.prebuilt.Name(j.ModuleBase.Name()) 2826} 2827 2828func (j *DexImport) Stem() string { 2829 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 2830} 2831 2832func (a *DexImport) JacocoReportClassesFile() android.Path { 2833 return nil 2834} 2835 2836func (a *DexImport) LintDepSets() LintDepSets { 2837 return LintDepSets{} 2838} 2839 2840func (j *DexImport) IsInstallable() bool { 2841 return true 2842} 2843 2844func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2845 if len(j.properties.Jars) != 1 { 2846 ctx.PropertyErrorf("jars", "exactly one jar must be provided") 2847 } 2848 2849 j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") 2850 j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) 2851 2852 inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") 2853 dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar") 2854 2855 if j.dexpreopter.uncompressedDex { 2856 rule := android.NewRuleBuilder() 2857 2858 temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned") 2859 rule.Temporary(temporary) 2860 2861 // use zip2zip to uncompress classes*.dex files 2862 rule.Command(). 2863 BuiltTool(ctx, "zip2zip"). 2864 FlagWithInput("-i ", inputJar). 2865 FlagWithOutput("-o ", temporary). 2866 FlagWithArg("-0 ", "'classes*.dex'") 2867 2868 // use zipalign to align uncompressed classes*.dex files 2869 rule.Command(). 2870 BuiltTool(ctx, "zipalign"). 2871 Flag("-f"). 2872 Text("4"). 2873 Input(temporary). 2874 Output(dexOutputFile) 2875 2876 rule.DeleteTemporaryFiles() 2877 2878 rule.Build(pctx, ctx, "uncompress_dex", "uncompress dex") 2879 } else { 2880 ctx.Build(pctx, android.BuildParams{ 2881 Rule: android.Cp, 2882 Input: inputJar, 2883 Output: dexOutputFile, 2884 }) 2885 } 2886 2887 j.dexJarFile = dexOutputFile 2888 2889 dexOutputFile = j.dexpreopt(ctx, dexOutputFile) 2890 2891 j.maybeStrippedDexJarFile = dexOutputFile 2892 2893 if j.IsForPlatform() { 2894 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 2895 j.Stem()+".jar", dexOutputFile) 2896 } 2897} 2898 2899func (j *DexImport) DexJarBuildPath() android.Path { 2900 return j.dexJarFile 2901} 2902 2903func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion int) error { 2904 // we don't check prebuilt modules for sdk_version 2905 return nil 2906} 2907 2908// dex_import imports a `.jar` file containing classes.dex files. 2909// 2910// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed 2911// to the device. 2912func DexImportFactory() android.Module { 2913 module := &DexImport{} 2914 2915 module.AddProperties(&module.properties) 2916 2917 android.InitPrebuiltModule(module, &module.properties.Jars) 2918 android.InitApexModule(module) 2919 InitJavaModule(module, android.DeviceSupported) 2920 return module 2921} 2922 2923// 2924// Defaults 2925// 2926type Defaults struct { 2927 android.ModuleBase 2928 android.DefaultsModuleBase 2929 android.ApexModuleBase 2930} 2931 2932// java_defaults provides a set of properties that can be inherited by other java or android modules. 2933// 2934// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`. Each 2935// property in the defaults module that exists in the depending module will be prepended to the depending module's 2936// value for that property. 2937// 2938// Example: 2939// 2940// java_defaults { 2941// name: "example_defaults", 2942// srcs: ["common/**/*.java"], 2943// javacflags: ["-Xlint:all"], 2944// aaptflags: ["--auto-add-overlay"], 2945// } 2946// 2947// java_library { 2948// name: "example", 2949// defaults: ["example_defaults"], 2950// srcs: ["example/**/*.java"], 2951// } 2952// 2953// is functionally identical to: 2954// 2955// java_library { 2956// name: "example", 2957// srcs: [ 2958// "common/**/*.java", 2959// "example/**/*.java", 2960// ], 2961// javacflags: ["-Xlint:all"], 2962// } 2963func defaultsFactory() android.Module { 2964 return DefaultsFactory() 2965} 2966 2967func DefaultsFactory() android.Module { 2968 module := &Defaults{} 2969 2970 module.AddProperties( 2971 &CompilerProperties{}, 2972 &CompilerDeviceProperties{}, 2973 &DexpreoptProperties{}, 2974 &android.ProtoProperties{}, 2975 &aaptProperties{}, 2976 &androidLibraryProperties{}, 2977 &appProperties{}, 2978 &appTestProperties{}, 2979 &overridableAppProperties{}, 2980 &testProperties{}, 2981 &ImportProperties{}, 2982 &AARImportProperties{}, 2983 &sdkLibraryProperties{}, 2984 &commonToSdkLibraryAndImportProperties{}, 2985 &DexImportProperties{}, 2986 &android.ApexProperties{}, 2987 &RuntimeResourceOverlayProperties{}, 2988 &LintProperties{}, 2989 ) 2990 2991 android.InitDefaultsModule(module) 2992 return module 2993} 2994 2995func kytheExtractJavaFactory() android.Singleton { 2996 return &kytheExtractJavaSingleton{} 2997} 2998 2999type kytheExtractJavaSingleton struct { 3000} 3001 3002func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) { 3003 var xrefTargets android.Paths 3004 ctx.VisitAllModules(func(module android.Module) { 3005 if javaModule, ok := module.(xref); ok { 3006 xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...) 3007 } 3008 }) 3009 // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets 3010 if len(xrefTargets) > 0 { 3011 ctx.Phony("xref_java", xrefTargets...) 3012 } 3013} 3014 3015var Bool = proptools.Bool 3016var BoolDefault = proptools.BoolDefault 3017var String = proptools.String 3018var inList = android.InList 3019