1// Copyright 2021 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 17import ( 18 "fmt" 19 "path/filepath" 20 "strconv" 21 "strings" 22 23 "github.com/google/blueprint/pathtools" 24 "github.com/google/blueprint/proptools" 25 26 "android/soong/android" 27 "android/soong/dexpreopt" 28 "android/soong/java/config" 29) 30 31// This file contains the definition and the implementation of the base module that most 32// source-based Java module structs embed. 33 34// TODO: 35// Autogenerated files: 36// Renderscript 37// Post-jar passes: 38// Proguard 39// Rmtypedefs 40// DroidDoc 41// Findbugs 42 43// Properties that are common to most Java modules, i.e. whether it's a host or device module. 44type CommonProperties struct { 45 // list of source files used to compile the Java module. May be .java, .kt, .logtags, .proto, 46 // or .aidl files. 47 Srcs []string `android:"path,arch_variant"` 48 49 // list Kotlin of source files containing Kotlin code that should be treated as common code in 50 // a codebase that supports Kotlin multiplatform. See 51 // https://kotlinlang.org/docs/reference/multiplatform.html. May be only be .kt files. 52 Common_srcs []string `android:"path,arch_variant"` 53 54 // list of source files that should not be used to build the Java module. 55 // This is most useful in the arch/multilib variants to remove non-common files 56 Exclude_srcs []string `android:"path,arch_variant"` 57 58 // list of directories containing Java resources 59 Java_resource_dirs []string `android:"arch_variant"` 60 61 // list of directories that should be excluded from java_resource_dirs 62 Exclude_java_resource_dirs []string `android:"arch_variant"` 63 64 // list of files to use as Java resources 65 Java_resources []string `android:"path,arch_variant"` 66 67 // list of files that should be excluded from java_resources and java_resource_dirs 68 Exclude_java_resources []string `android:"path,arch_variant"` 69 70 // list of module-specific flags that will be used for javac compiles 71 Javacflags []string `android:"arch_variant"` 72 73 // list of module-specific flags that will be used for kotlinc compiles 74 Kotlincflags []string `android:"arch_variant"` 75 76 // list of java libraries that will be in the classpath 77 Libs []string `android:"arch_variant"` 78 79 // list of java libraries that will be compiled into the resulting jar 80 Static_libs []string `android:"arch_variant"` 81 82 // manifest file to be included in resulting jar 83 Manifest *string `android:"path"` 84 85 // if not blank, run jarjar using the specified rules file 86 Jarjar_rules *string `android:"path,arch_variant"` 87 88 // If not blank, set the java version passed to javac as -source and -target 89 Java_version *string 90 91 // If set to true, allow this module to be dexed and installed on devices. Has no 92 // effect on host modules, which are always considered installable. 93 Installable *bool 94 95 // If set to true, include sources used to compile the module in to the final jar 96 Include_srcs *bool 97 98 // If not empty, classes are restricted to the specified packages and their sub-packages. 99 // This restriction is checked after applying jarjar rules and including static libs. 100 Permitted_packages []string 101 102 // List of modules to use as annotation processors 103 Plugins []string 104 105 // List of modules to export to libraries that directly depend on this library as annotation 106 // processors. Note that if the plugins set generates_api: true this will disable the turbine 107 // optimization on modules that depend on this module, which will reduce parallelism and cause 108 // more recompilation. 109 Exported_plugins []string 110 111 // The number of Java source entries each Javac instance can process 112 Javac_shard_size *int64 113 114 // Add host jdk tools.jar to bootclasspath 115 Use_tools_jar *bool 116 117 Openjdk9 struct { 118 // List of source files that should only be used when passing -source 1.9 or higher 119 Srcs []string `android:"path"` 120 121 // List of javac flags that should only be used when passing -source 1.9 or higher 122 Javacflags []string 123 } 124 125 // When compiling language level 9+ .java code in packages that are part of 126 // a system module, patch_module names the module that your sources and 127 // dependencies should be patched into. The Android runtime currently 128 // doesn't implement the JEP 261 module system so this option is only 129 // supported at compile time. It should only be needed to compile tests in 130 // packages that exist in libcore and which are inconvenient to move 131 // elsewhere. 132 Patch_module *string `android:"arch_variant"` 133 134 Jacoco struct { 135 // List of classes to include for instrumentation with jacoco to collect coverage 136 // information at runtime when building with coverage enabled. If unset defaults to all 137 // classes. 138 // Supports '*' as the last character of an entry in the list as a wildcard match. 139 // If preceded by '.' it matches all classes in the package and subpackages, otherwise 140 // it matches classes in the package that have the class name as a prefix. 141 Include_filter []string 142 143 // List of classes to exclude from instrumentation with jacoco to collect coverage 144 // information at runtime when building with coverage enabled. Overrides classes selected 145 // by the include_filter property. 146 // Supports '*' as the last character of an entry in the list as a wildcard match. 147 // If preceded by '.' it matches all classes in the package and subpackages, otherwise 148 // it matches classes in the package that have the class name as a prefix. 149 Exclude_filter []string 150 } 151 152 Errorprone struct { 153 // List of javac flags that should only be used when running errorprone. 154 Javacflags []string 155 156 // List of java_plugin modules that provide extra errorprone checks. 157 Extra_check_modules []string 158 159 // This property can be in 3 states. When set to true, errorprone will 160 // be run during the regular build. When set to false, errorprone will 161 // never be run. When unset, errorprone will be run when the RUN_ERROR_PRONE 162 // environment variable is true. Setting this to false will improve build 163 // performance more than adding -XepDisableAllChecks in javacflags. 164 Enabled *bool 165 } 166 167 Proto struct { 168 // List of extra options that will be passed to the proto generator. 169 Output_params []string 170 } 171 172 // If true, then jacocoagent is automatically added as a libs dependency so that 173 // r8 will not strip instrumentation classes out of dexed libraries. 174 Instrument bool `blueprint:"mutated"` 175 // If true, then the module supports statically including the jacocoagent 176 // into the library. 177 Supports_static_instrumentation bool `blueprint:"mutated"` 178 179 // List of files to include in the META-INF/services folder of the resulting jar. 180 Services []string `android:"path,arch_variant"` 181 182 // If true, package the kotlin stdlib into the jar. Defaults to true. 183 Static_kotlin_stdlib *bool `android:"arch_variant"` 184 185 // A list of java_library instances that provide additional hiddenapi annotations for the library. 186 Hiddenapi_additional_annotations []string 187} 188 189// Properties that are specific to device modules. Host module factories should not add these when 190// constructing a new module. 191type DeviceProperties struct { 192 // If not blank, set to the version of the sdk to compile against. 193 // Defaults to an empty string, which compiles the module against the private platform APIs. 194 // Values are of one of the following forms: 195 // 1) numerical API level, "current", "none", or "core_platform" 196 // 2) An SDK kind with an API level: "<sdk kind>_<API level>" 197 // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds. 198 // If the SDK kind is empty, it will be set to public. 199 Sdk_version *string 200 201 // if not blank, set the minimum version of the sdk that the compiled artifacts will run against. 202 // Defaults to sdk_version if not set. See sdk_version for possible values. 203 Min_sdk_version *string 204 205 // if not blank, set the maximum version of the sdk that the compiled artifacts will run against. 206 // Defaults to empty string "". See sdk_version for possible values. 207 Max_sdk_version *string 208 209 // if not blank, set the maxSdkVersion properties of permission and uses-permission tags. 210 // Defaults to empty string "". See sdk_version for possible values. 211 Replace_max_sdk_version_placeholder *string 212 213 // if not blank, set the targetSdkVersion in the AndroidManifest.xml. 214 // Defaults to sdk_version if not set. See sdk_version for possible values. 215 Target_sdk_version *string 216 217 // Whether to compile against the platform APIs instead of an SDK. 218 // If true, then sdk_version must be empty. The value of this field 219 // is ignored when module's type isn't android_app, android_test, or android_test_helper_app. 220 Platform_apis *bool 221 222 Aidl struct { 223 // Top level directories to pass to aidl tool 224 Include_dirs []string 225 226 // Directories rooted at the Android.bp file to pass to aidl tool 227 Local_include_dirs []string 228 229 // directories that should be added as include directories for any aidl sources of modules 230 // that depend on this module, as well as to aidl for this module. 231 Export_include_dirs []string 232 233 // whether to generate traces (for systrace) for this interface 234 Generate_traces *bool 235 236 // whether to generate Binder#GetTransaction name method. 237 Generate_get_transaction_name *bool 238 239 // whether all interfaces should be annotated with required permissions. 240 Enforce_permissions *bool 241 242 // allowlist for interfaces that (temporarily) do not require annotation for permissions. 243 Enforce_permissions_exceptions []string `android:"path"` 244 245 // list of flags that will be passed to the AIDL compiler 246 Flags []string 247 } 248 249 // If true, export a copy of the module as a -hostdex module for host testing. 250 Hostdex *bool 251 252 Target struct { 253 Hostdex struct { 254 // Additional required dependencies to add to -hostdex modules. 255 Required []string 256 } 257 } 258 259 // When targeting 1.9 and above, override the modules to use with --system, 260 // otherwise provides defaults libraries to add to the bootclasspath. 261 System_modules *string 262 263 IsSDKLibrary bool `blueprint:"mutated"` 264 265 // If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file. 266 // Defaults to false. 267 V4_signature *bool 268 269 // Only for libraries created by a sysprop_library module, SyspropPublicStub is the name of the 270 // public stubs library. 271 SyspropPublicStub string `blueprint:"mutated"` 272 273 HiddenAPIPackageProperties 274 HiddenAPIFlagFileProperties 275} 276 277// Device properties that can be overridden by overriding module (e.g. override_android_app) 278type OverridableDeviceProperties struct { 279 // set the name of the output. If not set, `name` is used. 280 // To override a module with this property set, overriding module might need to set this as well. 281 // Otherwise, both the overridden and the overriding modules will have the same output name, which 282 // can cause the duplicate output error. 283 Stem *string 284} 285 286// Functionality common to Module and Import 287// 288// It is embedded in Module so its functionality can be used by methods in Module 289// but it is currently only initialized by Import and Library. 290type embeddableInModuleAndImport struct { 291 292 // Functionality related to this being used as a component of a java_sdk_library. 293 EmbeddableSdkLibraryComponent 294} 295 296func (e *embeddableInModuleAndImport) initModuleAndImport(module android.Module) { 297 e.initSdkLibraryComponent(module) 298} 299 300// Module/Import's DepIsInSameApex(...) delegates to this method. 301// 302// This cannot implement DepIsInSameApex(...) directly as that leads to ambiguity with 303// the one provided by ApexModuleBase. 304func (e *embeddableInModuleAndImport) depIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 305 // dependencies other than the static linkage are all considered crossing APEX boundary 306 if staticLibTag == ctx.OtherModuleDependencyTag(dep) { 307 return true 308 } 309 return false 310} 311 312// OptionalDexJarPath can be either unset, hold a valid path to a dex jar file, 313// or an invalid path describing the reason it is invalid. 314// 315// It is unset if a dex jar isn't applicable, i.e. no build rule has been 316// requested to create one. 317// 318// If a dex jar has been requested to be built then it is set, and it may be 319// either a valid android.Path, or invalid with a reason message. The latter 320// happens if the source that should produce the dex file isn't able to. 321// 322// E.g. it is invalid with a reason message if there is a prebuilt APEX that 323// could produce the dex jar through a deapexer module, but the APEX isn't 324// installable so doing so wouldn't be safe. 325type OptionalDexJarPath struct { 326 isSet bool 327 path android.OptionalPath 328} 329 330// IsSet returns true if a path has been set, either invalid or valid. 331func (o OptionalDexJarPath) IsSet() bool { 332 return o.isSet 333} 334 335// Valid returns true if there is a path that is valid. 336func (o OptionalDexJarPath) Valid() bool { 337 return o.isSet && o.path.Valid() 338} 339 340// Path returns the valid path, or panics if it's either not set or is invalid. 341func (o OptionalDexJarPath) Path() android.Path { 342 if !o.isSet { 343 panic("path isn't set") 344 } 345 return o.path.Path() 346} 347 348// PathOrNil returns the path if it's set and valid, or else nil. 349func (o OptionalDexJarPath) PathOrNil() android.Path { 350 if o.Valid() { 351 return o.Path() 352 } 353 return nil 354} 355 356// InvalidReason returns the reason for an invalid path, which is never "". It 357// returns "" for an unset or valid path. 358func (o OptionalDexJarPath) InvalidReason() string { 359 if !o.isSet { 360 return "" 361 } 362 return o.path.InvalidReason() 363} 364 365func (o OptionalDexJarPath) String() string { 366 if !o.isSet { 367 return "<unset>" 368 } 369 return o.path.String() 370} 371 372// makeUnsetDexJarPath returns an unset OptionalDexJarPath. 373func makeUnsetDexJarPath() OptionalDexJarPath { 374 return OptionalDexJarPath{isSet: false} 375} 376 377// makeDexJarPathFromOptionalPath returns an OptionalDexJarPath that is set with 378// the given OptionalPath, which may be valid or invalid. 379func makeDexJarPathFromOptionalPath(path android.OptionalPath) OptionalDexJarPath { 380 return OptionalDexJarPath{isSet: true, path: path} 381} 382 383// makeDexJarPathFromPath returns an OptionalDexJarPath that is set with the 384// valid given path. It returns an unset OptionalDexJarPath if the given path is 385// nil. 386func makeDexJarPathFromPath(path android.Path) OptionalDexJarPath { 387 if path == nil { 388 return makeUnsetDexJarPath() 389 } 390 return makeDexJarPathFromOptionalPath(android.OptionalPathForPath(path)) 391} 392 393// Module contains the properties and members used by all java module types 394type Module struct { 395 android.ModuleBase 396 android.DefaultableModuleBase 397 android.ApexModuleBase 398 android.BazelModuleBase 399 400 // Functionality common to Module and Import. 401 embeddableInModuleAndImport 402 403 properties CommonProperties 404 protoProperties android.ProtoProperties 405 deviceProperties DeviceProperties 406 407 overridableDeviceProperties OverridableDeviceProperties 408 409 // jar file containing header classes including static library dependencies, suitable for 410 // inserting into the bootclasspath/classpath of another compile 411 headerJarFile android.Path 412 413 // jar file containing implementation classes including static library dependencies but no 414 // resources 415 implementationJarFile android.Path 416 417 // jar file containing only resources including from static library dependencies 418 resourceJar android.Path 419 420 // args and dependencies to package source files into a srcjar 421 srcJarArgs []string 422 srcJarDeps android.Paths 423 424 // jar file containing implementation classes and resources including static library 425 // dependencies 426 implementationAndResourcesJar android.Path 427 428 // output file containing classes.dex and resources 429 dexJarFile OptionalDexJarPath 430 431 // output file containing uninstrumented classes that will be instrumented by jacoco 432 jacocoReportClassesFile android.Path 433 434 // output file of the module, which may be a classes jar or a dex jar 435 outputFile android.Path 436 extraOutputFiles android.Paths 437 438 exportAidlIncludeDirs android.Paths 439 ignoredAidlPermissionList android.Paths 440 441 logtagsSrcs android.Paths 442 443 // installed file for binary dependency 444 installFile android.Path 445 446 // installed file for hostdex copy 447 hostdexInstallFile android.InstallPath 448 449 // list of unique .java and .kt source files 450 uniqueSrcFiles android.Paths 451 452 // list of srcjars that was passed to javac 453 compiledSrcJars android.Paths 454 455 // manifest file to use instead of properties.Manifest 456 overrideManifest android.OptionalPath 457 458 // list of plugins that this java module is exporting 459 exportedPluginJars android.Paths 460 461 // list of plugins that this java module is exporting 462 exportedPluginClasses []string 463 464 // if true, the exported plugins generate API and require disabling turbine. 465 exportedDisableTurbine bool 466 467 // list of source files, collected from srcFiles with unique java and all kt files, 468 // will be used by android.IDEInfo struct 469 expandIDEInfoCompiledSrcs []string 470 471 // expanded Jarjar_rules 472 expandJarjarRules android.Path 473 474 // Extra files generated by the module type to be added as java resources. 475 extraResources android.Paths 476 477 hiddenAPI 478 dexer 479 dexpreopter 480 usesLibrary 481 linter 482 483 // list of the xref extraction files 484 kytheFiles android.Paths 485 486 // Collect the module directory for IDE info in java/jdeps.go. 487 modulePaths []string 488 489 hideApexVariantFromMake bool 490 491 sdkVersion android.SdkSpec 492 minSdkVersion android.ApiLevel 493 maxSdkVersion android.ApiLevel 494 495 sourceExtensions []string 496} 497 498func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error { 499 sdkVersion := j.SdkVersion(ctx) 500 if sdkVersion.Stable() { 501 return nil 502 } 503 if sdkVersion.Kind == android.SdkCorePlatform { 504 if useLegacyCorePlatformApi(ctx, j.BaseModuleName()) { 505 return fmt.Errorf("non stable SDK %v - uses legacy core platform", sdkVersion) 506 } else { 507 // Treat stable core platform as stable. 508 return nil 509 } 510 } else { 511 return fmt.Errorf("non stable SDK %v", sdkVersion) 512 } 513} 514 515// checkSdkVersions enforces restrictions around SDK dependencies. 516func (j *Module) checkSdkVersions(ctx android.ModuleContext) { 517 if j.RequiresStableAPIs(ctx) { 518 if sc, ok := ctx.Module().(android.SdkContext); ok { 519 if !sc.SdkVersion(ctx).Specified() { 520 ctx.PropertyErrorf("sdk_version", 521 "sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).") 522 } 523 } 524 } 525 526 // Make sure this module doesn't statically link to modules with lower-ranked SDK link type. 527 // See rank() for details. 528 ctx.VisitDirectDeps(func(module android.Module) { 529 tag := ctx.OtherModuleDependencyTag(module) 530 switch module.(type) { 531 // TODO(satayev): cover other types as well, e.g. imports 532 case *Library, *AndroidLibrary: 533 switch tag { 534 case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag: 535 j.checkSdkLinkType(ctx, module.(moduleWithSdkDep), tag.(dependencyTag)) 536 } 537 } 538 }) 539} 540 541func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { 542 if sc, ok := ctx.Module().(android.SdkContext); ok { 543 usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis) 544 sdkVersionSpecified := sc.SdkVersion(ctx).Specified() 545 if usePlatformAPI && sdkVersionSpecified { 546 ctx.PropertyErrorf("platform_apis", "This module has conflicting settings. sdk_version is not empty, which means this module cannot use platform APIs. However platform_apis is set to true.") 547 } else if !usePlatformAPI && !sdkVersionSpecified { 548 ctx.PropertyErrorf("platform_apis", "This module has conflicting settings. sdk_version is empty, which means that this module is build against platform APIs. However platform_apis is not set to true") 549 } 550 551 } 552} 553 554func (j *Module) addHostProperties() { 555 j.AddProperties( 556 &j.properties, 557 &j.protoProperties, 558 &j.usesLibraryProperties, 559 ) 560} 561 562func (j *Module) addHostAndDeviceProperties() { 563 j.addHostProperties() 564 j.AddProperties( 565 &j.deviceProperties, 566 &j.overridableDeviceProperties, 567 &j.dexer.dexProperties, 568 &j.dexpreoptProperties, 569 &j.linter.properties, 570 ) 571} 572 573// provideHiddenAPIPropertyInfo populates a HiddenAPIPropertyInfo from hidden API properties and 574// makes it available through the hiddenAPIPropertyInfoProvider. 575func (j *Module) provideHiddenAPIPropertyInfo(ctx android.ModuleContext) { 576 hiddenAPIInfo := newHiddenAPIPropertyInfo() 577 578 // Populate with flag file paths from the properties. 579 hiddenAPIInfo.extractFlagFilesFromProperties(ctx, &j.deviceProperties.HiddenAPIFlagFileProperties) 580 581 // Populate with package rules from the properties. 582 hiddenAPIInfo.extractPackageRulesFromProperties(&j.deviceProperties.HiddenAPIPackageProperties) 583 584 ctx.SetProvider(hiddenAPIPropertyInfoProvider, hiddenAPIInfo) 585} 586 587func (j *Module) OutputFiles(tag string) (android.Paths, error) { 588 switch tag { 589 case "": 590 return append(android.Paths{j.outputFile}, j.extraOutputFiles...), nil 591 case android.DefaultDistTag: 592 return android.Paths{j.outputFile}, nil 593 case ".jar": 594 return android.Paths{j.implementationAndResourcesJar}, nil 595 case ".hjar": 596 return android.Paths{j.headerJarFile}, nil 597 case ".proguard_map": 598 if j.dexer.proguardDictionary.Valid() { 599 return android.Paths{j.dexer.proguardDictionary.Path()}, nil 600 } 601 return nil, fmt.Errorf("%q was requested, but no output file was found.", tag) 602 default: 603 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 604 } 605} 606 607var _ android.OutputFileProducer = (*Module)(nil) 608 609func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) { 610 initJavaModule(module, hod, false) 611} 612 613func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) { 614 initJavaModule(module, hod, true) 615} 616 617func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) { 618 multilib := android.MultilibCommon 619 if multiTargets { 620 android.InitAndroidMultiTargetsArchModule(module, hod, multilib) 621 } else { 622 android.InitAndroidArchModule(module, hod, multilib) 623 } 624 android.InitDefaultableModule(module) 625} 626 627func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool { 628 return j.properties.Instrument && 629 ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") && 630 ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir()) 631} 632 633func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool { 634 return j.properties.Supports_static_instrumentation && 635 j.shouldInstrument(ctx) && 636 (ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") || 637 ctx.Config().UnbundledBuild()) 638} 639 640func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool { 641 // Force enable the instrumentation for java code that is built for APEXes ... 642 // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent 643 // doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true. 644 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 645 isJacocoAgent := ctx.ModuleName() == "jacocoagent" 646 if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() { 647 if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { 648 return true 649 } else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { 650 return true 651 } 652 } 653 return false 654} 655 656func (j *Module) setInstrument(value bool) { 657 j.properties.Instrument = value 658} 659 660func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 661 return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version)) 662} 663 664func (j *Module) SystemModules() string { 665 return proptools.String(j.deviceProperties.System_modules) 666} 667 668func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 669 if j.deviceProperties.Min_sdk_version != nil { 670 return android.ApiLevelFrom(ctx, *j.deviceProperties.Min_sdk_version) 671 } 672 return j.SdkVersion(ctx).ApiLevel 673} 674 675func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 676 if j.deviceProperties.Max_sdk_version != nil { 677 return android.ApiLevelFrom(ctx, *j.deviceProperties.Max_sdk_version) 678 } 679 // Default is PrivateApiLevel 680 return android.SdkSpecPrivate.ApiLevel 681} 682 683func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel { 684 if j.deviceProperties.Replace_max_sdk_version_placeholder != nil { 685 return android.ApiLevelFrom(ctx, *j.deviceProperties.Replace_max_sdk_version_placeholder) 686 } 687 // Default is PrivateApiLevel 688 return android.SdkSpecPrivate.ApiLevel 689} 690 691func (j *Module) MinSdkVersionString() string { 692 return j.minSdkVersion.String() 693} 694 695func (j *Module) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 696 if j.deviceProperties.Target_sdk_version != nil { 697 return android.ApiLevelFrom(ctx, *j.deviceProperties.Target_sdk_version) 698 } 699 return j.SdkVersion(ctx).ApiLevel 700} 701 702func (j *Module) AvailableFor(what string) bool { 703 if what == android.AvailableToPlatform && Bool(j.deviceProperties.Hostdex) { 704 // Exception: for hostdex: true libraries, the platform variant is created 705 // even if it's not marked as available to platform. In that case, the platform 706 // variant is used only for the hostdex and not installed to the device. 707 return true 708 } 709 return j.ApexModuleBase.AvailableFor(what) 710} 711 712func (j *Module) deps(ctx android.BottomUpMutatorContext) { 713 if ctx.Device() { 714 j.linter.deps(ctx) 715 716 sdkDeps(ctx, android.SdkContext(j), j.dexer) 717 718 if j.deviceProperties.SyspropPublicStub != "" { 719 // This is a sysprop implementation library that has a corresponding sysprop public 720 // stubs library, and a dependency on it so that dependencies on the implementation can 721 // be forwarded to the public stubs library when necessary. 722 ctx.AddVariationDependencies(nil, syspropPublicStubDepTag, j.deviceProperties.SyspropPublicStub) 723 } 724 } 725 726 libDeps := ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) 727 ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...) 728 729 // Add dependency on libraries that provide additional hidden api annotations. 730 ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...) 731 732 if ctx.DeviceConfig().VndkVersion() != "" && ctx.Config().EnforceInterPartitionJavaSdkLibrary() { 733 // Require java_sdk_library at inter-partition java dependency to ensure stable 734 // interface between partitions. If inter-partition java_library dependency is detected, 735 // raise build error because java_library doesn't have a stable interface. 736 // 737 // Inputs: 738 // PRODUCT_ENFORCE_INTER_PARTITION_JAVA_SDK_LIBRARY 739 // if true, enable enforcement 740 // PRODUCT_INTER_PARTITION_JAVA_LIBRARY_ALLOWLIST 741 // exception list of java_library names to allow inter-partition dependency 742 for idx := range j.properties.Libs { 743 if libDeps[idx] == nil { 744 continue 745 } 746 747 if javaDep, ok := libDeps[idx].(javaSdkLibraryEnforceContext); ok { 748 // java_sdk_library is always allowed at inter-partition dependency. 749 // So, skip check. 750 if _, ok := javaDep.(*SdkLibrary); ok { 751 continue 752 } 753 754 j.checkPartitionsForJavaDependency(ctx, "libs", javaDep) 755 } 756 } 757 } 758 759 // For library dependencies that are component libraries (like stubs), add the implementation 760 // as a dependency (dexpreopt needs to be against the implementation library, not stubs). 761 for _, dep := range libDeps { 762 if dep != nil { 763 if component, ok := dep.(SdkLibraryComponentDependency); ok { 764 if lib := component.OptionalSdkLibraryImplementation(); lib != nil { 765 // Add library as optional if it's one of the optional compatibility libs. 766 tag := usesLibReqTag 767 if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) { 768 tag = usesLibOptTag 769 } 770 ctx.AddVariationDependencies(nil, tag, *lib) 771 } 772 } 773 } 774 } 775 776 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...) 777 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), errorpronePluginTag, j.properties.Errorprone.Extra_check_modules...) 778 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...) 779 780 android.ProtoDeps(ctx, &j.protoProperties) 781 if j.hasSrcExt(".proto") { 782 protoDeps(ctx, &j.protoProperties) 783 } 784 785 if j.hasSrcExt(".kt") { 786 // TODO(ccross): move this to a mutator pass that can tell if generated sources contain 787 // Kotlin files 788 ctx.AddVariationDependencies(nil, kotlinStdlibTag, 789 "kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8") 790 ctx.AddVariationDependencies(nil, kotlinAnnotationsTag, "kotlin-annotations") 791 } 792 793 // Framework libraries need special handling in static coverage builds: they should not have 794 // static dependency on jacoco, otherwise there would be multiple conflicting definitions of 795 // the same jacoco classes coming from different bootclasspath jars. 796 if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { 797 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { 798 j.properties.Instrument = true 799 } 800 } else if j.shouldInstrumentStatic(ctx) { 801 ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent") 802 } 803 804 if j.useCompose() { 805 ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag, 806 "androidx.compose.compiler_compiler-hosted") 807 } 808} 809 810func hasSrcExt(srcs []string, ext string) bool { 811 for _, src := range srcs { 812 if filepath.Ext(src) == ext { 813 return true 814 } 815 } 816 817 return false 818} 819 820func (j *Module) hasSrcExt(ext string) bool { 821 return hasSrcExt(j.properties.Srcs, ext) 822} 823 824func (j *Module) individualAidlFlags(ctx android.ModuleContext, aidlFile android.Path) string { 825 var flags string 826 827 if Bool(j.deviceProperties.Aidl.Enforce_permissions) { 828 if !android.InList(aidlFile.String(), j.ignoredAidlPermissionList.Strings()) { 829 flags = "-Wmissing-permission-annotation -Werror" 830 } 831 } 832 return flags 833} 834 835func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath, 836 aidlIncludeDirs android.Paths, aidlSrcs android.Paths) (string, android.Paths) { 837 838 aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs) 839 aidlIncludes = append(aidlIncludes, 840 android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...) 841 aidlIncludes = append(aidlIncludes, 842 android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...) 843 844 var flags []string 845 var deps android.Paths 846 var includeDirs android.Paths 847 848 flags = append(flags, j.deviceProperties.Aidl.Flags...) 849 850 if aidlPreprocess.Valid() { 851 flags = append(flags, "-p"+aidlPreprocess.String()) 852 deps = append(deps, aidlPreprocess.Path()) 853 } else if len(aidlIncludeDirs) > 0 { 854 includeDirs = append(includeDirs, aidlIncludeDirs...) 855 } 856 857 if len(j.exportAidlIncludeDirs) > 0 { 858 includeDirs = append(includeDirs, j.exportAidlIncludeDirs...) 859 } 860 861 if len(aidlIncludes) > 0 { 862 includeDirs = append(includeDirs, aidlIncludes...) 863 } 864 865 includeDirs = append(includeDirs, android.PathForModuleSrc(ctx)) 866 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() { 867 includeDirs = append(includeDirs, src.Path()) 868 } 869 flags = append(flags, android.JoinWithPrefix(includeDirs.Strings(), "-I")) 870 // add flags for dirs containing AIDL srcs that haven't been specified yet 871 flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs)) 872 873 sdkVersion := (j.SdkVersion(ctx)).Kind 874 defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule) || (sdkVersion == android.SdkSystem)) 875 if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) { 876 flags = append(flags, "-t") 877 } 878 879 if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) { 880 flags = append(flags, "--transaction_names") 881 } 882 883 if Bool(j.deviceProperties.Aidl.Enforce_permissions) { 884 exceptions := j.deviceProperties.Aidl.Enforce_permissions_exceptions 885 j.ignoredAidlPermissionList = android.PathsForModuleSrcExcludes(ctx, exceptions, nil) 886 } 887 888 aidlMinSdkVersion := j.MinSdkVersion(ctx).String() 889 flags = append(flags, "--min_sdk_version="+aidlMinSdkVersion) 890 891 return strings.Join(flags, " "), deps 892} 893 894func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags { 895 896 var flags javaBuilderFlags 897 898 // javaVersion flag. 899 flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j)) 900 901 epEnabled := j.properties.Errorprone.Enabled 902 if (ctx.Config().RunErrorProne() && epEnabled == nil) || Bool(epEnabled) { 903 if config.ErrorProneClasspath == nil && !ctx.Config().RunningInsideUnitTest() { 904 ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?") 905 } 906 907 errorProneFlags := []string{ 908 "-Xplugin:ErrorProne", 909 "${config.ErrorProneChecks}", 910 } 911 errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...) 912 913 flags.errorProneExtraJavacFlags = "${config.ErrorProneHeapFlags} ${config.ErrorProneFlags} " + 914 "'" + strings.Join(errorProneFlags, " ") + "'" 915 flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath)) 916 } 917 918 // classpath 919 flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...) 920 flags.classpath = append(flags.classpath, deps.classpath...) 921 flags.dexClasspath = append(flags.dexClasspath, deps.dexClasspath...) 922 flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...) 923 flags.processorPath = append(flags.processorPath, deps.processorPath...) 924 flags.errorProneProcessorPath = append(flags.errorProneProcessorPath, deps.errorProneProcessorPath...) 925 926 flags.processors = append(flags.processors, deps.processorClasses...) 927 flags.processors = android.FirstUniqueStrings(flags.processors) 928 929 if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() && 930 decodeSdkDep(ctx, android.SdkContext(j)).hasStandardLibs() { 931 // Give host-side tools a version of OpenJDK's standard libraries 932 // close to what they're targeting. As of Dec 2017, AOSP is only 933 // bundling OpenJDK 8 and 9, so nothing < 8 is available. 934 // 935 // When building with OpenJDK 8, the following should have no 936 // effect since those jars would be available by default. 937 // 938 // When building with OpenJDK 9 but targeting a version < 1.8, 939 // putting them on the bootclasspath means that: 940 // a) code can't (accidentally) refer to OpenJDK 9 specific APIs 941 // b) references to existing APIs are not reinterpreted in an 942 // OpenJDK 9-specific way, eg. calls to subclasses of 943 // java.nio.Buffer as in http://b/70862583 944 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME") 945 flags.bootClasspath = append(flags.bootClasspath, 946 android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"), 947 android.PathForSource(ctx, java8Home, "jre/lib/rt.jar")) 948 if Bool(j.properties.Use_tools_jar) { 949 flags.bootClasspath = append(flags.bootClasspath, 950 android.PathForSource(ctx, java8Home, "lib/tools.jar")) 951 } 952 } 953 954 // systemModules 955 flags.systemModules = deps.systemModules 956 957 return flags 958} 959 960func (j *Module) collectJavacFlags( 961 ctx android.ModuleContext, flags javaBuilderFlags, srcFiles android.Paths) javaBuilderFlags { 962 // javac flags. 963 javacFlags := j.properties.Javacflags 964 965 if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() { 966 // For non-host binaries, override the -g flag passed globally to remove 967 // local variable debug info to reduce disk and memory usage. 968 javacFlags = append(javacFlags, "-g:source,lines") 969 } 970 javacFlags = append(javacFlags, "-Xlint:-dep-ann") 971 972 if flags.javaVersion.usesJavaModules() { 973 javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...) 974 975 if j.properties.Patch_module != nil { 976 // Manually specify build directory in case it is not under the repo root. 977 // (javac doesn't seem to expand into symbolic links when searching for patch-module targets, so 978 // just adding a symlink under the root doesn't help.) 979 patchPaths := []string{".", ctx.Config().SoongOutDir()} 980 981 // b/150878007 982 // 983 // Workaround to support *Bazel-executed* JDK9 javac in Bazel's 984 // execution root for --patch-module. If this javac command line is 985 // invoked within Bazel's execution root working directory, the top 986 // level directories (e.g. libcore/, tools/, frameworks/) are all 987 // symlinks. JDK9 javac does not traverse into symlinks, which causes 988 // --patch-module to fail source file lookups when invoked in the 989 // execution root. 990 // 991 // Short of patching javac or enumerating *all* directories as possible 992 // input dirs, manually add the top level dir of the source files to be 993 // compiled. 994 topLevelDirs := map[string]bool{} 995 for _, srcFilePath := range srcFiles { 996 srcFileParts := strings.Split(srcFilePath.String(), "/") 997 // Ignore source files that are already in the top level directory 998 // as well as generated files in the out directory. The out 999 // directory may be an absolute path, which means srcFileParts[0] is the 1000 // empty string, so check that as well. Note that "out" in Bazel's execution 1001 // root is *not* a symlink, which doesn't cause problems for --patch-modules 1002 // anyway, so it's fine to not apply this workaround for generated 1003 // source files. 1004 if len(srcFileParts) > 1 && 1005 srcFileParts[0] != "" && 1006 srcFileParts[0] != "out" { 1007 topLevelDirs[srcFileParts[0]] = true 1008 } 1009 } 1010 patchPaths = append(patchPaths, android.SortedKeys(topLevelDirs)...) 1011 1012 classPath := flags.classpath.FormJavaClassPath("") 1013 if classPath != "" { 1014 patchPaths = append(patchPaths, classPath) 1015 } 1016 javacFlags = append( 1017 javacFlags, 1018 "--patch-module="+String(j.properties.Patch_module)+"="+strings.Join(patchPaths, ":")) 1019 } 1020 } 1021 1022 if len(javacFlags) > 0 { 1023 // optimization. 1024 ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " ")) 1025 flags.javacFlags = "$javacFlags" 1026 } 1027 1028 return flags 1029} 1030 1031func (j *Module) AddJSONData(d *map[string]interface{}) { 1032 (&j.ModuleBase).AddJSONData(d) 1033 (*d)["Java"] = map[string]interface{}{ 1034 "SourceExtensions": j.sourceExtensions, 1035 } 1036 1037} 1038 1039func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { 1040 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs) 1041 1042 deps := j.collectDeps(ctx) 1043 flags := j.collectBuilderFlags(ctx, deps) 1044 1045 if flags.javaVersion.usesJavaModules() { 1046 j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...) 1047 } 1048 1049 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) 1050 j.sourceExtensions = []string{} 1051 for _, ext := range []string{".kt", ".proto", ".aidl", ".java", ".logtags"} { 1052 if hasSrcExt(srcFiles.Strings(), ext) { 1053 j.sourceExtensions = append(j.sourceExtensions, ext) 1054 } 1055 } 1056 if hasSrcExt(srcFiles.Strings(), ".proto") { 1057 flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags) 1058 } 1059 1060 kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, nil) 1061 if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 { 1062 ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files") 1063 } 1064 1065 aidlSrcs := srcFiles.FilterByExt(".aidl") 1066 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs, aidlSrcs) 1067 1068 nonGeneratedSrcJars := srcFiles.FilterByExt(".srcjar") 1069 srcFiles = j.genSources(ctx, srcFiles, flags) 1070 1071 // Collect javac flags only after computing the full set of srcFiles to 1072 // ensure that the --patch-module lookup paths are complete. 1073 flags = j.collectJavacFlags(ctx, flags, srcFiles) 1074 1075 srcJars := srcFiles.FilterByExt(".srcjar") 1076 srcJars = append(srcJars, deps.srcJars...) 1077 if aaptSrcJar != nil { 1078 srcJars = append(srcJars, aaptSrcJar) 1079 } 1080 srcFiles = srcFiles.FilterOutByExt(".srcjar") 1081 1082 if j.properties.Jarjar_rules != nil { 1083 j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules) 1084 } 1085 1086 jarName := ctx.ModuleName() + ".jar" 1087 1088 var uniqueJavaFiles android.Paths 1089 set := make(map[string]bool) 1090 for _, v := range srcFiles.FilterByExt(".java") { 1091 if _, found := set[v.String()]; !found { 1092 set[v.String()] = true 1093 uniqueJavaFiles = append(uniqueJavaFiles, v) 1094 } 1095 } 1096 var uniqueKtFiles android.Paths 1097 for _, v := range srcFiles.FilterByExt(".kt") { 1098 if _, found := set[v.String()]; !found { 1099 set[v.String()] = true 1100 uniqueKtFiles = append(uniqueKtFiles, v) 1101 } 1102 } 1103 1104 var uniqueSrcFiles android.Paths 1105 uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...) 1106 uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...) 1107 j.uniqueSrcFiles = uniqueSrcFiles 1108 1109 // We don't currently run annotation processors in turbine, which means we can't use turbine 1110 // generated header jars when an annotation processor that generates API is enabled. One 1111 // exception (handled further below) is when kotlin sources are enabled, in which case turbine 1112 // is used to run all of the annotation processors. 1113 disableTurbine := deps.disableTurbine 1114 1115 // Collect .java and .kt files for AIDEGen 1116 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...) 1117 1118 var kotlinJars android.Paths 1119 var kotlinHeaderJars android.Paths 1120 1121 if srcFiles.HasExt(".kt") { 1122 // When using kotlin sources turbine is used to generate annotation processor sources, 1123 // including for annotation processors that generate API, so we can use turbine for 1124 // java sources too. 1125 disableTurbine = false 1126 1127 // user defined kotlin flags. 1128 kotlincFlags := j.properties.Kotlincflags 1129 CheckKotlincFlags(ctx, kotlincFlags) 1130 1131 // Workaround for KT-46512 1132 kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class") 1133 1134 // If there are kotlin files, compile them first but pass all the kotlin and java files 1135 // kotlinc will use the java files to resolve types referenced by the kotlin files, but 1136 // won't emit any classes for them. 1137 kotlincFlags = append(kotlincFlags, "-no-stdlib") 1138 if ctx.Device() { 1139 kotlincFlags = append(kotlincFlags, "-no-jdk") 1140 } 1141 1142 for _, plugin := range deps.kotlinPlugins { 1143 kotlincFlags = append(kotlincFlags, "-Xplugin="+plugin.String()) 1144 } 1145 flags.kotlincDeps = append(flags.kotlincDeps, deps.kotlinPlugins...) 1146 1147 if len(kotlincFlags) > 0 { 1148 // optimization. 1149 ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " ")) 1150 flags.kotlincFlags += "$kotlincFlags" 1151 } 1152 1153 // Collect common .kt files for AIDEGen 1154 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...) 1155 1156 flags.classpath = append(flags.classpath, deps.kotlinStdlib...) 1157 flags.classpath = append(flags.classpath, deps.kotlinAnnotations...) 1158 1159 flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...) 1160 flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...) 1161 1162 if len(flags.processorPath) > 0 { 1163 // Use kapt for annotation processing 1164 kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar") 1165 kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar") 1166 kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) 1167 srcJars = append(srcJars, kaptSrcJar) 1168 kotlinJars = append(kotlinJars, kaptResJar) 1169 // Disable annotation processing in javac, it's already been handled by kapt 1170 flags.processorPath = nil 1171 flags.processors = nil 1172 } 1173 1174 kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName) 1175 kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName) 1176 kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) 1177 if ctx.Failed() { 1178 return 1179 } 1180 1181 // Make javac rule depend on the kotlinc rule 1182 flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...) 1183 1184 kotlinJars = append(kotlinJars, kotlinJar) 1185 kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar) 1186 1187 // Jar kotlin classes into the final jar after javac 1188 if BoolDefault(j.properties.Static_kotlin_stdlib, true) { 1189 kotlinJars = append(kotlinJars, deps.kotlinStdlib...) 1190 kotlinJars = append(kotlinJars, deps.kotlinAnnotations...) 1191 kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinStdlib...) 1192 kotlinHeaderJars = append(kotlinHeaderJars, deps.kotlinAnnotations...) 1193 } else { 1194 flags.dexClasspath = append(flags.dexClasspath, deps.kotlinStdlib...) 1195 flags.dexClasspath = append(flags.dexClasspath, deps.kotlinAnnotations...) 1196 } 1197 } 1198 1199 jars := append(android.Paths(nil), kotlinJars...) 1200 1201 j.compiledSrcJars = srcJars 1202 1203 enableSharding := false 1204 var headerJarFileWithoutDepsOrJarjar android.Path 1205 if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine { 1206 if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 { 1207 enableSharding = true 1208 // Formerly, there was a check here that prevented annotation processors 1209 // from being used when sharding was enabled, as some annotation processors 1210 // do not function correctly in sharded environments. It was removed to 1211 // allow for the use of annotation processors that do function correctly 1212 // with sharding enabled. See: b/77284273. 1213 } 1214 headerJarFileWithoutDepsOrJarjar, j.headerJarFile = 1215 j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, kotlinHeaderJars) 1216 if ctx.Failed() { 1217 return 1218 } 1219 } 1220 if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 { 1221 hasErrorproneableFiles := false 1222 for _, ext := range j.sourceExtensions { 1223 if ext != ".proto" && ext != ".aidl" { 1224 // Skip running errorprone on pure proto or pure aidl modules. Some modules take a long time to 1225 // compile, and it's not useful to have warnings on these generated sources. 1226 hasErrorproneableFiles = true 1227 break 1228 } 1229 } 1230 var extraJarDeps android.Paths 1231 if Bool(j.properties.Errorprone.Enabled) { 1232 // If error-prone is enabled, enable errorprone flags on the regular 1233 // build. 1234 flags = enableErrorproneFlags(flags) 1235 } else if hasErrorproneableFiles && ctx.Config().RunErrorProne() && j.properties.Errorprone.Enabled == nil { 1236 // Otherwise, if the RUN_ERROR_PRONE environment variable is set, create 1237 // a new jar file just for compiling with the errorprone compiler to. 1238 // This is because we don't want to cause the java files to get completely 1239 // rebuilt every time the state of the RUN_ERROR_PRONE variable changes. 1240 // We also don't want to run this if errorprone is enabled by default for 1241 // this module, or else we could have duplicated errorprone messages. 1242 errorproneFlags := enableErrorproneFlags(flags) 1243 errorprone := android.PathForModuleOut(ctx, "errorprone", jarName) 1244 1245 transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneFlags, nil, 1246 "errorprone", "errorprone") 1247 1248 extraJarDeps = append(extraJarDeps, errorprone) 1249 } 1250 1251 if enableSharding { 1252 if headerJarFileWithoutDepsOrJarjar != nil { 1253 flags.classpath = append(classpath{headerJarFileWithoutDepsOrJarjar}, flags.classpath...) 1254 } 1255 shardSize := int(*(j.properties.Javac_shard_size)) 1256 var shardSrcs []android.Paths 1257 if len(uniqueJavaFiles) > 0 { 1258 shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize) 1259 for idx, shardSrc := range shardSrcs { 1260 classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc, 1261 nil, flags, extraJarDeps) 1262 jars = append(jars, classes) 1263 } 1264 } 1265 if len(srcJars) > 0 { 1266 classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs), 1267 nil, srcJars, flags, extraJarDeps) 1268 jars = append(jars, classes) 1269 } 1270 } else { 1271 classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps) 1272 jars = append(jars, classes) 1273 } 1274 if ctx.Failed() { 1275 return 1276 } 1277 } 1278 1279 j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles 1280 1281 var includeSrcJar android.WritablePath 1282 if Bool(j.properties.Include_srcs) { 1283 includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar") 1284 TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps) 1285 } 1286 1287 dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs, 1288 j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources) 1289 fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources, j.properties.Exclude_java_resources) 1290 extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources 1291 1292 var resArgs []string 1293 var resDeps android.Paths 1294 1295 resArgs = append(resArgs, dirArgs...) 1296 resDeps = append(resDeps, dirDeps...) 1297 1298 resArgs = append(resArgs, fileArgs...) 1299 resDeps = append(resDeps, fileDeps...) 1300 1301 resArgs = append(resArgs, extraArgs...) 1302 resDeps = append(resDeps, extraDeps...) 1303 1304 if len(resArgs) > 0 { 1305 resourceJar := android.PathForModuleOut(ctx, "res", jarName) 1306 TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps) 1307 j.resourceJar = resourceJar 1308 if ctx.Failed() { 1309 return 1310 } 1311 } 1312 1313 var resourceJars android.Paths 1314 if j.resourceJar != nil { 1315 resourceJars = append(resourceJars, j.resourceJar) 1316 } 1317 if Bool(j.properties.Include_srcs) { 1318 resourceJars = append(resourceJars, includeSrcJar) 1319 } 1320 resourceJars = append(resourceJars, deps.staticResourceJars...) 1321 1322 if len(resourceJars) > 1 { 1323 combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName) 1324 TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{}, 1325 false, nil, nil) 1326 j.resourceJar = combinedJar 1327 } else if len(resourceJars) == 1 { 1328 j.resourceJar = resourceJars[0] 1329 } 1330 1331 if len(deps.staticJars) > 0 { 1332 jars = append(jars, deps.staticJars...) 1333 } 1334 1335 manifest := j.overrideManifest 1336 if !manifest.Valid() && j.properties.Manifest != nil { 1337 manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest)) 1338 } 1339 1340 services := android.PathsForModuleSrc(ctx, j.properties.Services) 1341 if len(services) > 0 { 1342 servicesJar := android.PathForModuleOut(ctx, "services", jarName) 1343 var zipargs []string 1344 for _, file := range services { 1345 serviceFile := file.String() 1346 zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile) 1347 } 1348 rule := zip 1349 args := map[string]string{ 1350 "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "), 1351 } 1352 if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") { 1353 rule = zipRE 1354 args["implicits"] = strings.Join(services.Strings(), ",") 1355 } 1356 ctx.Build(pctx, android.BuildParams{ 1357 Rule: rule, 1358 Output: servicesJar, 1359 Implicits: services, 1360 Args: args, 1361 }) 1362 jars = append(jars, servicesJar) 1363 } 1364 1365 // Combine the classes built from sources, any manifests, and any static libraries into 1366 // classes.jar. If there is only one input jar this step will be skipped. 1367 var outputFile android.OutputPath 1368 1369 if len(jars) == 1 && !manifest.Valid() { 1370 // Optimization: skip the combine step as there is nothing to do 1371 // TODO(ccross): this leaves any module-info.class files, but those should only come from 1372 // prebuilt dependencies until we support modules in the platform build, so there shouldn't be 1373 // any if len(jars) == 1. 1374 1375 // Transform the single path to the jar into an OutputPath as that is required by the following 1376 // code. 1377 if moduleOutPath, ok := jars[0].(android.ModuleOutPath); ok { 1378 // The path contains an embedded OutputPath so reuse that. 1379 outputFile = moduleOutPath.OutputPath 1380 } else if outputPath, ok := jars[0].(android.OutputPath); ok { 1381 // The path is an OutputPath so reuse it directly. 1382 outputFile = outputPath 1383 } else { 1384 // The file is not in the out directory so create an OutputPath into which it can be copied 1385 // and which the following code can use to refer to it. 1386 combinedJar := android.PathForModuleOut(ctx, "combined", jarName) 1387 ctx.Build(pctx, android.BuildParams{ 1388 Rule: android.Cp, 1389 Input: jars[0], 1390 Output: combinedJar, 1391 }) 1392 outputFile = combinedJar.OutputPath 1393 } 1394 } else { 1395 combinedJar := android.PathForModuleOut(ctx, "combined", jarName) 1396 TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest, 1397 false, nil, nil) 1398 outputFile = combinedJar.OutputPath 1399 } 1400 1401 // jarjar implementation jar if necessary 1402 if j.expandJarjarRules != nil { 1403 // Transform classes.jar into classes-jarjar.jar 1404 jarjarFile := android.PathForModuleOut(ctx, "jarjar", jarName).OutputPath 1405 TransformJarJar(ctx, jarjarFile, outputFile, j.expandJarjarRules) 1406 outputFile = jarjarFile 1407 1408 // jarjar resource jar if necessary 1409 if j.resourceJar != nil { 1410 resourceJarJarFile := android.PathForModuleOut(ctx, "res-jarjar", jarName) 1411 TransformJarJar(ctx, resourceJarJarFile, j.resourceJar, j.expandJarjarRules) 1412 j.resourceJar = resourceJarJarFile 1413 } 1414 1415 if ctx.Failed() { 1416 return 1417 } 1418 } 1419 1420 // Check package restrictions if necessary. 1421 if len(j.properties.Permitted_packages) > 0 { 1422 // Time stamp file created by the package check rule. 1423 pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp") 1424 1425 // Create a rule to copy the output jar to another path and add a validate dependency that 1426 // will check that the jar only contains the permitted packages. The new location will become 1427 // the output file of this module. 1428 inputFile := outputFile 1429 outputFile = android.PathForModuleOut(ctx, "package-check", jarName).OutputPath 1430 ctx.Build(pctx, android.BuildParams{ 1431 Rule: android.Cp, 1432 Input: inputFile, 1433 Output: outputFile, 1434 // Make sure that any dependency on the output file will cause ninja to run the package check 1435 // rule. 1436 Validation: pkgckFile, 1437 }) 1438 1439 // Check packages and create a timestamp file when complete. 1440 CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages) 1441 1442 if ctx.Failed() { 1443 return 1444 } 1445 } 1446 1447 j.implementationJarFile = outputFile 1448 if j.headerJarFile == nil { 1449 // If this module couldn't generate a header jar (for example due to api generating annotation processors) 1450 // then use the implementation jar. Run it through zip2zip first to remove any files in META-INF/services 1451 // so that javac on modules that depend on this module don't pick up annotation processors (which may be 1452 // missing their implementations) from META-INF/services/javax.annotation.processing.Processor. 1453 headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName) 1454 convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile) 1455 j.headerJarFile = headerJarFile 1456 } 1457 1458 // enforce syntax check to jacoco filters for any build (http://b/183622051) 1459 specs := j.jacocoModuleToZipCommand(ctx) 1460 if ctx.Failed() { 1461 return 1462 } 1463 1464 if j.shouldInstrument(ctx) { 1465 outputFile = j.instrument(ctx, flags, outputFile, jarName, specs) 1466 } 1467 1468 // merge implementation jar with resources if necessary 1469 implementationAndResourcesJar := outputFile 1470 if j.resourceJar != nil { 1471 jars := android.Paths{j.resourceJar, implementationAndResourcesJar} 1472 combinedJar := android.PathForModuleOut(ctx, "withres", jarName).OutputPath 1473 TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest, 1474 false, nil, nil) 1475 implementationAndResourcesJar = combinedJar 1476 } 1477 1478 j.implementationAndResourcesJar = implementationAndResourcesJar 1479 1480 // Enable dex compilation for the APEX variants, unless it is disabled explicitly 1481 compileDex := j.dexProperties.Compile_dex 1482 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 1483 if j.DirectlyInAnyApex() && !apexInfo.IsForPlatform() { 1484 if compileDex == nil { 1485 compileDex = proptools.BoolPtr(true) 1486 } 1487 if j.deviceProperties.Hostdex == nil { 1488 j.deviceProperties.Hostdex = proptools.BoolPtr(true) 1489 } 1490 } 1491 1492 if ctx.Device() && (Bool(j.properties.Installable) || Bool(compileDex)) { 1493 if j.hasCode(ctx) { 1494 if j.shouldInstrumentStatic(ctx) { 1495 j.dexer.extraProguardFlagFiles = append(j.dexer.extraProguardFlagFiles, 1496 android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags")) 1497 } 1498 // Dex compilation 1499 var dexOutputFile android.OutputPath 1500 params := &compileDexParams{ 1501 flags: flags, 1502 sdkVersion: j.SdkVersion(ctx), 1503 minSdkVersion: j.MinSdkVersion(ctx), 1504 classesJar: implementationAndResourcesJar, 1505 jarName: jarName, 1506 } 1507 dexOutputFile = j.dexer.compileDex(ctx, params) 1508 if ctx.Failed() { 1509 return 1510 } 1511 1512 // merge dex jar with resources if necessary 1513 if j.resourceJar != nil { 1514 jars := android.Paths{dexOutputFile, j.resourceJar} 1515 combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName).OutputPath 1516 TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{}, 1517 false, nil, nil) 1518 if *j.dexProperties.Uncompress_dex { 1519 combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName).OutputPath 1520 TransformZipAlign(ctx, combinedAlignedJar, combinedJar) 1521 dexOutputFile = combinedAlignedJar 1522 } else { 1523 dexOutputFile = combinedJar 1524 } 1525 } 1526 1527 // Initialize the hiddenapi structure. 1528 1529 j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), j.implementationJarFile, j.dexProperties.Uncompress_dex) 1530 1531 // Encode hidden API flags in dex file, if needed. 1532 dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) 1533 1534 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 1535 1536 // Dexpreopting 1537 j.dexpreopt(ctx, dexOutputFile) 1538 1539 outputFile = dexOutputFile 1540 } else { 1541 // There is no code to compile into a dex jar, make sure the resources are propagated 1542 // to the APK if this is an app. 1543 outputFile = implementationAndResourcesJar 1544 j.dexJarFile = makeDexJarPathFromPath(j.resourceJar) 1545 } 1546 1547 if ctx.Failed() { 1548 return 1549 } 1550 } else { 1551 outputFile = implementationAndResourcesJar 1552 } 1553 1554 if ctx.Device() { 1555 lintSDKVersion := func(apiLevel android.ApiLevel) int { 1556 if !apiLevel.IsPreview() { 1557 return apiLevel.FinalInt() 1558 } else { 1559 // When running metalava, we pass --version-codename. When that value 1560 // is not REL, metalava will add 1 to the --current-version argument. 1561 // On old branches, PLATFORM_SDK_VERSION is the latest version (for that 1562 // branch) and the codename is REL, except potentially on the most 1563 // recent non-master branch. On that branch, it goes through two other 1564 // phases before it gets to the phase previously described: 1565 // - PLATFORM_SDK_VERSION has not been updated yet, and the codename 1566 // is not rel. This happens for most of the internal branch's life 1567 // while the branch has been cut but is still under active development. 1568 // - PLATFORM_SDK_VERSION has been set, but the codename is still not 1569 // REL. This happens briefly during the release process. During this 1570 // state the code to add --current-version is commented out, and then 1571 // that commenting out is reverted after the codename is set to REL. 1572 // On the master branch, the PLATFORM_SDK_VERSION always represents a 1573 // prior version and the codename is always non-REL. 1574 // 1575 // We need to add one here to match metalava adding 1. Technically 1576 // this means that in the state described in the second bullet point 1577 // above, this number is 1 higher than it should be. 1578 return ctx.Config().PlatformSdkVersion().FinalInt() + 1 1579 } 1580 } 1581 1582 j.linter.name = ctx.ModuleName() 1583 j.linter.srcs = append(srcFiles, nonGeneratedSrcJars...) 1584 j.linter.srcJars, _ = android.FilterPathList(srcJars, nonGeneratedSrcJars) 1585 j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...) 1586 j.linter.classes = j.implementationJarFile 1587 j.linter.minSdkVersion = lintSDKVersion(j.MinSdkVersion(ctx)) 1588 j.linter.targetSdkVersion = lintSDKVersion(j.TargetSdkVersion(ctx)) 1589 j.linter.compileSdkVersion = lintSDKVersion(j.SdkVersion(ctx).ApiLevel) 1590 j.linter.compileSdkKind = j.SdkVersion(ctx).Kind 1591 j.linter.javaLanguageLevel = flags.javaVersion.String() 1592 j.linter.kotlinLanguageLevel = "1.3" 1593 if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() { 1594 j.linter.buildModuleReportZip = true 1595 } 1596 j.linter.lint(ctx) 1597 } 1598 1599 ctx.CheckbuildFile(outputFile) 1600 1601 ctx.SetProvider(JavaInfoProvider, JavaInfo{ 1602 HeaderJars: android.PathsIfNonNil(j.headerJarFile), 1603 TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars, 1604 TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars, 1605 ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar), 1606 ImplementationJars: android.PathsIfNonNil(j.implementationJarFile), 1607 ResourceJars: android.PathsIfNonNil(j.resourceJar), 1608 AidlIncludeDirs: j.exportAidlIncludeDirs, 1609 SrcJarArgs: j.srcJarArgs, 1610 SrcJarDeps: j.srcJarDeps, 1611 ExportedPlugins: j.exportedPluginJars, 1612 ExportedPluginClasses: j.exportedPluginClasses, 1613 ExportedPluginDisableTurbine: j.exportedDisableTurbine, 1614 JacocoReportClassesFile: j.jacocoReportClassesFile, 1615 }) 1616 1617 // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource 1618 j.outputFile = outputFile.WithoutRel() 1619} 1620 1621func (j *Module) useCompose() bool { 1622 return android.InList("androidx.compose.runtime_runtime", j.properties.Static_libs) 1623} 1624 1625// Returns a copy of the supplied flags, but with all the errorprone-related 1626// fields copied to the regular build's fields. 1627func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags { 1628 flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...) 1629 1630 if len(flags.errorProneExtraJavacFlags) > 0 { 1631 if len(flags.javacFlags) > 0 { 1632 flags.javacFlags += " " + flags.errorProneExtraJavacFlags 1633 } else { 1634 flags.javacFlags = flags.errorProneExtraJavacFlags 1635 } 1636 } 1637 return flags 1638} 1639 1640func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int, 1641 srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.WritablePath { 1642 1643 kzipName := pathtools.ReplaceExtension(jarName, "kzip") 1644 if idx >= 0 { 1645 kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip" 1646 jarName += strconv.Itoa(idx) 1647 } 1648 1649 classes := android.PathForModuleOut(ctx, "javac", jarName).OutputPath 1650 TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, flags, extraJarDeps) 1651 1652 if ctx.Config().EmitXrefRules() { 1653 extractionFile := android.PathForModuleOut(ctx, kzipName) 1654 emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps) 1655 j.kytheFiles = append(j.kytheFiles, extractionFile) 1656 } 1657 1658 return classes 1659} 1660 1661// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user, 1662// since some of these flags may be used internally. 1663func CheckKotlincFlags(ctx android.ModuleContext, flags []string) { 1664 for _, flag := range flags { 1665 flag = strings.TrimSpace(flag) 1666 1667 if !strings.HasPrefix(flag, "-") { 1668 ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag) 1669 } else if strings.HasPrefix(flag, "-Xintellij-plugin-root") { 1670 ctx.PropertyErrorf("kotlincflags", 1671 "Bad flag: `%s`, only use internal compiler for consistency.", flag) 1672 } else if inList(flag, config.KotlincIllegalFlags) { 1673 ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag) 1674 } else if flag == "-include-runtime" { 1675 ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag) 1676 } else { 1677 args := strings.Split(flag, " ") 1678 if args[0] == "-kotlin-home" { 1679 ctx.PropertyErrorf("kotlincflags", 1680 "Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag) 1681 } 1682 } 1683 } 1684} 1685 1686func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths, 1687 deps deps, flags javaBuilderFlags, jarName string, 1688 extraJars android.Paths) (headerJar, jarjarAndDepsHeaderJar android.Path) { 1689 1690 var jars android.Paths 1691 if len(srcFiles) > 0 || len(srcJars) > 0 { 1692 // Compile java sources into turbine.jar. 1693 turbineJar := android.PathForModuleOut(ctx, "turbine", jarName) 1694 TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags) 1695 if ctx.Failed() { 1696 return nil, nil 1697 } 1698 jars = append(jars, turbineJar) 1699 headerJar = turbineJar 1700 } 1701 1702 jars = append(jars, extraJars...) 1703 1704 // Combine any static header libraries into classes-header.jar. If there is only 1705 // one input jar this step will be skipped. 1706 jars = append(jars, deps.staticHeaderJars...) 1707 1708 // we cannot skip the combine step for now if there is only one jar 1709 // since we have to strip META-INF/TRANSITIVE dir from turbine.jar 1710 combinedJar := android.PathForModuleOut(ctx, "turbine-combined", jarName) 1711 TransformJarsToJar(ctx, combinedJar, "for turbine", jars, android.OptionalPath{}, 1712 false, nil, []string{"META-INF/TRANSITIVE"}) 1713 jarjarAndDepsHeaderJar = combinedJar 1714 1715 if j.expandJarjarRules != nil { 1716 // Transform classes.jar into classes-jarjar.jar 1717 jarjarFile := android.PathForModuleOut(ctx, "turbine-jarjar", jarName) 1718 TransformJarJar(ctx, jarjarFile, jarjarAndDepsHeaderJar, j.expandJarjarRules) 1719 jarjarAndDepsHeaderJar = jarjarFile 1720 if ctx.Failed() { 1721 return nil, nil 1722 } 1723 } 1724 1725 return headerJar, jarjarAndDepsHeaderJar 1726} 1727 1728func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags, 1729 classesJar android.Path, jarName string, specs string) android.OutputPath { 1730 1731 jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName) 1732 instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName).OutputPath 1733 1734 jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs) 1735 1736 j.jacocoReportClassesFile = jacocoReportClassesFile 1737 1738 return instrumentedJar 1739} 1740 1741type providesTransitiveHeaderJars struct { 1742 // set of header jars for all transitive libs deps 1743 transitiveLibsHeaderJars *android.DepSet 1744 // set of header jars for all transitive static libs deps 1745 transitiveStaticLibsHeaderJars *android.DepSet 1746} 1747 1748func (j *providesTransitiveHeaderJars) TransitiveLibsHeaderJars() *android.DepSet { 1749 return j.transitiveLibsHeaderJars 1750} 1751 1752func (j *providesTransitiveHeaderJars) TransitiveStaticLibsHeaderJars() *android.DepSet { 1753 return j.transitiveStaticLibsHeaderJars 1754} 1755 1756func (j *providesTransitiveHeaderJars) collectTransitiveHeaderJars(ctx android.ModuleContext) { 1757 directLibs := android.Paths{} 1758 directStaticLibs := android.Paths{} 1759 transitiveLibs := []*android.DepSet{} 1760 transitiveStaticLibs := []*android.DepSet{} 1761 ctx.VisitDirectDeps(func(module android.Module) { 1762 // don't add deps of the prebuilt version of the same library 1763 if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) { 1764 return 1765 } 1766 1767 dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) 1768 if dep.TransitiveLibsHeaderJars != nil { 1769 transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJars) 1770 } 1771 if dep.TransitiveStaticLibsHeaderJars != nil { 1772 transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJars) 1773 } 1774 1775 tag := ctx.OtherModuleDependencyTag(module) 1776 _, isUsesLibDep := tag.(usesLibraryDependencyTag) 1777 if tag == libTag || tag == r8LibraryJarTag || isUsesLibDep { 1778 directLibs = append(directLibs, dep.HeaderJars...) 1779 } else if tag == staticLibTag { 1780 directStaticLibs = append(directStaticLibs, dep.HeaderJars...) 1781 } 1782 }) 1783 j.transitiveLibsHeaderJars = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs) 1784 j.transitiveStaticLibsHeaderJars = android.NewDepSet(android.POSTORDER, directStaticLibs, transitiveStaticLibs) 1785} 1786 1787func (j *Module) HeaderJars() android.Paths { 1788 if j.headerJarFile == nil { 1789 return nil 1790 } 1791 return android.Paths{j.headerJarFile} 1792} 1793 1794func (j *Module) ImplementationJars() android.Paths { 1795 if j.implementationJarFile == nil { 1796 return nil 1797 } 1798 return android.Paths{j.implementationJarFile} 1799} 1800 1801func (j *Module) DexJarBuildPath() OptionalDexJarPath { 1802 return j.dexJarFile 1803} 1804 1805func (j *Module) DexJarInstallPath() android.Path { 1806 return j.installFile 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) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 1822 return j.classLoaderContexts 1823} 1824 1825// Collect information for opening IDE project files in java/jdeps.go. 1826func (j *Module) IDEInfo(dpInfo *android.IdeInfo) { 1827 dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...) 1828 dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) 1829 dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) 1830 dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...) 1831 if j.expandJarjarRules != nil { 1832 dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String()) 1833 } 1834 dpInfo.Paths = append(dpInfo.Paths, j.modulePaths...) 1835 dpInfo.Static_libs = append(dpInfo.Static_libs, j.properties.Static_libs...) 1836 dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...) 1837} 1838 1839func (j *Module) CompilerDeps() []string { 1840 jdeps := []string{} 1841 jdeps = append(jdeps, j.properties.Libs...) 1842 jdeps = append(jdeps, j.properties.Static_libs...) 1843 return jdeps 1844} 1845 1846func (j *Module) hasCode(ctx android.ModuleContext) bool { 1847 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) 1848 return len(srcFiles) > 0 || len(ctx.GetDirectDepsWithTag(staticLibTag)) > 0 1849} 1850 1851// Implements android.ApexModule 1852func (j *Module) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 1853 return j.depIsInSameApex(ctx, dep) 1854} 1855 1856// Implements android.ApexModule 1857func (j *Module) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { 1858 sdkVersionSpec := j.SdkVersion(ctx) 1859 minSdkVersion := j.MinSdkVersion(ctx) 1860 if !minSdkVersion.Specified() { 1861 return fmt.Errorf("min_sdk_version is not specified") 1862 } 1863 // If the module is compiling against core (via sdk_version), skip comparison check. 1864 if sdkVersionSpec.Kind == android.SdkCore { 1865 return nil 1866 } 1867 if minSdkVersion.GreaterThan(sdkVersion) { 1868 return fmt.Errorf("newer SDK(%v)", minSdkVersion) 1869 } 1870 return nil 1871} 1872 1873func (j *Module) Stem() string { 1874 return proptools.StringDefault(j.overridableDeviceProperties.Stem, j.Name()) 1875} 1876 1877func (j *Module) JacocoReportClassesFile() android.Path { 1878 return j.jacocoReportClassesFile 1879} 1880 1881func (j *Module) IsInstallable() bool { 1882 return Bool(j.properties.Installable) 1883} 1884 1885type sdkLinkType int 1886 1887const ( 1888 // TODO(jiyong) rename these for better readability. Make the allowed 1889 // and disallowed link types explicit 1890 // order is important here. See rank() 1891 javaCore sdkLinkType = iota 1892 javaSdk 1893 javaSystem 1894 javaModule 1895 javaSystemServer 1896 javaPlatform 1897) 1898 1899func (lt sdkLinkType) String() string { 1900 switch lt { 1901 case javaCore: 1902 return "core Java API" 1903 case javaSdk: 1904 return "Android API" 1905 case javaSystem: 1906 return "system API" 1907 case javaModule: 1908 return "module API" 1909 case javaSystemServer: 1910 return "system server API" 1911 case javaPlatform: 1912 return "private API" 1913 default: 1914 panic(fmt.Errorf("unrecognized linktype: %d", lt)) 1915 } 1916} 1917 1918// rank determines the total order among sdkLinkType. An SDK link type of rank A can link to 1919// another SDK link type of rank B only when B <= A. For example, a module linking to Android SDK 1920// can't statically depend on modules that use Platform API. 1921func (lt sdkLinkType) rank() int { 1922 return int(lt) 1923} 1924 1925type moduleWithSdkDep interface { 1926 android.Module 1927 getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) 1928} 1929 1930func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) { 1931 switch name { 1932 case android.SdkCore.JavaLibraryName(ctx.Config()), "legacy.core.platform.api.stubs", "stable.core.platform.api.stubs", 1933 "stub-annotations", "private-stub-annotations-jar", 1934 "core-lambda-stubs", "core-generated-annotation-stubs": 1935 return javaCore, true 1936 case android.SdkPublic.JavaLibraryName(ctx.Config()): 1937 return javaSdk, true 1938 case android.SdkSystem.JavaLibraryName(ctx.Config()): 1939 return javaSystem, true 1940 case android.SdkModule.JavaLibraryName(ctx.Config()): 1941 return javaModule, true 1942 case android.SdkSystemServer.JavaLibraryName(ctx.Config()): 1943 return javaSystemServer, true 1944 case android.SdkTest.JavaLibraryName(ctx.Config()): 1945 return javaSystem, true 1946 } 1947 1948 if stub, linkType := moduleStubLinkType(name); stub { 1949 return linkType, true 1950 } 1951 1952 ver := m.SdkVersion(ctx) 1953 switch ver.Kind { 1954 case android.SdkCore: 1955 return javaCore, false 1956 case android.SdkSystem: 1957 return javaSystem, false 1958 case android.SdkPublic: 1959 return javaSdk, false 1960 case android.SdkModule: 1961 return javaModule, false 1962 case android.SdkSystemServer: 1963 return javaSystemServer, false 1964 case android.SdkPrivate, android.SdkNone, android.SdkCorePlatform, android.SdkTest: 1965 return javaPlatform, false 1966 } 1967 1968 if !ver.Valid() { 1969 panic(fmt.Errorf("sdk_version is invalid. got %q", ver.Raw)) 1970 } 1971 return javaSdk, false 1972} 1973 1974// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than 1975// this module's. See the comment on rank() for details and an example. 1976func (j *Module) checkSdkLinkType( 1977 ctx android.ModuleContext, dep moduleWithSdkDep, tag dependencyTag) { 1978 if ctx.Host() { 1979 return 1980 } 1981 1982 myLinkType, stubs := j.getSdkLinkType(ctx, ctx.ModuleName()) 1983 if stubs { 1984 return 1985 } 1986 depLinkType, _ := dep.getSdkLinkType(ctx, ctx.OtherModuleName(dep)) 1987 1988 if myLinkType.rank() < depLinkType.rank() { 1989 ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+ 1990 "In order to fix this, consider adjusting sdk_version: OR platform_apis: "+ 1991 "property of the source or target module so that target module is built "+ 1992 "with the same or smaller API set when compared to the source.", 1993 myLinkType, ctx.OtherModuleName(dep), depLinkType) 1994 } 1995} 1996 1997func (j *Module) collectDeps(ctx android.ModuleContext) deps { 1998 var deps deps 1999 2000 if ctx.Device() { 2001 sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) 2002 if sdkDep.invalidVersion { 2003 ctx.AddMissingDependencies(sdkDep.bootclasspath) 2004 ctx.AddMissingDependencies(sdkDep.java9Classpath) 2005 } else if sdkDep.useFiles { 2006 // sdkDep.jar is actually equivalent to turbine header.jar. 2007 deps.classpath = append(deps.classpath, sdkDep.jars...) 2008 deps.dexClasspath = append(deps.dexClasspath, sdkDep.jars...) 2009 deps.aidlPreprocess = sdkDep.aidl 2010 } else { 2011 deps.aidlPreprocess = sdkDep.aidl 2012 } 2013 } 2014 2015 sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName()) 2016 2017 j.collectTransitiveHeaderJars(ctx) 2018 ctx.VisitDirectDeps(func(module android.Module) { 2019 otherName := ctx.OtherModuleName(module) 2020 tag := ctx.OtherModuleDependencyTag(module) 2021 2022 if IsJniDepTag(tag) { 2023 // Handled by AndroidApp.collectAppDeps 2024 return 2025 } 2026 if tag == certificateTag { 2027 // Handled by AndroidApp.collectAppDeps 2028 return 2029 } 2030 2031 if dep, ok := module.(SdkLibraryDependency); ok { 2032 switch tag { 2033 case sdkLibTag, libTag: 2034 depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx)) 2035 deps.classpath = append(deps.classpath, depHeaderJars...) 2036 deps.dexClasspath = append(deps.dexClasspath, depHeaderJars...) 2037 case staticLibTag: 2038 ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName) 2039 } 2040 } else if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { 2041 dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) 2042 if sdkLinkType != javaPlatform && 2043 ctx.OtherModuleHasProvider(module, SyspropPublicStubInfoProvider) { 2044 // dep is a sysprop implementation library, but this module is not linking against 2045 // the platform, so it gets the sysprop public stubs library instead. Replace 2046 // dep with the JavaInfo from the SyspropPublicStubInfoProvider. 2047 syspropDep := ctx.OtherModuleProvider(module, SyspropPublicStubInfoProvider).(SyspropPublicStubInfo) 2048 dep = syspropDep.JavaInfo 2049 } 2050 switch tag { 2051 case bootClasspathTag: 2052 deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...) 2053 case sdkLibTag, libTag, instrumentationForTag: 2054 if _, ok := module.(*Plugin); ok { 2055 ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName) 2056 } 2057 deps.classpath = append(deps.classpath, dep.HeaderJars...) 2058 deps.dexClasspath = append(deps.dexClasspath, dep.HeaderJars...) 2059 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) 2060 addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...) 2061 deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine 2062 case java9LibTag: 2063 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...) 2064 case staticLibTag: 2065 if _, ok := module.(*Plugin); ok { 2066 ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName) 2067 } 2068 deps.classpath = append(deps.classpath, dep.HeaderJars...) 2069 deps.staticJars = append(deps.staticJars, dep.ImplementationJars...) 2070 deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...) 2071 deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...) 2072 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) 2073 addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...) 2074 // Turbine doesn't run annotation processors, so any module that uses an 2075 // annotation processor that generates API is incompatible with the turbine 2076 // optimization. 2077 deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine 2078 case pluginTag: 2079 if plugin, ok := module.(*Plugin); ok { 2080 if plugin.pluginProperties.Processor_class != nil { 2081 addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.pluginProperties.Processor_class) 2082 } else { 2083 addPlugins(&deps, dep.ImplementationAndResourcesJars) 2084 } 2085 // Turbine doesn't run annotation processors, so any module that uses an 2086 // annotation processor that generates API is incompatible with the turbine 2087 // optimization. 2088 deps.disableTurbine = deps.disableTurbine || Bool(plugin.pluginProperties.Generates_api) 2089 } else { 2090 ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName) 2091 } 2092 case errorpronePluginTag: 2093 if _, ok := module.(*Plugin); ok { 2094 deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...) 2095 } else { 2096 ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName) 2097 } 2098 case exportedPluginTag: 2099 if plugin, ok := module.(*Plugin); ok { 2100 j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...) 2101 if plugin.pluginProperties.Processor_class != nil { 2102 j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.pluginProperties.Processor_class) 2103 } 2104 // Turbine doesn't run annotation processors, so any module that uses an 2105 // annotation processor that generates API is incompatible with the turbine 2106 // optimization. 2107 j.exportedDisableTurbine = Bool(plugin.pluginProperties.Generates_api) 2108 } else { 2109 ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName) 2110 } 2111 case kotlinStdlibTag: 2112 deps.kotlinStdlib = append(deps.kotlinStdlib, dep.HeaderJars...) 2113 case kotlinAnnotationsTag: 2114 deps.kotlinAnnotations = dep.HeaderJars 2115 case kotlinPluginTag: 2116 deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...) 2117 case syspropPublicStubDepTag: 2118 // This is a sysprop implementation library, forward the JavaInfoProvider from 2119 // the corresponding sysprop public stub library as SyspropPublicStubInfoProvider. 2120 ctx.SetProvider(SyspropPublicStubInfoProvider, SyspropPublicStubInfo{ 2121 JavaInfo: dep, 2122 }) 2123 } 2124 } else if dep, ok := module.(android.SourceFileProducer); ok { 2125 switch tag { 2126 case sdkLibTag, libTag: 2127 checkProducesJars(ctx, dep) 2128 deps.classpath = append(deps.classpath, dep.Srcs()...) 2129 deps.dexClasspath = append(deps.classpath, dep.Srcs()...) 2130 case staticLibTag: 2131 checkProducesJars(ctx, dep) 2132 deps.classpath = append(deps.classpath, dep.Srcs()...) 2133 deps.staticJars = append(deps.staticJars, dep.Srcs()...) 2134 deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...) 2135 } 2136 } else { 2137 switch tag { 2138 case bootClasspathTag: 2139 // If a system modules dependency has been added to the bootclasspath 2140 // then add its libs to the bootclasspath. 2141 sm := module.(SystemModulesProvider) 2142 deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars()...) 2143 2144 case systemModulesTag: 2145 if deps.systemModules != nil { 2146 panic("Found two system module dependencies") 2147 } 2148 sm := module.(SystemModulesProvider) 2149 outputDir, outputDeps := sm.OutputDirAndDeps() 2150 deps.systemModules = &systemModules{outputDir, outputDeps} 2151 2152 case instrumentationForTag: 2153 ctx.PropertyErrorf("instrumentation_for", "dependency %q of type %q does not provide JavaInfo so is unsuitable for use with this property", ctx.OtherModuleName(module), ctx.OtherModuleType(module)) 2154 } 2155 } 2156 2157 addCLCFromDep(ctx, module, j.classLoaderContexts) 2158 }) 2159 2160 return deps 2161} 2162 2163func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) { 2164 deps.processorPath = append(deps.processorPath, pluginJars...) 2165 deps.processorClasses = append(deps.processorClasses, pluginClasses...) 2166} 2167 2168// TODO(b/132357300) Generalize SdkLibrarComponentDependency to non-SDK libraries and merge with 2169// this interface. 2170type ProvidesUsesLib interface { 2171 ProvidesUsesLib() *string 2172} 2173 2174func (j *Module) ProvidesUsesLib() *string { 2175 return j.usesLibraryProperties.Provides_uses_lib 2176} 2177 2178type ModuleWithStem interface { 2179 Stem() string 2180} 2181 2182var _ ModuleWithStem = (*Module)(nil) 2183 2184func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { 2185 switch ctx.ModuleType() { 2186 case "java_library", "java_library_host", "java_library_static": 2187 if lib, ok := ctx.Module().(*Library); ok { 2188 javaLibraryBp2Build(ctx, lib) 2189 } 2190 case "java_binary_host": 2191 if binary, ok := ctx.Module().(*Binary); ok { 2192 javaBinaryHostBp2Build(ctx, binary) 2193 } 2194 } 2195} 2196