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