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