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 "encoding/gob" 19 "fmt" 20 "path/filepath" 21 "reflect" 22 "slices" 23 "strconv" 24 "strings" 25 26 "github.com/google/blueprint" 27 "github.com/google/blueprint/depset" 28 "github.com/google/blueprint/pathtools" 29 "github.com/google/blueprint/proptools" 30 31 "android/soong/android" 32 "android/soong/dexpreopt" 33 "android/soong/java/config" 34) 35 36// This file contains the definition and the implementation of the base module that most 37// source-based Java module structs embed. 38 39// TODO: 40// Autogenerated files: 41// Renderscript 42// Post-jar passes: 43// Proguard 44// Rmtypedefs 45// DroidDoc 46// Findbugs 47 48// Properties that are common to most Java modules, i.e. whether it's a host or device module. 49type CommonProperties struct { 50 // list of source files used to compile the Java module. May be .java, .kt, .logtags, .proto, 51 // or .aidl files. 52 Srcs []string `android:"path,arch_variant"` 53 54 // list Kotlin of source files containing Kotlin code that should be treated as common code in 55 // a codebase that supports Kotlin multiplatform. See 56 // https://kotlinlang.org/docs/reference/multiplatform.html. May be only be .kt files. 57 Common_srcs []string `android:"path,arch_variant"` 58 59 // list of source files that should not be used to build the Java module. 60 // This is most useful in the arch/multilib variants to remove non-common files 61 Exclude_srcs []string `android:"path,arch_variant"` 62 63 // list of Kotlin source files that should excluded from the list of common_srcs. 64 Exclude_common_srcs []string `android:"path,arch_variant"` 65 66 // list of directories containing Java resources 67 Java_resource_dirs []string `android:"arch_variant"` 68 69 // list of directories that should be excluded from java_resource_dirs 70 Exclude_java_resource_dirs []string `android:"arch_variant"` 71 72 // list of files to use as Java resources 73 Java_resources proptools.Configurable[[]string] `android:"path,arch_variant"` 74 75 // list of files that should be excluded from java_resources and java_resource_dirs 76 Exclude_java_resources []string `android:"path,arch_variant"` 77 78 // Same as java_resources, but modules added here will use the device variant. Can be useful 79 // for making a host test that tests the contents of a device built app. 80 Device_common_java_resources proptools.Configurable[[]string] `android:"path_device_common"` 81 82 // Same as java_resources, but modules added here will use the device's os variant and the 83 // device's first architecture variant. Can be useful for making a host test that tests the 84 // contents of a native device built app. 85 Device_first_java_resources proptools.Configurable[[]string] `android:"path_device_first"` 86 87 // list of module-specific flags that will be used for javac compiles 88 Javacflags []string `android:"arch_variant"` 89 90 // list of module-specific flags that will be used for kotlinc compiles 91 Kotlincflags []string `android:"arch_variant"` 92 93 // Kotlin language version to target. Currently only 1.9 and 2 are supported. 94 // See kotlinc's `-language-version` flag. 95 Kotlin_lang_version *string 96 97 // list of java libraries that will be in the classpath 98 Libs []string `android:"arch_variant"` 99 100 // list of java libraries that will be compiled into the resulting jar 101 Static_libs proptools.Configurable[[]string] `android:"arch_variant"` 102 103 // manifest file to be included in resulting jar 104 Manifest *string `android:"path"` 105 106 // if not blank, run jarjar using the specified rules file 107 Jarjar_rules *string `android:"path,arch_variant"` 108 109 // java class names to rename with jarjar when a reverse dependency has a jarjar_prefix 110 // property. 111 Jarjar_rename []string 112 113 // if not blank, used as prefix to generate repackage rule 114 Jarjar_prefix *string 115 116 // Number of shards for jarjar. It needs to be an integer represented as a string. 117 // TODO(b/383559945) change it to int, once Configurable supports the type. 118 Jarjar_shards proptools.Configurable[string] 119 120 // If not blank, set the java version passed to javac as -source and -target 121 Java_version *string 122 123 // If set to true, allow this module to be dexed and installed on devices. Has no 124 // effect on host modules, which are always considered installable. 125 Installable *bool 126 127 // If set to true, include sources used to compile the module in to the final jar 128 Include_srcs *bool 129 130 // If not empty, classes are restricted to the specified packages and their sub-packages. 131 // This restriction is checked after applying jarjar rules and including static libs. 132 Permitted_packages []string 133 134 // List of modules to use as annotation processors 135 Plugins []string 136 137 // List of modules to use as kotlin plugin 138 Kotlin_plugins []string 139 140 // List of modules to export to libraries that directly depend on this library as annotation 141 // processors. Note that if the plugins set generates_api: true this will disable the turbine 142 // optimization on modules that depend on this module, which will reduce parallelism and cause 143 // more recompilation. 144 Exported_plugins []string 145 146 // The number of Java source entries each Javac instance can process 147 Javac_shard_size *int64 148 149 // Add host jdk tools.jar to bootclasspath 150 Use_tools_jar *bool 151 152 Openjdk9 struct { 153 // List of source files that should only be used when passing -source 1.9 or higher 154 Srcs []string `android:"path"` 155 156 // List of javac flags that should only be used when passing -source 1.9 or higher 157 Javacflags []string 158 } 159 160 // When compiling language level 9+ .java code in packages that are part of 161 // a system module, patch_module names the module that your sources and 162 // dependencies should be patched into. The Android runtime currently 163 // doesn't implement the JEP 261 module system so this option is only 164 // supported at compile time. It should only be needed to compile tests in 165 // packages that exist in libcore and which are inconvenient to move 166 // elsewhere. 167 Patch_module *string 168 169 Jacoco struct { 170 // List of classes to include for instrumentation with jacoco to collect coverage 171 // information at runtime when building with coverage enabled. If unset defaults to all 172 // classes. 173 // Supports '*' as the last character of an entry in the list as a wildcard match. 174 // If preceded by '.' it matches all classes in the package and subpackages, otherwise 175 // it matches classes in the package that have the class name as a prefix. 176 Include_filter []string 177 178 // List of classes to exclude from instrumentation with jacoco to collect coverage 179 // information at runtime when building with coverage enabled. Overrides classes selected 180 // by the include_filter property. 181 // Supports '*' as the last character of an entry in the list as a wildcard match. 182 // If preceded by '.' it matches all classes in the package and subpackages, otherwise 183 // it matches classes in the package that have the class name as a prefix. 184 Exclude_filter []string 185 } 186 187 Errorprone struct { 188 // List of javac flags that should only be used when running errorprone. 189 Javacflags []string 190 191 // List of java_plugin modules that provide extra errorprone checks. 192 Extra_check_modules []string 193 194 // This property can be in 3 states. When set to true, errorprone will 195 // be run during the regular build. When set to false, errorprone will 196 // never be run. When unset, errorprone will be run when the RUN_ERROR_PRONE 197 // environment variable is true. Setting this to false will improve build 198 // performance more than adding -XepDisableAllChecks in javacflags. 199 Enabled *bool 200 } 201 202 Proto struct { 203 // List of extra options that will be passed to the proto generator. 204 Output_params []string 205 } 206 207 // If true, then jacocoagent is automatically added as a libs dependency so that 208 // r8 will not strip instrumentation classes out of dexed libraries. 209 Instrument bool `blueprint:"mutated"` 210 // If true, then the module supports statically including the jacocoagent 211 // into the library. 212 Supports_static_instrumentation bool `blueprint:"mutated"` 213 214 // List of files to include in the META-INF/services folder of the resulting jar. 215 Services []string `android:"path,arch_variant"` 216 217 // If true, package the kotlin stdlib into the jar. Defaults to true. 218 Static_kotlin_stdlib *bool `android:"arch_variant"` 219 220 // A list of java_library instances that provide additional hiddenapi annotations for the library. 221 Hiddenapi_additional_annotations []string 222 223 // Additional srcJars tacked in by GeneratedJavaLibraryModule 224 Generated_srcjars []android.Path `android:"mutated"` 225 226 // intermediate aconfig cache file tacked in by GeneratedJavaLibraryModule 227 Aconfig_Cache_files []android.Path `android:"mutated"` 228 229 // If true, then only the headers are built and not the implementation jar. 230 Headers_only *bool 231 232 // A list of files or dependencies to make available to the build sandbox. This is 233 // useful if source files are symlinks, the targets of the symlinks must be listed here. 234 // Note that currently not all actions implemented by android_apps are sandboxed, so you 235 // may only see this being necessary in lint builds. 236 Compile_data []string `android:"path"` 237 238 // Property signifying whether the module compiles stubs or not. 239 // Should be set to true when srcs of this module are stub files. 240 // This property does not need to be set to true when the module depends on 241 // the stubs via libs, but should be set to true when the module depends on 242 // the stubs via static libs. 243 Is_stubs_module *bool 244 245 Ravenizer struct { 246 // If true, enable the "Ravenizer" tool on the output jar. 247 // "Ravenizer" is a tool for Ravenwood tests, but it can also be enabled on other kinds 248 // of java targets. 249 Enabled *bool 250 251 // If true, the "Ravenizer" tool will remove all Mockito and DexMaker 252 // classes from the output jar. 253 Strip_mockito *bool 254 } 255 256 // Contributing api surface of the stub module. Is not visible to bp modules, and should 257 // only be set for stub submodules generated by the java_sdk_library 258 Stub_contributing_api *string `blueprint:"mutated"` 259 260 // If true, enable the "ApiMapper" tool on the output jar. "ApiMapper" is a tool to inject 261 // bytecode to log API calls. 262 ApiMapper bool `blueprint:"mutated"` 263} 264 265// Properties that are specific to device modules. Host module factories should not add these when 266// constructing a new module. 267type DeviceProperties struct { 268 // If not blank, set to the version of the sdk to compile against. 269 // Defaults to an empty string, which compiles the module against the private platform APIs. 270 // Values are of one of the following forms: 271 // 1) numerical API level, "current", "none", or "core_platform" 272 // 2) An SDK kind with an API level: "<sdk kind>_<API level>" 273 // See build/soong/android/sdk_version.go for the complete and up to date list of SDK kinds. 274 // If the SDK kind is empty, it will be set to public. 275 Sdk_version *string 276 277 // if not blank, set the maximum version of the sdk that the compiled artifacts will run against. 278 // Defaults to empty string "". See sdk_version for possible values. 279 Max_sdk_version *string 280 281 // if not blank, set the maxSdkVersion properties of permission and uses-permission tags. 282 // Defaults to empty string "". See sdk_version for possible values. 283 Replace_max_sdk_version_placeholder *string 284 285 // if not blank, set the targetSdkVersion in the AndroidManifest.xml. 286 // Defaults to sdk_version if not set. See sdk_version for possible values. 287 Target_sdk_version *string 288 289 // Whether to compile against the platform APIs instead of an SDK. 290 // If true, then sdk_version must be empty. The value of this field 291 // is ignored when module's type isn't android_app, android_test, or android_test_helper_app. 292 Platform_apis *bool 293 294 Aidl struct { 295 // Top level directories to pass to aidl tool 296 Include_dirs []string 297 298 // Directories rooted at the Android.bp file to pass to aidl tool 299 Local_include_dirs []string 300 301 // directories that should be added as include directories for any aidl sources of modules 302 // that depend on this module, as well as to aidl for this module. 303 Export_include_dirs []string 304 305 // whether to generate traces (for systrace) for this interface 306 Generate_traces *bool 307 308 // whether to generate Binder#GetTransaction name method. 309 Generate_get_transaction_name *bool 310 311 // whether all interfaces should be annotated with required permissions. 312 Enforce_permissions *bool 313 314 // allowlist for interfaces that (temporarily) do not require annotation for permissions. 315 Enforce_permissions_exceptions []string `android:"path"` 316 317 // list of flags that will be passed to the AIDL compiler 318 Flags []string 319 } 320 321 // If true, export a copy of the module as a -hostdex module for host testing. 322 Hostdex *bool 323 324 Target struct { 325 Hostdex struct { 326 // Additional required dependencies to add to -hostdex modules. 327 Required []string 328 } 329 } 330 331 // When targeting 1.9 and above, override the modules to use with --system, 332 // otherwise provides defaults libraries to add to the bootclasspath. 333 System_modules *string 334 335 IsSDKLibrary bool `blueprint:"mutated"` 336 337 // If true, generate the signature file of APK Signing Scheme V4, along side the signed APK file. 338 // Defaults to false. 339 V4_signature *bool 340 341 // Only for libraries created by a sysprop_library module, SyspropPublicStub is the name of the 342 // public stubs library. 343 SyspropPublicStub string `blueprint:"mutated"` 344 345 HiddenAPIPackageProperties 346 HiddenAPIFlagFileProperties 347} 348 349// Properties that can be overridden by overriding module (e.g. override_android_app) 350type OverridableProperties struct { 351 // set the name of the output. If not set, `name` is used. 352 // To override a module with this property set, overriding module might need to set this as well. 353 // Otherwise, both the overridden and the overriding modules will have the same output name, which 354 // can cause the duplicate output error. 355 Stem *string 356 357 // if not blank, set the minimum version of the sdk that the compiled artifacts will run against. 358 // Defaults to sdk_version if not set. See sdk_version for possible values. 359 Min_sdk_version *string 360} 361 362// Functionality common to Module and Import 363// 364// It is embedded in Module so its functionality can be used by methods in Module 365// but it is currently only initialized by Import and Library. 366type embeddableInModuleAndImport struct { 367 368 // Functionality related to this being used as a component of a java_sdk_library. 369 EmbeddableSdkLibraryComponent 370} 371 372func (e *embeddableInModuleAndImport) initModuleAndImport(module android.Module) { 373 e.initSdkLibraryComponent(module) 374} 375 376// Module/Import's OutgoingDepIsInSameApex(...) delegates to this method. 377// 378// This cannot implement OutgoingDepIsInSameApex(...) directly as that leads to ambiguity with 379// the one provided by ApexModuleBase. 380func depIsInSameApex(tag blueprint.DependencyTag) bool { 381 // dependencies other than the static linkage are all considered crossing APEX boundary 382 if tag == staticLibTag { 383 return true 384 } 385 return false 386} 387 388// OptionalDexJarPath can be either unset, hold a valid path to a dex jar file, 389// or an invalid path describing the reason it is invalid. 390// 391// It is unset if a dex jar isn't applicable, i.e. no build rule has been 392// requested to create one. 393// 394// If a dex jar has been requested to be built then it is set, and it may be 395// either a valid android.Path, or invalid with a reason message. The latter 396// happens if the source that should produce the dex file isn't able to. 397// 398// E.g. it is invalid with a reason message if there is a prebuilt APEX that 399// could produce the dex jar through a deapexer module, but the APEX isn't 400// installable so doing so wouldn't be safe. 401type OptionalDexJarPath struct { 402 isSet bool 403 path android.OptionalPath 404} 405 406// IsSet returns true if a path has been set, either invalid or valid. 407func (o OptionalDexJarPath) IsSet() bool { 408 return o.isSet 409} 410 411// Valid returns true if there is a path that is valid. 412func (o OptionalDexJarPath) Valid() bool { 413 return o.isSet && o.path.Valid() 414} 415 416// Path returns the valid path, or panics if it's either not set or is invalid. 417func (o OptionalDexJarPath) Path() android.Path { 418 if !o.isSet { 419 panic("path isn't set") 420 } 421 return o.path.Path() 422} 423 424// PathOrNil returns the path if it's set and valid, or else nil. 425func (o OptionalDexJarPath) PathOrNil() android.Path { 426 if o.Valid() { 427 return o.Path() 428 } 429 return nil 430} 431 432// InvalidReason returns the reason for an invalid path, which is never "". It 433// returns "" for an unset or valid path. 434func (o OptionalDexJarPath) InvalidReason() string { 435 if !o.isSet { 436 return "" 437 } 438 return o.path.InvalidReason() 439} 440 441func (o OptionalDexJarPath) String() string { 442 if !o.isSet { 443 return "<unset>" 444 } 445 return o.path.String() 446} 447 448// makeUnsetDexJarPath returns an unset OptionalDexJarPath. 449func makeUnsetDexJarPath() OptionalDexJarPath { 450 return OptionalDexJarPath{isSet: false} 451} 452 453// makeDexJarPathFromOptionalPath returns an OptionalDexJarPath that is set with 454// the given OptionalPath, which may be valid or invalid. 455func makeDexJarPathFromOptionalPath(path android.OptionalPath) OptionalDexJarPath { 456 return OptionalDexJarPath{isSet: true, path: path} 457} 458 459// makeDexJarPathFromPath returns an OptionalDexJarPath that is set with the 460// valid given path. It returns an unset OptionalDexJarPath if the given path is 461// nil. 462func makeDexJarPathFromPath(path android.Path) OptionalDexJarPath { 463 if path == nil { 464 return makeUnsetDexJarPath() 465 } 466 return makeDexJarPathFromOptionalPath(android.OptionalPathForPath(path)) 467} 468 469// Module contains the properties and members used by all java module types 470type Module struct { 471 android.ModuleBase 472 android.DefaultableModuleBase 473 android.ApexModuleBase 474 475 // Functionality common to Module and Import. 476 embeddableInModuleAndImport 477 478 properties CommonProperties 479 protoProperties android.ProtoProperties 480 deviceProperties DeviceProperties 481 482 overridableProperties OverridableProperties 483 sourceProperties android.SourceProperties 484 485 // jar file containing header classes including static library dependencies, suitable for 486 // inserting into the bootclasspath/classpath of another compile 487 headerJarFile android.Path 488 489 // jar file containing implementation classes including static library dependencies but no 490 // resources 491 implementationJarFile android.Path 492 493 // args and dependencies to package source files into a srcjar 494 srcJarArgs []string 495 srcJarDeps android.Paths 496 497 // the source files of this module and all its static dependencies 498 transitiveSrcFiles depset.DepSet[android.Path] 499 500 // jar file containing implementation classes and resources including static library 501 // dependencies 502 implementationAndResourcesJar android.Path 503 504 // output file containing classes.dex and resources 505 dexJarFile OptionalDexJarPath 506 507 // output file containing uninstrumented classes that will be instrumented by jacoco 508 jacocoReportClassesFile android.Path 509 510 // output file of the module, which may be a classes jar or a dex jar 511 outputFile android.Path 512 extraOutputFiles android.Paths 513 514 exportAidlIncludeDirs android.Paths 515 ignoredAidlPermissionList android.Paths 516 517 logtagsSrcs android.Paths 518 519 // installed file for binary dependency 520 installFile android.Path 521 522 // installed file for hostdex copy 523 hostdexInstallFile android.InstallPath 524 525 // list of unique .java and .kt source files 526 uniqueSrcFiles android.Paths 527 528 // list of srcjars that was passed to javac 529 compiledSrcJars android.Paths 530 531 // manifest file to use instead of properties.Manifest 532 overrideManifest android.OptionalPath 533 534 // list of plugins that this java module is exporting 535 exportedPluginJars android.Paths 536 537 // list of plugins that this java module is exporting 538 exportedPluginClasses []string 539 540 // if true, the exported plugins generate API and require disabling turbine. 541 exportedDisableTurbine bool 542 543 // list of source files, collected from srcFiles with unique java and all kt files, 544 // will be used by android.IDEInfo struct 545 expandIDEInfoCompiledSrcs []string 546 547 // expanded Jarjar_rules 548 expandJarjarRules android.Path 549 550 // jarjar rule for inherited jarjar rules 551 repackageJarjarRules android.Path 552 553 // Extra files generated by the module type to be added as java resources. 554 extraResources android.Paths 555 556 hiddenAPI 557 dexer 558 dexpreopter 559 usesLibrary 560 linter 561 562 // list of the xref extraction files 563 kytheFiles android.Paths 564 kytheKotlinFiles android.Paths 565 566 hideApexVariantFromMake bool 567 568 sdkVersion android.SdkSpec 569 minSdkVersion android.ApiLevel 570 maxSdkVersion android.ApiLevel 571 572 sourceExtensions []string 573 574 annoSrcJars android.Paths 575 576 // output file name based on Stem property. 577 // This should be set in every ModuleWithStem's GenerateAndroidBuildActions 578 // or the module should override Stem(). 579 stem string 580 581 // Values that will be set in the JarJarProvider data for jarjar repackaging, 582 // and merged with our dependencies' rules. 583 jarjarRenameRules map[string]string 584 585 stubsLinkType StubsLinkType 586 587 // Paths to the aconfig intermediate cache files that are provided by the 588 // java_aconfig_library or java_library modules that are statically linked 589 // to this module. Does not contain cache files from all transitive dependencies. 590 aconfigCacheFiles android.Paths 591 592 // List of soong module dependencies required to compile the current module. 593 // This information is printed out to `Dependencies` field in module_bp_java_deps.json 594 compileDepNames []string 595 596 ravenizer struct { 597 enabled bool 598 } 599} 600 601var _ android.InstallableModule = (*Module)(nil) 602 603// To satisfy the InstallableModule interface 604func (j *Module) StaticDependencyTags() []blueprint.DependencyTag { 605 return []blueprint.DependencyTag{staticLibTag} 606} 607 608// To satisfy the InstallableModule interface 609func (j *Module) DynamicDependencyTags() []blueprint.DependencyTag { 610 return []blueprint.DependencyTag{libTag, sdkLibTag, bootClasspathTag, systemModulesTag, 611 instrumentationForTag, java9LibTag} 612} 613 614// Overrides android.ModuleBase.InstallInProduct() 615func (j *Module) InstallInProduct() bool { 616 return j.ProductSpecific() 617} 618 619var _ android.StubsAvailableModule = (*Module)(nil) 620 621// To safisfy the StubsAvailableModule interface 622func (j *Module) IsStubsModule() bool { 623 return proptools.Bool(j.properties.Is_stubs_module) 624} 625 626func CheckStableSdkVersion(ctx android.BaseModuleContext, module android.ModuleProxy) error { 627 if info, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { 628 if info.SdkVersion.Stable() { 629 return nil 630 } 631 if info.SdkVersion.Kind == android.SdkCorePlatform { 632 if useLegacyCorePlatformApi(ctx, android.OtherModulePointerProviderOrDefault(ctx, module, android.CommonModuleInfoProvider).BaseModuleName) { 633 return fmt.Errorf("non stable SDK %v - uses legacy core platform", info.SdkVersion) 634 } else { 635 // Treat stable core platform as stable. 636 return nil 637 } 638 } else { 639 return fmt.Errorf("non stable SDK %v", info.SdkVersion) 640 } 641 } 642 643 return nil 644} 645 646// checkSdkVersions enforces restrictions around SDK dependencies. 647func (j *Module) checkSdkVersions(ctx android.ModuleContext) { 648 if j.RequiresStableAPIs(ctx) { 649 if sc, ok := ctx.Module().(android.SdkContext); ok { 650 if !sc.SdkVersion(ctx).Specified() { 651 ctx.PropertyErrorf("sdk_version", 652 "sdk_version must have a value when the module is located at vendor or product(only if PRODUCT_ENFORCE_PRODUCT_PARTITION_INTERFACE is set).") 653 } 654 } 655 } 656 657 // Make sure this module doesn't statically link to modules with lower-ranked SDK link type. 658 // See rank() for details. 659 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { 660 tag := ctx.OtherModuleDependencyTag(module) 661 libInfo, isJavaLibrary := android.OtherModuleProvider(ctx, module, JavaLibraryInfoProvider) 662 _, isAndroidLibrary := android.OtherModuleProvider(ctx, module, AndroidLibraryInfoProvider) 663 _, isJavaAconfigLibrary := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider) 664 // Exclude java_aconfig_library modules to maintain consistency with existing behavior. 665 if (isJavaLibrary && !libInfo.Prebuilt && !isJavaAconfigLibrary) || isAndroidLibrary { 666 // TODO(satayev): cover other types as well, e.g. imports 667 switch tag { 668 case bootClasspathTag, sdkLibTag, libTag, staticLibTag, java9LibTag: 669 j.checkSdkLinkType(ctx, module) 670 } 671 } 672 }) 673} 674 675func (j *Module) checkPlatformAPI(ctx android.ModuleContext) { 676 if sc, ok := ctx.Module().(android.SdkContext); ok { 677 usePlatformAPI := proptools.Bool(j.deviceProperties.Platform_apis) 678 sdkVersionSpecified := sc.SdkVersion(ctx).Specified() 679 if usePlatformAPI && sdkVersionSpecified { 680 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.") 681 } else if !usePlatformAPI && !sdkVersionSpecified { 682 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") 683 } 684 685 } 686} 687 688func (j *Module) checkHeadersOnly(ctx android.ModuleContext) { 689 if _, ok := ctx.Module().(android.SdkContext); ok { 690 headersOnly := proptools.Bool(j.properties.Headers_only) 691 installable := proptools.Bool(j.properties.Installable) 692 693 if headersOnly && installable { 694 ctx.PropertyErrorf("headers_only", "This module has conflicting settings. headers_only is true which, which means this module doesn't generate an implementation jar. However installable is set to true.") 695 } 696 } 697} 698 699func (j *Module) addHostProperties() { 700 j.AddProperties( 701 &j.properties, 702 &j.overridableProperties, 703 &j.protoProperties, 704 &j.usesLibraryProperties, 705 ) 706} 707 708func (j *Module) addHostAndDeviceProperties() { 709 j.addHostProperties() 710 j.AddProperties( 711 &j.deviceProperties, 712 &j.dexer.dexProperties, 713 &j.dexpreoptProperties, 714 &j.linter.properties, 715 ) 716} 717 718// provideHiddenAPIPropertyInfo populates a HiddenAPIPropertyInfo from hidden API properties and 719// makes it available through the hiddenAPIPropertyInfoProvider. 720func (j *Module) provideHiddenAPIPropertyInfo(ctx android.ModuleContext) { 721 hiddenAPIInfo := newHiddenAPIPropertyInfo() 722 723 // Populate with flag file paths from the properties. 724 hiddenAPIInfo.extractFlagFilesFromProperties(ctx, &j.deviceProperties.HiddenAPIFlagFileProperties) 725 726 // Populate with package rules from the properties. 727 hiddenAPIInfo.extractPackageRulesFromProperties(&j.deviceProperties.HiddenAPIPackageProperties) 728 729 android.SetProvider(ctx, hiddenAPIPropertyInfoProvider, hiddenAPIInfo) 730} 731 732// helper method for java modules to set OutputFilesProvider 733func setOutputFiles(ctx android.ModuleContext, m Module) { 734 ctx.SetOutputFiles(append(android.PathsIfNonNil(m.outputFile), m.extraOutputFiles...), "") 735 ctx.SetOutputFiles(android.PathsIfNonNil(m.outputFile), android.DefaultDistTag) 736 ctx.SetOutputFiles(android.PathsIfNonNil(m.implementationAndResourcesJar), ".jar") 737 ctx.SetOutputFiles(android.PathsIfNonNil(m.headerJarFile), ".hjar") 738 if m.dexer.proguardDictionary.Valid() { 739 ctx.SetOutputFiles(android.Paths{m.dexer.proguardDictionary.Path()}, ".proguard_map") 740 } 741 ctx.SetOutputFiles(m.properties.Generated_srcjars, ".generated_srcjars") 742} 743 744func InitJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported) { 745 initJavaModule(module, hod, false) 746} 747 748func InitJavaModuleMultiTargets(module android.DefaultableModule, hod android.HostOrDeviceSupported) { 749 initJavaModule(module, hod, true) 750} 751 752func initJavaModule(module android.DefaultableModule, hod android.HostOrDeviceSupported, multiTargets bool) { 753 multilib := android.MultilibCommon 754 if multiTargets { 755 android.InitAndroidMultiTargetsArchModule(module, hod, multilib) 756 } else { 757 android.InitAndroidArchModule(module, hod, multilib) 758 } 759 android.InitDefaultableModule(module) 760} 761 762func (j *Module) shouldInstrument(ctx android.BaseModuleContext) bool { 763 return j.properties.Instrument && 764 ctx.Config().IsEnvTrue("EMMA_INSTRUMENT") && 765 ctx.DeviceConfig().JavaCoverageEnabledForPath(ctx.ModuleDir()) 766} 767 768func (j *Module) shouldApiMapper() bool { 769 return j.properties.ApiMapper 770} 771 772func (j *Module) shouldInstrumentStatic(ctx android.BaseModuleContext) bool { 773 return j.properties.Supports_static_instrumentation && 774 j.shouldInstrument(ctx) && 775 (ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_STATIC") || 776 ctx.Config().UnbundledBuild()) 777} 778 779func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool { 780 // Force enable the instrumentation for java code that is built for APEXes ... 781 // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent 782 // doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true. 783 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 784 isJacocoAgent := ctx.ModuleName() == "jacocoagent" 785 786 compileDex := Bool(j.dexProperties.Compile_dex) || Bool(j.properties.Installable) 787 if compileDex && !isJacocoAgent && !apexInfo.IsForPlatform() { 788 if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { 789 return true 790 } else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { 791 return true 792 } 793 } 794 return false 795} 796 797func (j *Module) setInstrument(value bool) { 798 j.properties.Instrument = value 799} 800 801func (j *Module) setApiMapper(value bool) { 802 j.properties.ApiMapper = value 803} 804 805func (j *Module) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 806 return android.SdkSpecFrom(ctx, String(j.deviceProperties.Sdk_version)) 807} 808 809func (j *Module) SystemModules() string { 810 return proptools.String(j.deviceProperties.System_modules) 811} 812 813func (j *Module) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 814 if j.overridableProperties.Min_sdk_version != nil { 815 return android.ApiLevelFrom(ctx, *j.overridableProperties.Min_sdk_version) 816 } 817 return j.SdkVersion(ctx).ApiLevel 818} 819 820func (j *Module) GetDeviceProperties() *DeviceProperties { 821 return &j.deviceProperties 822} 823 824func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 825 if j.deviceProperties.Max_sdk_version != nil { 826 return android.ApiLevelFrom(ctx, *j.deviceProperties.Max_sdk_version) 827 } 828 // Default is PrivateApiLevel 829 return android.SdkSpecPrivate.ApiLevel 830} 831 832func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel { 833 if j.deviceProperties.Replace_max_sdk_version_placeholder != nil { 834 return android.ApiLevelFrom(ctx, *j.deviceProperties.Replace_max_sdk_version_placeholder) 835 } 836 // Default is PrivateApiLevel 837 return android.SdkSpecPrivate.ApiLevel 838} 839 840func (j *Module) MinSdkVersionString() string { 841 return j.minSdkVersion.String() 842} 843 844func (j *Module) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 845 if j.deviceProperties.Target_sdk_version != nil { 846 return android.ApiLevelFrom(ctx, *j.deviceProperties.Target_sdk_version) 847 } 848 return j.SdkVersion(ctx).ApiLevel 849} 850 851func (j *Module) AvailableFor(what string) bool { 852 return android.CheckAvailableForApex(what, j.ApexAvailableFor()) 853} 854 855func (j *Module) ApexAvailableFor() []string { 856 list := j.ApexModuleBase.ApexAvailable() 857 if Bool(j.deviceProperties.Hostdex) { 858 // Exception: for hostdex: true libraries, the platform variant is created 859 // even if it's not marked as available to platform. In that case, the platform 860 // variant is used only for the hostdex and not installed to the device. 861 list = append(list, android.AvailableToPlatform) 862 } 863 return android.FirstUniqueStrings(list) 864} 865 866func (j *Module) staticLibs(ctx android.BaseModuleContext) []string { 867 return j.properties.Static_libs.GetOrDefault(ctx, nil) 868} 869 870func (j *Module) deps(ctx android.BottomUpMutatorContext) { 871 if ctx.Device() { 872 j.linter.deps(ctx) 873 874 sdkDeps(ctx, android.SdkContext(j), j.dexer) 875 876 if j.deviceProperties.SyspropPublicStub != "" { 877 // This is a sysprop implementation library that has a corresponding sysprop public 878 // stubs library, and a dependency on it so that dependencies on the implementation can 879 // be forwarded to the public stubs library when necessary. 880 ctx.AddVariationDependencies(nil, syspropPublicStubDepTag, j.deviceProperties.SyspropPublicStub) 881 } 882 } 883 884 libDeps := ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) 885 886 ctx.AddVariationDependencies(nil, staticLibTag, j.staticLibs(ctx)...) 887 888 // Add dependency on libraries that provide additional hidden api annotations. 889 ctx.AddVariationDependencies(nil, hiddenApiAnnotationsTag, j.properties.Hiddenapi_additional_annotations...) 890 891 // Add dependency on (soft) downstream libs from which to trace references during optimization. 892 traceRefs := j.dexProperties.Optimize.Trace_references_from.GetOrDefault(ctx, []string{}) 893 ctx.AddVariationDependencies(nil, traceReferencesTag, traceRefs...) 894 895 // For library dependencies that are component libraries (like stubs), add the implementation 896 // as a dependency (dexpreopt needs to be against the implementation library, not stubs). 897 for _, dep := range libDeps { 898 if dep != nil { 899 if component, ok := dep.(SdkLibraryComponentDependency); ok { 900 if lib := component.OptionalSdkLibraryImplementation(); lib != nil { 901 // Add library as optional if it's one of the optional compatibility libs or it's 902 // explicitly listed in the optional_uses_libs property. 903 tag := usesLibReqTag 904 if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) || 905 android.InList(*lib, j.usesLibrary.usesLibraryProperties.Optional_uses_libs.GetOrDefault(ctx, nil)) { 906 tag = usesLibOptTag 907 } 908 ctx.AddVariationDependencies(nil, tag, *lib) 909 } 910 } 911 } 912 } 913 914 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), pluginTag, j.properties.Plugins...) 915 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag, j.properties.Kotlin_plugins...) 916 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), errorpronePluginTag, j.properties.Errorprone.Extra_check_modules...) 917 ctx.AddFarVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), exportedPluginTag, j.properties.Exported_plugins...) 918 919 android.ProtoDeps(ctx, &j.protoProperties) 920 if j.hasSrcExt(".proto") { 921 protoDeps(ctx, &j.protoProperties) 922 } 923 924 if j.hasSrcExt(".kt") { 925 // TODO(ccross): move this to a mutator pass that can tell if generated sources contain 926 // Kotlin files 927 tag := staticLibTag 928 if !BoolDefault(j.properties.Static_kotlin_stdlib, true) { 929 tag = libTag 930 } 931 ctx.AddVariationDependencies(nil, tag, 932 "kotlin-stdlib", "kotlin-stdlib-jdk7", "kotlin-stdlib-jdk8", "kotlin-annotations") 933 } 934 935 // Framework libraries need special handling in static coverage builds: they should not have 936 // static dependency on jacoco, otherwise there would be multiple conflicting definitions of 937 // the same jacoco classes coming from different bootclasspath jars. 938 if inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { 939 if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { 940 j.properties.Instrument = true 941 } 942 } else if j.shouldInstrumentStatic(ctx) { 943 ctx.AddVariationDependencies(nil, staticLibTag, "jacocoagent") 944 } 945 946 if j.useCompose(ctx) { 947 ctx.AddVariationDependencies(ctx.Config().BuildOSCommonTarget.Variations(), kotlinPluginTag, 948 "kotlin-compose-compiler-plugin") 949 } 950} 951 952func hasSrcExt(srcs []string, ext string) bool { 953 for _, src := range srcs { 954 if filepath.Ext(src) == ext { 955 return true 956 } 957 } 958 959 return false 960} 961 962func (j *Module) hasSrcExt(ext string) bool { 963 return hasSrcExt(j.properties.Srcs, ext) 964} 965 966func (j *Module) individualAidlFlags(ctx android.ModuleContext, aidlFile android.Path) string { 967 var flags string 968 969 if Bool(j.deviceProperties.Aidl.Enforce_permissions) { 970 if !android.InList(aidlFile.String(), j.ignoredAidlPermissionList.Strings()) { 971 flags = "-Wmissing-permission-annotation -Werror" 972 } 973 } 974 return flags 975} 976 977func (j *Module) aidlFlags(ctx android.ModuleContext, aidlPreprocess android.OptionalPath, 978 aidlIncludeDirs android.Paths, aidlSrcs android.Paths) (string, android.Paths) { 979 980 aidlIncludes := android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Local_include_dirs) 981 aidlIncludes = append(aidlIncludes, 982 android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs)...) 983 aidlIncludes = append(aidlIncludes, 984 android.PathsForSource(ctx, j.deviceProperties.Aidl.Include_dirs)...) 985 986 var flags []string 987 var deps android.Paths 988 var includeDirs android.Paths 989 990 flags = append(flags, j.deviceProperties.Aidl.Flags...) 991 992 if aidlPreprocess.Valid() { 993 flags = append(flags, "-p"+aidlPreprocess.String()) 994 deps = append(deps, aidlPreprocess.Path()) 995 } else if len(aidlIncludeDirs) > 0 { 996 includeDirs = append(includeDirs, aidlIncludeDirs...) 997 } 998 999 if len(j.exportAidlIncludeDirs) > 0 { 1000 includeDirs = append(includeDirs, j.exportAidlIncludeDirs...) 1001 } 1002 1003 if len(aidlIncludes) > 0 { 1004 includeDirs = append(includeDirs, aidlIncludes...) 1005 } 1006 1007 includeDirs = append(includeDirs, android.PathForModuleSrc(ctx)) 1008 if src := android.ExistentPathForSource(ctx, ctx.ModuleDir(), "src"); src.Valid() { 1009 includeDirs = append(includeDirs, src.Path()) 1010 } 1011 flags = append(flags, android.JoinWithPrefix(includeDirs.Strings(), "-I")) 1012 // add flags for dirs containing AIDL srcs that haven't been specified yet 1013 flags = append(flags, genAidlIncludeFlags(ctx, aidlSrcs, includeDirs)) 1014 1015 sdkVersion := (j.SdkVersion(ctx)).Kind 1016 defaultTrace := ((sdkVersion == android.SdkSystemServer) || (sdkVersion == android.SdkCore) || (sdkVersion == android.SdkCorePlatform) || (sdkVersion == android.SdkModule) || (sdkVersion == android.SdkSystem)) 1017 if proptools.BoolDefault(j.deviceProperties.Aidl.Generate_traces, defaultTrace) { 1018 flags = append(flags, "-t") 1019 } 1020 1021 if Bool(j.deviceProperties.Aidl.Generate_get_transaction_name) { 1022 flags = append(flags, "--transaction_names") 1023 } 1024 1025 if Bool(j.deviceProperties.Aidl.Enforce_permissions) { 1026 exceptions := j.deviceProperties.Aidl.Enforce_permissions_exceptions 1027 j.ignoredAidlPermissionList = android.PathsForModuleSrcExcludes(ctx, exceptions, nil) 1028 } 1029 1030 aidlMinSdkVersion := j.MinSdkVersion(ctx).String() 1031 flags = append(flags, "--min_sdk_version="+aidlMinSdkVersion) 1032 1033 return strings.Join(flags, " "), deps 1034} 1035 1036func (j *Module) collectBuilderFlags(ctx android.ModuleContext, deps deps) javaBuilderFlags { 1037 1038 var flags javaBuilderFlags 1039 1040 // javaVersion flag. 1041 flags.javaVersion = getJavaVersion(ctx, String(j.properties.Java_version), android.SdkContext(j)) 1042 1043 epEnabled := j.properties.Errorprone.Enabled 1044 if (ctx.Config().RunErrorProne() && epEnabled == nil) || Bool(epEnabled) { 1045 if config.ErrorProneClasspath == nil && !ctx.Config().RunningInsideUnitTest() { 1046 ctx.ModuleErrorf("cannot build with Error Prone, missing external/error_prone?") 1047 } 1048 1049 errorProneFlags := []string{ 1050 "-Xplugin:ErrorProne", 1051 "${config.ErrorProneChecks}", 1052 } 1053 errorProneFlags = append(errorProneFlags, j.properties.Errorprone.Javacflags...) 1054 1055 flags.errorProneExtraJavacFlags = "${config.ErrorProneHeapFlags} ${config.ErrorProneFlags} " + 1056 "'" + strings.Join(errorProneFlags, " ") + "'" 1057 flags.errorProneProcessorPath = classpath(android.PathsForSource(ctx, config.ErrorProneClasspath)) 1058 } 1059 1060 // classpath 1061 flags.bootClasspath = append(flags.bootClasspath, deps.bootClasspath...) 1062 flags.classpath = append(flags.classpath, deps.classpath...) 1063 flags.dexClasspath = append(flags.dexClasspath, deps.dexClasspath...) 1064 flags.java9Classpath = append(flags.java9Classpath, deps.java9Classpath...) 1065 flags.processorPath = append(flags.processorPath, deps.processorPath...) 1066 flags.errorProneProcessorPath = append(flags.errorProneProcessorPath, deps.errorProneProcessorPath...) 1067 1068 flags.processors = append(flags.processors, deps.processorClasses...) 1069 flags.processors = android.FirstUniqueStrings(flags.processors) 1070 1071 if len(flags.bootClasspath) == 0 && ctx.Host() && !flags.javaVersion.usesJavaModules() && 1072 decodeSdkDep(ctx, android.SdkContext(j)).hasStandardLibs() { 1073 // Give host-side tools a version of OpenJDK's standard libraries 1074 // close to what they're targeting. As of Dec 2017, AOSP is only 1075 // bundling OpenJDK 8 and 9, so nothing < 8 is available. 1076 // 1077 // When building with OpenJDK 8, the following should have no 1078 // effect since those jars would be available by default. 1079 // 1080 // When building with OpenJDK 9 but targeting a version < 1.8, 1081 // putting them on the bootclasspath means that: 1082 // a) code can't (accidentally) refer to OpenJDK 9 specific APIs 1083 // b) references to existing APIs are not reinterpreted in an 1084 // OpenJDK 9-specific way, eg. calls to subclasses of 1085 // java.nio.Buffer as in http://b/70862583 1086 java8Home := ctx.Config().Getenv("ANDROID_JAVA8_HOME") 1087 flags.bootClasspath = append(flags.bootClasspath, 1088 android.PathForSource(ctx, java8Home, "jre/lib/jce.jar"), 1089 android.PathForSource(ctx, java8Home, "jre/lib/rt.jar")) 1090 if Bool(j.properties.Use_tools_jar) { 1091 flags.bootClasspath = append(flags.bootClasspath, 1092 android.PathForSource(ctx, java8Home, "lib/tools.jar")) 1093 } 1094 } 1095 1096 // systemModules 1097 flags.systemModules = deps.systemModules 1098 1099 return flags 1100} 1101 1102func (j *Module) collectJavacFlags( 1103 ctx android.ModuleContext, flags javaBuilderFlags, srcFiles android.Paths) javaBuilderFlags { 1104 // javac flags. 1105 javacFlags := j.properties.Javacflags 1106 var needsDebugInfo bool 1107 1108 needsDebugInfo = false 1109 for _, flag := range javacFlags { 1110 if strings.HasPrefix(flag, "-g") { 1111 needsDebugInfo = true 1112 } 1113 } 1114 1115 if ctx.Config().MinimizeJavaDebugInfo() && !ctx.Host() && !needsDebugInfo { 1116 // For non-host binaries, override the -g flag passed globally to remove 1117 // local variable debug info to reduce disk and memory usage. 1118 javacFlags = append(javacFlags, "-g:source,lines") 1119 } 1120 javacFlags = append(javacFlags, "-Xlint:-dep-ann") 1121 1122 if flags.javaVersion.usesJavaModules() { 1123 javacFlags = append(javacFlags, j.properties.Openjdk9.Javacflags...) 1124 } else if len(j.properties.Openjdk9.Javacflags) > 0 { 1125 // java version defaults higher than openjdk 9, these conditionals should no longer be necessary 1126 ctx.PropertyErrorf("openjdk9.javacflags", "JDK version defaults to higher than 9") 1127 } 1128 1129 if flags.javaVersion.usesJavaModules() { 1130 if j.properties.Patch_module != nil { 1131 // Manually specify build directory in case it is not under the repo root. 1132 // (javac doesn't seem to expand into symbolic links when searching for patch-module targets, so 1133 // just adding a symlink under the root doesn't help.) 1134 patchPaths := []string{".", ctx.Config().SoongOutDir()} 1135 1136 classPath := flags.classpath.FormJavaClassPath("") 1137 if classPath != "" { 1138 patchPaths = append(patchPaths, classPath) 1139 } 1140 javacFlags = append( 1141 javacFlags, 1142 "--patch-module="+String(j.properties.Patch_module)+"="+strings.Join(patchPaths, ":")) 1143 } 1144 } 1145 1146 if len(javacFlags) > 0 { 1147 // optimization. 1148 ctx.Variable(pctx, "javacFlags", strings.Join(javacFlags, " ")) 1149 flags.javacFlags = "$javacFlags" 1150 } 1151 1152 return flags 1153} 1154 1155func (j *Module) AddJSONData(d *map[string]interface{}) { 1156 (&j.ModuleBase).AddJSONData(d) 1157 (*d)["Java"] = map[string]interface{}{ 1158 "SourceExtensions": j.sourceExtensions, 1159 } 1160 1161} 1162 1163func (j *Module) addGeneratedSrcJars(path android.Path) { 1164 j.properties.Generated_srcjars = append(j.properties.Generated_srcjars, path) 1165} 1166 1167func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspathJars, extraCombinedJars, extraDepCombinedJars android.Paths) *JavaInfo { 1168 // Auto-propagating jarjar rules 1169 jarjarProviderData := j.collectJarJarRules(ctx) 1170 if jarjarProviderData != nil { 1171 android.SetProvider(ctx, JarJarProvider, *jarjarProviderData) 1172 text := getJarJarRuleText(jarjarProviderData) 1173 if text != "" { 1174 ruleTextFile := android.PathForModuleOut(ctx, "repackaged-jarjar", "repackaging.txt") 1175 android.WriteFileRule(ctx, ruleTextFile, text) 1176 j.repackageJarjarRules = ruleTextFile 1177 } 1178 } 1179 1180 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.deviceProperties.Aidl.Export_include_dirs) 1181 1182 // Only override the original value if explicitly set 1183 if j.properties.Ravenizer.Enabled != nil { 1184 j.ravenizer.enabled = *j.properties.Ravenizer.Enabled 1185 } 1186 1187 deps := j.collectDeps(ctx) 1188 flags := j.collectBuilderFlags(ctx, deps) 1189 1190 if flags.javaVersion.usesJavaModules() { 1191 j.properties.Srcs = append(j.properties.Srcs, j.properties.Openjdk9.Srcs...) 1192 } else if len(j.properties.Openjdk9.Javacflags) > 0 { 1193 // java version defaults higher than openjdk 9, these conditionals should no longer be necessary 1194 ctx.PropertyErrorf("openjdk9.srcs", "JDK version defaults to higher than 9") 1195 } 1196 1197 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) 1198 j.sourceExtensions = []string{} 1199 for _, ext := range []string{".kt", ".proto", ".aidl", ".java", ".logtags"} { 1200 if hasSrcExt(srcFiles.Strings(), ext) { 1201 j.sourceExtensions = append(j.sourceExtensions, ext) 1202 } 1203 } 1204 if hasSrcExt(srcFiles.Strings(), ".proto") { 1205 flags = protoFlags(ctx, &j.properties, &j.protoProperties, flags) 1206 } 1207 1208 kotlinCommonSrcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Common_srcs, j.properties.Exclude_common_srcs) 1209 if len(kotlinCommonSrcFiles.FilterOutByExt(".kt")) > 0 { 1210 ctx.PropertyErrorf("common_srcs", "common_srcs must be .kt files") 1211 } 1212 1213 aidlSrcs := srcFiles.FilterByExt(".aidl") 1214 flags.aidlFlags, flags.aidlDeps = j.aidlFlags(ctx, deps.aidlPreprocess, deps.aidlIncludeDirs, aidlSrcs) 1215 1216 nonGeneratedSrcJars := srcFiles.FilterByExt(".srcjar") 1217 srcFiles = j.genSources(ctx, srcFiles, flags) 1218 1219 // Collect javac flags only after computing the full set of srcFiles to 1220 // ensure that the --patch-module lookup paths are complete. 1221 flags = j.collectJavacFlags(ctx, flags, srcFiles) 1222 1223 srcJars := srcFiles.FilterByExt(".srcjar") 1224 srcJars = append(srcJars, deps.srcJars...) 1225 srcJars = append(srcJars, extraSrcJars...) 1226 srcJars = append(srcJars, j.properties.Generated_srcjars...) 1227 srcFiles = srcFiles.FilterOutByExt(".srcjar") 1228 1229 if j.properties.Jarjar_rules != nil { 1230 j.expandJarjarRules = android.PathForModuleSrc(ctx, *j.properties.Jarjar_rules) 1231 } 1232 1233 jarName := j.Stem() + ".jar" 1234 1235 var uniqueJavaFiles android.Paths 1236 set := make(map[string]bool) 1237 for _, v := range srcFiles.FilterByExt(".java") { 1238 if _, found := set[v.String()]; !found { 1239 set[v.String()] = true 1240 uniqueJavaFiles = append(uniqueJavaFiles, v) 1241 } 1242 } 1243 var uniqueKtFiles android.Paths 1244 for _, v := range srcFiles.FilterByExt(".kt") { 1245 if _, found := set[v.String()]; !found { 1246 set[v.String()] = true 1247 uniqueKtFiles = append(uniqueKtFiles, v) 1248 } 1249 } 1250 1251 var uniqueSrcFiles android.Paths 1252 uniqueSrcFiles = append(uniqueSrcFiles, uniqueJavaFiles...) 1253 uniqueSrcFiles = append(uniqueSrcFiles, uniqueKtFiles...) 1254 j.uniqueSrcFiles = uniqueSrcFiles 1255 1256 // We don't currently run annotation processors in turbine, which means we can't use turbine 1257 // generated header jars when an annotation processor that generates API is enabled. One 1258 // exception (handled further below) is when kotlin sources are enabled, in which case turbine 1259 // is used to run all of the annotation processors. 1260 disableTurbine := deps.disableTurbine 1261 1262 // Collect .java and .kt files for AIDEGen 1263 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...) 1264 1265 var kotlinHeaderJars android.Paths 1266 1267 // Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before 1268 // any dependencies so that it can override any non-final R classes from dependencies with the 1269 // final R classes from the app. 1270 flags.classpath = append(android.CopyOf(extraClasspathJars), flags.classpath...) 1271 1272 j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...) 1273 1274 var localImplementationJars android.Paths 1275 1276 // If compiling headers then compile them and skip the rest 1277 if proptools.Bool(j.properties.Headers_only) { 1278 if srcFiles.HasExt(".kt") { 1279 ctx.ModuleErrorf("Compiling headers_only with .kt not supported") 1280 } 1281 if ctx.Config().IsEnvFalse("TURBINE_ENABLED") || disableTurbine { 1282 ctx.ModuleErrorf("headers_only is enabled but Turbine is disabled.") 1283 } 1284 1285 transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars 1286 1287 localHeaderJars, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, 1288 extraCombinedJars) 1289 1290 combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false) 1291 if jarjared { 1292 localHeaderJars = android.Paths{combinedHeaderJarFile} 1293 transitiveStaticLibsHeaderJars = nil 1294 } 1295 combinedHeaderJarFile, repackaged := j.repackageFlagsIfNecessary(ctx, combinedHeaderJarFile, jarName, "repackage-turbine") 1296 if repackaged { 1297 localHeaderJars = android.Paths{combinedHeaderJarFile} 1298 transitiveStaticLibsHeaderJars = nil 1299 } 1300 if ctx.Failed() { 1301 return nil 1302 } 1303 j.headerJarFile = combinedHeaderJarFile 1304 1305 if len(localHeaderJars) > 0 { 1306 ctx.CheckbuildFile(localHeaderJars...) 1307 } else { 1308 // There are no local sources or resources in this module, so there is nothing to checkbuild. 1309 ctx.UncheckedModule() 1310 } 1311 1312 j.outputFile = j.headerJarFile 1313 return &JavaInfo{ 1314 HeaderJars: android.PathsIfNonNil(j.headerJarFile), 1315 LocalHeaderJars: localHeaderJars, 1316 TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars), 1317 TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8, 1318 TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8, 1319 AidlIncludeDirs: j.exportAidlIncludeDirs, 1320 ExportedPlugins: j.exportedPluginJars, 1321 ExportedPluginClasses: j.exportedPluginClasses, 1322 ExportedPluginDisableTurbine: j.exportedDisableTurbine, 1323 StubsLinkType: j.stubsLinkType, 1324 AconfigIntermediateCacheOutputPaths: deps.aconfigProtoFiles, 1325 SdkVersion: j.SdkVersion(ctx), 1326 } 1327 } 1328 1329 if srcFiles.HasExt(".kt") { 1330 // When using kotlin sources turbine is used to generate annotation processor sources, 1331 // including for annotation processors that generate API, so we can use turbine for 1332 // java sources too. 1333 disableTurbine = false 1334 1335 // user defined kotlin flags. 1336 kotlincFlags := j.properties.Kotlincflags 1337 CheckKotlincFlags(ctx, kotlincFlags) 1338 1339 // Available kotlin versions can be found at 1340 // https://github.com/JetBrains/kotlin/blob/master/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt#L560 1341 // in the `LanguageVersion` class. 1342 // For now, avoid targeting language versions directly, as we'd like to kee our source 1343 // code version aligned as much as possible. Ideally, after defaulting to "2", we 1344 // can remove the "1.9" option entirely, or at least make it emit a warning. 1345 kotlin_default_lang_version := "1.9" 1346 if build_flag_lang_version, ok := ctx.Config().GetBuildFlag("RELEASE_KOTLIN_LANG_VERSION"); ok { 1347 kotlin_default_lang_version = build_flag_lang_version 1348 } 1349 kotlin_lang_version := proptools.StringDefault(j.properties.Kotlin_lang_version, kotlin_default_lang_version) 1350 switch kotlin_lang_version { 1351 case "1.9": 1352 kotlincFlags = append(kotlincFlags, "-language-version 1.9") 1353 case "2": 1354 kotlincFlags = append(kotlincFlags, "-Xsuppress-version-warnings", "-Xconsistent-data-class-copy-visibility") 1355 default: 1356 ctx.PropertyErrorf("kotlin_lang_version", "Must be one of `1.9` or `2`") 1357 } 1358 1359 // Workaround for KT-46512 1360 kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class") 1361 1362 // If there are kotlin files, compile them first but pass all the kotlin and java files 1363 // kotlinc will use the java files to resolve types referenced by the kotlin files, but 1364 // won't emit any classes for them. 1365 kotlincFlags = append(kotlincFlags, "-no-stdlib") 1366 if ctx.Device() { 1367 kotlincFlags = append(kotlincFlags, "-no-jdk") 1368 } 1369 1370 for _, plugin := range deps.kotlinPlugins { 1371 kotlincFlags = append(kotlincFlags, "-Xplugin="+plugin.String()) 1372 } 1373 flags.kotlincDeps = append(flags.kotlincDeps, deps.kotlinPlugins...) 1374 1375 if len(kotlincFlags) > 0 { 1376 // optimization. 1377 ctx.Variable(pctx, "kotlincFlags", strings.Join(kotlincFlags, " ")) 1378 flags.kotlincFlags += "$kotlincFlags" 1379 } 1380 1381 // Collect common .kt files for AIDEGen 1382 j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, kotlinCommonSrcFiles.Strings()...) 1383 1384 flags.kotlincClasspath = append(flags.kotlincClasspath, flags.bootClasspath...) 1385 flags.kotlincClasspath = append(flags.kotlincClasspath, flags.classpath...) 1386 1387 if len(flags.processorPath) > 0 { 1388 // Use kapt for annotation processing 1389 kaptSrcJar := android.PathForModuleOut(ctx, "kapt", "kapt-sources.jar") 1390 kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar") 1391 kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) 1392 srcJars = append(srcJars, kaptSrcJar) 1393 localImplementationJars = append(localImplementationJars, kaptResJar) 1394 // Disable annotation processing in javac, it's already been handled by kapt 1395 flags.processorPath = nil 1396 flags.processors = nil 1397 } 1398 1399 kotlinJar := android.PathForModuleOut(ctx, "kotlin", jarName) 1400 kotlinHeaderJar := android.PathForModuleOut(ctx, "kotlin_headers", jarName) 1401 j.kotlinCompile(ctx, kotlinJar, kotlinHeaderJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) 1402 if ctx.Failed() { 1403 return nil 1404 } 1405 1406 kotlinJarPath, _ := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc") 1407 1408 // Make javac rule depend on the kotlinc rule 1409 flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...) 1410 1411 localImplementationJars = append(localImplementationJars, kotlinJarPath) 1412 1413 kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar) 1414 } 1415 1416 j.compiledSrcJars = srcJars 1417 1418 transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars 1419 1420 enableSharding := false 1421 var localHeaderJars android.Paths 1422 var shardingHeaderJars android.Paths 1423 var repackagedHeaderJarFile android.Path 1424 if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine { 1425 if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 { 1426 enableSharding = true 1427 // Formerly, there was a check here that prevented annotation processors 1428 // from being used when sharding was enabled, as some annotation processors 1429 // do not function correctly in sharded environments. It was removed to 1430 // allow for the use of annotation processors that do function correctly 1431 // with sharding enabled. See: b/77284273. 1432 } 1433 extraJars := slices.Clone(kotlinHeaderJars) 1434 extraJars = append(extraJars, extraCombinedJars...) 1435 var combinedHeaderJarFile android.Path 1436 localHeaderJars, combinedHeaderJarFile = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars) 1437 shardingHeaderJars = localHeaderJars 1438 1439 var jarjared bool 1440 j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine", false) 1441 if jarjared { 1442 // jarjar modifies transitive static dependencies, use the combined header jar and drop the transitive 1443 // static libs header jars. 1444 localHeaderJars = android.Paths{j.headerJarFile} 1445 transitiveStaticLibsHeaderJars = nil 1446 } 1447 var repackaged bool 1448 repackagedHeaderJarFile, repackaged = j.repackageFlagsIfNecessary(ctx, j.headerJarFile, jarName, "turbine") 1449 if repackaged { 1450 // repackage modifies transitive static dependencies, use the combined header jar and drop the transitive 1451 // static libs header jars. 1452 // TODO(b/356688296): this shouldn't export both the unmodified and repackaged header jars 1453 localHeaderJars = android.Paths{j.headerJarFile, repackagedHeaderJarFile} 1454 transitiveStaticLibsHeaderJars = nil 1455 } 1456 } 1457 if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 { 1458 hasErrorproneableFiles := false 1459 for _, ext := range j.sourceExtensions { 1460 if ext != ".proto" && ext != ".aidl" { 1461 // Skip running errorprone on pure proto or pure aidl modules. Some modules take a long time to 1462 // compile, and it's not useful to have warnings on these generated sources. 1463 hasErrorproneableFiles = true 1464 break 1465 } 1466 } 1467 var extraJarDeps android.Paths 1468 if Bool(j.properties.Errorprone.Enabled) { 1469 // If error-prone is enabled, enable errorprone flags on the regular 1470 // build. 1471 flags = enableErrorproneFlags(flags) 1472 } else if hasErrorproneableFiles && ctx.Config().RunErrorProne() && j.properties.Errorprone.Enabled == nil { 1473 if ctx.Config().RunErrorProneInline() { 1474 // On CI, we're not going to toggle back/forth between errorprone and non-errorprone 1475 // builds, so it's faster if we don't compile the module twice and instead always 1476 // compile the module with errorprone. 1477 flags = enableErrorproneFlags(flags) 1478 } else { 1479 // Otherwise, if the RUN_ERROR_PRONE environment variable is set, create 1480 // a new jar file just for compiling with the errorprone compiler to. 1481 // This is because we don't want to cause the java files to get completely 1482 // rebuilt every time the state of the RUN_ERROR_PRONE variable changes. 1483 // We also don't want to run this if errorprone is enabled by default for 1484 // this module, or else we could have duplicated errorprone messages. 1485 errorproneFlags := enableErrorproneFlags(flags) 1486 errorprone := android.PathForModuleOut(ctx, "errorprone", jarName) 1487 errorproneAnnoSrcJar := android.PathForModuleOut(ctx, "errorprone", "anno.srcjar") 1488 1489 transformJavaToClasses(ctx, errorprone, -1, uniqueJavaFiles, srcJars, errorproneAnnoSrcJar, errorproneFlags, nil, 1490 "errorprone", "errorprone") 1491 1492 extraJarDeps = append(extraJarDeps, errorprone) 1493 } 1494 } 1495 1496 if enableSharding { 1497 if len(shardingHeaderJars) > 0 { 1498 flags.classpath = append(classpath(slices.Clone(shardingHeaderJars)), flags.classpath...) 1499 } 1500 shardSize := int(*(j.properties.Javac_shard_size)) 1501 var shardSrcs []android.Paths 1502 if len(uniqueJavaFiles) > 0 { 1503 shardSrcs = android.ShardPaths(uniqueJavaFiles, shardSize) 1504 for idx, shardSrc := range shardSrcs { 1505 classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc, 1506 nil, flags, extraJarDeps) 1507 classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx)) 1508 localImplementationJars = append(localImplementationJars, classes) 1509 } 1510 } 1511 // Assume approximately 5 sources per srcjar. 1512 // For framework-minus-apex in AOSP at the time this was written, there are 266 srcjars, with a mean 1513 // of 5.8 sources per srcjar, but a median of 1, a standard deviation of 10, and a max of 48 source files. 1514 if len(srcJars) > 0 { 1515 startIdx := len(shardSrcs) 1516 shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5) 1517 for idx, shardSrcJars := range shardSrcJarsList { 1518 classes := j.compileJavaClasses(ctx, jarName, startIdx+idx, 1519 nil, shardSrcJars, flags, extraJarDeps) 1520 classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx)) 1521 localImplementationJars = append(localImplementationJars, classes) 1522 } 1523 } 1524 } else { 1525 classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps) 1526 classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac") 1527 localImplementationJars = append(localImplementationJars, classes) 1528 } 1529 if ctx.Failed() { 1530 return nil 1531 } 1532 } 1533 1534 localImplementationJars = append(localImplementationJars, extraCombinedJars...) 1535 1536 j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles 1537 1538 var includeSrcJar android.WritablePath 1539 if Bool(j.properties.Include_srcs) { 1540 includeSrcJar = android.PathForModuleOut(ctx, ctx.ModuleName()+".srcjar") 1541 TransformResourcesToJar(ctx, includeSrcJar, j.srcJarArgs, j.srcJarDeps) 1542 } 1543 1544 dirArgs, dirDeps := ResourceDirsToJarArgs(ctx, j.properties.Java_resource_dirs, 1545 j.properties.Exclude_java_resource_dirs, j.properties.Exclude_java_resources) 1546 fileArgs, fileDeps := ResourceFilesToJarArgs(ctx, j.properties.Java_resources.GetOrDefault(ctx, nil), j.properties.Exclude_java_resources) 1547 fileArgs2, fileDeps2 := ResourceFilesToJarArgs(ctx, j.properties.Device_common_java_resources.GetOrDefault(ctx, nil), nil) 1548 fileArgs3, fileDeps3 := ResourceFilesToJarArgs(ctx, j.properties.Device_first_java_resources.GetOrDefault(ctx, nil), nil) 1549 fileArgs = slices.Concat(fileArgs, fileArgs2, fileArgs3) 1550 fileDeps = slices.Concat(fileDeps, fileDeps2, fileDeps3) 1551 extraArgs, extraDeps := resourcePathsToJarArgs(j.extraResources), j.extraResources 1552 1553 var resArgs []string 1554 var resDeps android.Paths 1555 1556 resArgs = append(resArgs, dirArgs...) 1557 resDeps = append(resDeps, dirDeps...) 1558 1559 resArgs = append(resArgs, fileArgs...) 1560 resDeps = append(resDeps, fileDeps...) 1561 1562 resArgs = append(resArgs, extraArgs...) 1563 resDeps = append(resDeps, extraDeps...) 1564 1565 var localResourceJars android.Paths 1566 if len(resArgs) > 0 { 1567 resourceJar := android.PathForModuleOut(ctx, "res", jarName) 1568 TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps) 1569 if ctx.Failed() { 1570 return nil 1571 } 1572 localResourceJars = append(localResourceJars, resourceJar) 1573 } 1574 1575 if Bool(j.properties.Include_srcs) { 1576 localResourceJars = append(localResourceJars, includeSrcJar) 1577 } 1578 1579 services := android.PathsForModuleSrc(ctx, j.properties.Services) 1580 if len(services) > 0 { 1581 servicesJar := android.PathForModuleOut(ctx, "services", jarName) 1582 var zipargs []string 1583 for _, file := range services { 1584 serviceFile := file.String() 1585 zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile) 1586 } 1587 rule := zip 1588 args := map[string]string{ 1589 "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "), 1590 } 1591 if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_ZIP") { 1592 rule = zipRE 1593 args["implicits"] = strings.Join(services.Strings(), ",") 1594 } 1595 ctx.Build(pctx, android.BuildParams{ 1596 Rule: rule, 1597 Output: servicesJar, 1598 Implicits: services, 1599 Args: args, 1600 }) 1601 localResourceJars = append(localResourceJars, servicesJar) 1602 } 1603 1604 completeStaticLibsResourceJars := depset.New(depset.PREORDER, localResourceJars, deps.transitiveStaticLibsResourceJars) 1605 1606 var combinedResourceJar android.Path 1607 resourceJars := completeStaticLibsResourceJars.ToList() 1608 if len(resourceJars) == 1 { 1609 combinedResourceJar = resourceJars[0] 1610 } else if len(resourceJars) > 0 { 1611 combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName) 1612 TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{}, 1613 false, nil, nil) 1614 combinedResourceJar = combinedJar 1615 } 1616 1617 manifest := j.overrideManifest 1618 if !manifest.Valid() && j.properties.Manifest != nil { 1619 manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest)) 1620 } 1621 1622 // Combine the classes built from sources, any manifests, and any static libraries into 1623 // classes.jar. If there is only one input jar this step will be skipped. 1624 var outputFile android.Path 1625 1626 completeStaticLibsImplementationJars := depset.New(depset.PREORDER, localImplementationJars, deps.transitiveStaticLibsImplementationJars) 1627 1628 jars := completeStaticLibsImplementationJars.ToList() 1629 1630 jars = append(jars, extraDepCombinedJars...) 1631 1632 if len(jars) == 1 && !manifest.Valid() { 1633 // Optimization: skip the combine step as there is nothing to do 1634 // TODO(ccross): this leaves any module-info.class files, but those should only come from 1635 // prebuilt dependencies until we support modules in the platform build, so there shouldn't be 1636 // any if len(extraJars) == 0. 1637 1638 // moduleStubLinkType determines if the module is the TopLevelStubLibrary generated 1639 // from sdk_library. The TopLevelStubLibrary contains only one static lib, 1640 // either with .from-source or .from-text suffix. 1641 // outputFile should be agnostic to the build configuration, 1642 // thus copy the single input static lib in order to prevent the static lib from being exposed 1643 // to the copy rules. 1644 if stub, _ := moduleStubLinkType(j); stub { 1645 copiedJar := android.PathForModuleOut(ctx, "combined", jarName) 1646 ctx.Build(pctx, android.BuildParams{ 1647 Rule: android.Cp, 1648 Input: jars[0], 1649 Output: copiedJar, 1650 }) 1651 completeStaticLibsImplementationJars = depset.New(depset.PREORDER, android.Paths{copiedJar}, nil) 1652 outputFile = copiedJar 1653 } else { 1654 outputFile = jars[0] 1655 } 1656 } else { 1657 combinedJar := android.PathForModuleOut(ctx, "combined", jarName) 1658 TransformJarsToJar(ctx, combinedJar, "for javac", jars, manifest, 1659 false, nil, nil) 1660 outputFile = combinedJar 1661 } 1662 1663 // jarjar implementation jar if necessary 1664 jarjarFile, jarjarred := j.jarjarIfNecessary(ctx, outputFile, jarName, "", true) 1665 if jarjarred { 1666 localImplementationJars = android.Paths{jarjarFile} 1667 completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil) 1668 } 1669 outputFile = jarjarFile 1670 1671 // jarjar resource jar if necessary 1672 if combinedResourceJar != nil { 1673 resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource", false) 1674 combinedResourceJar = resourceJarJarFile 1675 if jarjarred { 1676 localResourceJars = android.Paths{resourceJarJarFile} 1677 completeStaticLibsResourceJars = depset.New(depset.PREORDER, localResourceJars, nil) 1678 } 1679 } 1680 1681 if ctx.Failed() { 1682 return nil 1683 } 1684 1685 if j.ravenizer.enabled { 1686 ravenizerInput := outputFile 1687 ravenizerOutput := android.PathForModuleOut(ctx, "ravenizer", "", jarName) 1688 ravenizerArgs := "" 1689 if proptools.Bool(j.properties.Ravenizer.Strip_mockito) { 1690 ravenizerArgs = "--strip-mockito" 1691 } 1692 TransformRavenizer(ctx, ravenizerOutput, ravenizerInput, ravenizerArgs) 1693 outputFile = ravenizerOutput 1694 localImplementationJars = android.Paths{ravenizerOutput} 1695 completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil) 1696 if combinedResourceJar != nil { 1697 ravenizerInput = combinedResourceJar 1698 ravenizerOutput = android.PathForModuleOut(ctx, "ravenizer", "resources", jarName) 1699 TransformRavenizer(ctx, ravenizerOutput, ravenizerInput, ravenizerArgs) 1700 combinedResourceJar = ravenizerOutput 1701 localResourceJars = android.Paths{ravenizerOutput} 1702 completeStaticLibsResourceJars = depset.New(depset.PREORDER, localResourceJars, nil) 1703 } 1704 } 1705 1706 if j.shouldApiMapper() { 1707 inputFile := outputFile 1708 apiMapperFile := android.PathForModuleOut(ctx, "apimapper", jarName) 1709 ctx.Build(pctx, android.BuildParams{ 1710 Rule: apimapper, 1711 Description: "apimapper", 1712 Input: inputFile, 1713 Output: apiMapperFile, 1714 }) 1715 outputFile = apiMapperFile 1716 localImplementationJars = android.Paths{apiMapperFile} 1717 completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil) 1718 } 1719 1720 // Check package restrictions if necessary. 1721 if len(j.properties.Permitted_packages) > 0 { 1722 // Time stamp file created by the package check rule. 1723 pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp") 1724 1725 // Create a rule to copy the output jar to another path and add a validate dependency that 1726 // will check that the jar only contains the permitted packages. The new location will become 1727 // the output file of this module. 1728 inputFile := outputFile 1729 packageCheckOutputFile := android.PathForModuleOut(ctx, "package-check", jarName) 1730 ctx.Build(pctx, android.BuildParams{ 1731 Rule: android.Cp, 1732 Input: inputFile, 1733 Output: packageCheckOutputFile, 1734 // Make sure that any dependency on the output file will cause ninja to run the package check 1735 // rule. 1736 Validation: pkgckFile, 1737 }) 1738 outputFile = packageCheckOutputFile 1739 localImplementationJars = android.Paths{packageCheckOutputFile} 1740 completeStaticLibsImplementationJars = depset.New(depset.PREORDER, localImplementationJars, nil) 1741 1742 // Check packages and create a timestamp file when complete. 1743 CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages) 1744 1745 if ctx.Failed() { 1746 return nil 1747 } 1748 } 1749 1750 j.implementationJarFile = outputFile 1751 if j.headerJarFile == nil { 1752 // If this module couldn't generate a header jar (for example due to api generating annotation processors) 1753 // then use the implementation jar. Run it through zip2zip first to remove any files in META-INF/services 1754 // so that javac on modules that depend on this module don't pick up annotation processors (which may be 1755 // missing their implementations) from META-INF/services/javax.annotation.processing.Processor. 1756 headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName) 1757 convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile) 1758 j.headerJarFile = headerJarFile 1759 if len(localImplementationJars) == 1 { 1760 localHeaderJarFile := android.PathForModuleOut(ctx, "local-javac-header", jarName) 1761 convertImplementationJarToHeaderJar(ctx, localImplementationJars[0], localHeaderJarFile) 1762 localHeaderJars = append(localHeaderJars, localHeaderJarFile) 1763 } else { 1764 localHeaderJars = append(localHeaderJars, headerJarFile) 1765 } 1766 } 1767 1768 // enforce syntax check to jacoco filters for any build (http://b/183622051) 1769 specs := j.jacocoModuleToZipCommand(ctx) 1770 if ctx.Failed() { 1771 return nil 1772 } 1773 1774 completeStaticLibsImplementationJarsToCombine := completeStaticLibsImplementationJars 1775 1776 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) 1777 1778 // Enable dex compilation for the APEX variants, unless it is disabled explicitly 1779 compileDex := Bool(j.dexProperties.Compile_dex) || Bool(j.properties.Installable) 1780 1781 if j.shouldInstrument(ctx) && (!ctx.Device() || compileDex) { 1782 instrumentedOutputFile := j.instrument(ctx, flags, outputFile, jarName, specs) 1783 completeStaticLibsImplementationJarsToCombine = depset.New(depset.PREORDER, android.Paths{instrumentedOutputFile}, nil) 1784 outputFile = instrumentedOutputFile 1785 } 1786 1787 // merge implementation jar with resources if necessary 1788 var implementationAndResourcesJarsToCombine android.Paths 1789 combinedResourceJars := completeStaticLibsResourceJars.ToList() 1790 if len(combinedResourceJars) > 0 { 1791 implementationAndResourcesJarsToCombine = slices.Concat(combinedResourceJars, 1792 completeStaticLibsImplementationJarsToCombine.ToList(), extraDepCombinedJars) 1793 } 1794 1795 if len(implementationAndResourcesJarsToCombine) > 0 { 1796 combinedJar := android.PathForModuleOut(ctx, "withres", jarName) 1797 TransformJarsToJar(ctx, combinedJar, "for resources", implementationAndResourcesJarsToCombine, manifest, 1798 false, nil, nil) 1799 outputFile = combinedJar 1800 } 1801 1802 j.implementationAndResourcesJar = outputFile 1803 1804 if ctx.Device() && compileDex { 1805 if j.hasCode(ctx) { 1806 if j.shouldInstrumentStatic(ctx) { 1807 j.dexer.extraProguardFlagsFiles = append(j.dexer.extraProguardFlagsFiles, 1808 android.PathForSource(ctx, "build/make/core/proguard.jacoco.flags")) 1809 } 1810 // Dex compilation 1811 var dexOutputFile android.Path 1812 params := &compileDexParams{ 1813 flags: flags, 1814 sdkVersion: j.SdkVersion(ctx), 1815 minSdkVersion: j.MinSdkVersion(ctx), 1816 classesJar: outputFile, 1817 jarName: jarName, 1818 } 1819 if j.GetProfileGuided(ctx) && j.optimizeOrObfuscateEnabled(ctx) && !j.EnableProfileRewriting(ctx) { 1820 ctx.PropertyErrorf("enable_profile_rewriting", 1821 "Enable_profile_rewriting must be true when profile_guided dexpreopt and R8 optimization/obfuscation is turned on. The attached profile should be sourced from an unoptimized/unobfuscated APK.", 1822 ) 1823 } 1824 if j.EnableProfileRewriting(ctx) { 1825 profile := j.GetProfile(ctx) 1826 if profile == "" || !j.GetProfileGuided(ctx) { 1827 ctx.PropertyErrorf("enable_profile_rewriting", "Profile and Profile_guided must be set when enable_profile_rewriting is true") 1828 } 1829 params.artProfileInput = &profile 1830 } 1831 dexOutputFile, dexArtProfileOutput := j.dexer.compileDex(ctx, params) 1832 if ctx.Failed() { 1833 return nil 1834 } 1835 1836 // If r8/d8 provides a profile that matches the optimized dex, use that for dexpreopt. 1837 if dexArtProfileOutput != nil { 1838 j.dexpreopter.SetRewrittenProfile(dexArtProfileOutput) 1839 } 1840 1841 // merge dex jar with resources if necessary 1842 if len(combinedResourceJars) > 0 { 1843 dexAndResourceJarsToCombine := append(android.Paths{dexOutputFile}, combinedResourceJars...) 1844 1845 combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName) 1846 TransformJarsToJar(ctx, combinedJar, "for dex resources", dexAndResourceJarsToCombine, android.OptionalPath{}, 1847 false, nil, nil) 1848 if *j.dexProperties.Uncompress_dex { 1849 combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName) 1850 TransformZipAlign(ctx, combinedAlignedJar, combinedJar, nil) 1851 dexOutputFile = combinedAlignedJar 1852 } else { 1853 dexOutputFile = combinedJar 1854 } 1855 } 1856 1857 // Initialize the hiddenapi structure. 1858 1859 j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), j.implementationJarFile, j.dexProperties.Uncompress_dex) 1860 1861 // Encode hidden API flags in dex file, if needed. 1862 dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) 1863 1864 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 1865 1866 // Dexpreopting 1867 libName := android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()) 1868 if j.SdkLibraryName() != nil && strings.HasSuffix(ctx.ModuleName(), ".impl") { 1869 libName = strings.TrimSuffix(libName, ".impl") 1870 } 1871 j.dexpreopt(ctx, libName, dexOutputFile) 1872 1873 outputFile = dexOutputFile 1874 1875 ctx.CheckbuildFile(dexOutputFile) 1876 } else { 1877 // There is no code to compile into a dex jar, make sure the resources are propagated 1878 // to the APK if this is an app. 1879 j.dexJarFile = makeDexJarPathFromPath(combinedResourceJar) 1880 } 1881 1882 if ctx.Failed() { 1883 return nil 1884 } 1885 } 1886 1887 if ctx.Device() { 1888 lintSDKVersion := func(apiLevel android.ApiLevel) android.ApiLevel { 1889 if !apiLevel.IsPreview() { 1890 return apiLevel 1891 } else { 1892 return ctx.Config().DefaultAppTargetSdk(ctx) 1893 } 1894 } 1895 1896 j.linter.name = ctx.ModuleName() 1897 j.linter.srcs = append(srcFiles, nonGeneratedSrcJars...) 1898 j.linter.srcJars, _ = android.FilterPathList(srcJars, nonGeneratedSrcJars) 1899 j.linter.classpath = append(append(android.Paths(nil), flags.bootClasspath...), flags.classpath...) 1900 j.linter.classes = j.implementationJarFile 1901 j.linter.minSdkVersion = lintSDKVersion(j.MinSdkVersion(ctx)) 1902 j.linter.targetSdkVersion = lintSDKVersion(j.TargetSdkVersion(ctx)) 1903 j.linter.compileSdkVersion = lintSDKVersion(j.SdkVersion(ctx).ApiLevel) 1904 j.linter.compileSdkKind = j.SdkVersion(ctx).Kind 1905 j.linter.javaLanguageLevel = flags.javaVersion.String() 1906 j.linter.kotlinLanguageLevel = "1.3" 1907 j.linter.compile_data = android.PathsForModuleSrc(ctx, j.properties.Compile_data) 1908 if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() { 1909 j.linter.buildModuleReportZip = true 1910 } 1911 j.linter.lint(ctx) 1912 } 1913 1914 j.collectTransitiveSrcFiles(ctx, srcFiles) 1915 1916 if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 { 1917 ctx.CheckbuildFile(localImplementationJars...) 1918 ctx.CheckbuildFile(localResourceJars...) 1919 ctx.CheckbuildFile(localHeaderJars...) 1920 } else { 1921 // There are no local sources or resources in this module, so there is nothing to checkbuild. 1922 ctx.UncheckedModule() 1923 } 1924 1925 // Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource 1926 j.outputFile = outputFile.WithoutRel() 1927 1928 return &JavaInfo{ 1929 HeaderJars: android.PathsIfNonNil(j.headerJarFile), 1930 RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile), 1931 1932 LocalHeaderJars: localHeaderJars, 1933 TransitiveStaticLibsHeaderJars: depset.New(depset.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars), 1934 TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars, 1935 TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars, 1936 1937 TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8, 1938 TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8, 1939 ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar), 1940 ImplementationJars: android.PathsIfNonNil(j.implementationJarFile), 1941 ResourceJars: android.PathsIfNonNil(combinedResourceJar), 1942 AidlIncludeDirs: j.exportAidlIncludeDirs, 1943 SrcJarArgs: j.srcJarArgs, 1944 SrcJarDeps: j.srcJarDeps, 1945 TransitiveSrcFiles: j.transitiveSrcFiles, 1946 ExportedPlugins: j.exportedPluginJars, 1947 ExportedPluginClasses: j.exportedPluginClasses, 1948 ExportedPluginDisableTurbine: j.exportedDisableTurbine, 1949 JacocoReportClassesFile: j.jacocoReportClassesFile, 1950 StubsLinkType: j.stubsLinkType, 1951 AconfigIntermediateCacheOutputPaths: j.aconfigCacheFiles, 1952 SdkVersion: j.SdkVersion(ctx), 1953 OutputFile: j.outputFile, 1954 } 1955} 1956 1957func (j *Module) useCompose(ctx android.BaseModuleContext) bool { 1958 return android.InList("androidx.compose.runtime_runtime", j.staticLibs(ctx)) 1959} 1960 1961func collectDepProguardSpecInfo(ctx android.ModuleContext) (transitiveProguardFlags, transitiveUnconditionalExportedFlags []depset.DepSet[android.Path]) { 1962 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { 1963 depProguardInfo, _ := android.OtherModuleProvider(ctx, m, ProguardSpecInfoProvider) 1964 depTag := ctx.OtherModuleDependencyTag(m) 1965 1966 transitiveUnconditionalExportedFlags = append(transitiveUnconditionalExportedFlags, depProguardInfo.UnconditionallyExportedProguardFlags) 1967 transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.UnconditionallyExportedProguardFlags) 1968 1969 if depTag == staticLibTag { 1970 transitiveProguardFlags = append(transitiveProguardFlags, depProguardInfo.ProguardFlagsFiles) 1971 } 1972 }) 1973 1974 return transitiveProguardFlags, transitiveUnconditionalExportedFlags 1975} 1976 1977func (j *Module) collectProguardSpecInfo(ctx android.ModuleContext) ProguardSpecInfo { 1978 transitiveProguardFlags, transitiveUnconditionalExportedFlags := collectDepProguardSpecInfo(ctx) 1979 1980 directUnconditionalExportedFlags := android.Paths{} 1981 proguardFlagsForThisModule := android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files) 1982 exportUnconditionally := proptools.Bool(j.dexProperties.Optimize.Export_proguard_flags_files) 1983 if exportUnconditionally { 1984 // if we explicitly export, then our unconditional exports are the same as our transitive flags 1985 transitiveUnconditionalExportedFlags = transitiveProguardFlags 1986 directUnconditionalExportedFlags = proguardFlagsForThisModule 1987 } 1988 1989 return ProguardSpecInfo{ 1990 Export_proguard_flags_files: exportUnconditionally, 1991 ProguardFlagsFiles: depset.New[android.Path]( 1992 depset.POSTORDER, 1993 proguardFlagsForThisModule, 1994 transitiveProguardFlags, 1995 ), 1996 UnconditionallyExportedProguardFlags: depset.New[android.Path]( 1997 depset.POSTORDER, 1998 directUnconditionalExportedFlags, 1999 transitiveUnconditionalExportedFlags, 2000 ), 2001 } 2002 2003} 2004 2005// Returns a copy of the supplied flags, but with all the errorprone-related 2006// fields copied to the regular build's fields. 2007func enableErrorproneFlags(flags javaBuilderFlags) javaBuilderFlags { 2008 flags.processorPath = append(flags.errorProneProcessorPath, flags.processorPath...) 2009 2010 if len(flags.errorProneExtraJavacFlags) > 0 { 2011 if len(flags.javacFlags) > 0 { 2012 flags.javacFlags += " " + flags.errorProneExtraJavacFlags 2013 } else { 2014 flags.javacFlags = flags.errorProneExtraJavacFlags 2015 } 2016 } 2017 return flags 2018} 2019 2020func (j *Module) compileJavaClasses(ctx android.ModuleContext, jarName string, idx int, 2021 srcFiles, srcJars android.Paths, flags javaBuilderFlags, extraJarDeps android.Paths) android.Path { 2022 2023 kzipName := pathtools.ReplaceExtension(jarName, "kzip") 2024 annoSrcJar := android.PathForModuleOut(ctx, "javac", "anno.srcjar") 2025 if idx >= 0 { 2026 kzipName = strings.TrimSuffix(jarName, filepath.Ext(jarName)) + strconv.Itoa(idx) + ".kzip" 2027 annoSrcJar = android.PathForModuleOut(ctx, "javac", "anno-"+strconv.Itoa(idx)+".srcjar") 2028 jarName += strconv.Itoa(idx) 2029 } 2030 2031 classes := android.PathForModuleOut(ctx, "javac", jarName) 2032 TransformJavaToClasses(ctx, classes, idx, srcFiles, srcJars, annoSrcJar, flags, extraJarDeps) 2033 2034 if ctx.Config().EmitXrefRules() && ctx.Module() == ctx.PrimaryModule() { 2035 extractionFile := android.PathForModuleOut(ctx, kzipName) 2036 emitXrefRule(ctx, extractionFile, idx, srcFiles, srcJars, flags, extraJarDeps) 2037 j.kytheFiles = append(j.kytheFiles, extractionFile) 2038 } 2039 2040 if len(flags.processorPath) > 0 { 2041 j.annoSrcJars = append(j.annoSrcJars, annoSrcJar) 2042 } 2043 2044 return classes 2045} 2046 2047// Check for invalid kotlinc flags. Only use this for flags explicitly passed by the user, 2048// since some of these flags may be used internally. 2049func CheckKotlincFlags(ctx android.ModuleContext, flags []string) { 2050 for _, flag := range flags { 2051 flag = strings.TrimSpace(flag) 2052 2053 if !strings.HasPrefix(flag, "-") { 2054 ctx.PropertyErrorf("kotlincflags", "Flag `%s` must start with `-`", flag) 2055 } else if strings.HasPrefix(flag, "-Xintellij-plugin-root") { 2056 ctx.PropertyErrorf("kotlincflags", 2057 "Bad flag: `%s`, only use internal compiler for consistency.", flag) 2058 } else if slices.ContainsFunc(config.KotlincIllegalFlags, func(f string) bool { 2059 return strings.HasPrefix(flag, f) 2060 }) { 2061 ctx.PropertyErrorf("kotlincflags", "Flag `%s` already used by build system", flag) 2062 } else if flag == "-include-runtime" { 2063 ctx.PropertyErrorf("kotlincflags", "Bad flag: `%s`, do not include runtime.", flag) 2064 } else { 2065 args := strings.Split(flag, " ") 2066 if args[0] == "-kotlin-home" { 2067 ctx.PropertyErrorf("kotlincflags", 2068 "Bad flag: `%s`, kotlin home already set to default (path to kotlinc in the repo).", flag) 2069 } 2070 } 2071 } 2072} 2073 2074func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths, 2075 deps deps, flags javaBuilderFlags, jarName string, 2076 extraJars android.Paths) (localHeaderJars android.Paths, combinedHeaderJar android.Path) { 2077 2078 if len(srcFiles) > 0 || len(srcJars) > 0 { 2079 // Compile java sources into turbine.jar. 2080 turbineJar := android.PathForModuleOut(ctx, "turbine", jarName) 2081 TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags) 2082 localHeaderJars = append(localHeaderJars, turbineJar) 2083 } 2084 2085 localHeaderJars = append(localHeaderJars, extraJars...) 2086 2087 // Combine any static header libraries into classes-header.jar. If there is only 2088 // one input jar this step will be skipped. 2089 depSet := depset.New(depset.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars) 2090 jars := depSet.ToList() 2091 2092 // we cannot skip the combine step for now if there is only one jar 2093 // since we have to strip META-INF/TRANSITIVE dir from turbine.jar 2094 combinedHeaderJarOutputPath := android.PathForModuleOut(ctx, "turbine-combined", jarName) 2095 TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{}, 2096 false, nil, []string{"META-INF/TRANSITIVE"}) 2097 2098 return localHeaderJars, combinedHeaderJarOutputPath 2099} 2100 2101func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags, 2102 classesJar android.Path, jarName string, specs string) android.Path { 2103 2104 jacocoReportClassesFile := android.PathForModuleOut(ctx, "jacoco-report-classes", jarName) 2105 instrumentedJar := android.PathForModuleOut(ctx, "jacoco", jarName) 2106 2107 jacocoInstrumentJar(ctx, instrumentedJar, jacocoReportClassesFile, classesJar, specs) 2108 2109 j.jacocoReportClassesFile = jacocoReportClassesFile 2110 2111 return instrumentedJar 2112} 2113 2114type providesTransitiveHeaderJarsForR8 struct { 2115 // set of header jars for all transitive libs deps 2116 transitiveLibsHeaderJarsForR8 depset.DepSet[android.Path] 2117 // set of header jars for all transitive static libs deps 2118 transitiveStaticLibsHeaderJarsForR8 depset.DepSet[android.Path] 2119} 2120 2121// collectTransitiveHeaderJarsForR8 visits direct dependencies and collects all transitive libs and static_libs 2122// header jars. The semantics of the collected jars are odd (it collects combined jars that contain the static 2123// libs, but also the static libs, and it collects transitive libs dependencies of static_libs), so these 2124// are only used to expand the --lib arguments to R8. 2125func (j *providesTransitiveHeaderJarsForR8) collectTransitiveHeaderJarsForR8(ctx android.ModuleContext) { 2126 directLibs := android.Paths{} 2127 directStaticLibs := android.Paths{} 2128 transitiveLibs := []depset.DepSet[android.Path]{} 2129 transitiveStaticLibs := []depset.DepSet[android.Path]{} 2130 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { 2131 // don't add deps of the prebuilt version of the same library 2132 if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) { 2133 return 2134 } 2135 2136 if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { 2137 tag := ctx.OtherModuleDependencyTag(module) 2138 _, isUsesLibDep := tag.(usesLibraryDependencyTag) 2139 if tag == libTag || tag == r8LibraryJarTag || isUsesLibDep { 2140 directLibs = append(directLibs, dep.HeaderJars...) 2141 } else if tag == staticLibTag { 2142 directStaticLibs = append(directStaticLibs, dep.HeaderJars...) 2143 } else { 2144 // Don't propagate transitive libs for other kinds of dependencies. 2145 return 2146 } 2147 2148 transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJarsForR8) 2149 transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJarsForR8) 2150 } 2151 }) 2152 j.transitiveLibsHeaderJarsForR8 = depset.New(depset.POSTORDER, directLibs, transitiveLibs) 2153 j.transitiveStaticLibsHeaderJarsForR8 = depset.New(depset.POSTORDER, directStaticLibs, transitiveStaticLibs) 2154} 2155 2156func (j *Module) HeaderJars() android.Paths { 2157 if j.headerJarFile == nil { 2158 return nil 2159 } 2160 return android.Paths{j.headerJarFile} 2161} 2162 2163func (j *Module) ImplementationJars() android.Paths { 2164 if j.implementationJarFile == nil { 2165 return nil 2166 } 2167 return android.Paths{j.implementationJarFile} 2168} 2169 2170func (j *Module) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { 2171 return j.dexJarFile 2172} 2173 2174func (j *Module) DexJarInstallPath() android.Path { 2175 return j.installFile 2176} 2177 2178func (j *Module) ImplementationAndResourcesJars() android.Paths { 2179 if j.implementationAndResourcesJar == nil { 2180 return nil 2181 } 2182 return android.Paths{j.implementationAndResourcesJar} 2183} 2184 2185func (j *Module) AidlIncludeDirs() android.Paths { 2186 // exportAidlIncludeDirs is type android.Paths already 2187 return j.exportAidlIncludeDirs 2188} 2189 2190func (j *Module) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 2191 return j.classLoaderContexts 2192} 2193 2194// Collect information for opening IDE project files in java/jdeps.go. 2195func (j *Module) IDEInfo(ctx android.BaseModuleContext, dpInfo *android.IdeInfo) { 2196 if j.expandJarjarRules != nil { 2197 dpInfo.Jarjar_rules = append(dpInfo.Jarjar_rules, j.expandJarjarRules.String()) 2198 } 2199 if j.headerJarFile != nil { 2200 // Add the header jar so that the rdeps can be resolved to the repackaged classes. 2201 dpInfo.Jars = append(dpInfo.Jars, j.headerJarFile.String()) 2202 } 2203 dpInfo.Srcs = append(dpInfo.Srcs, j.expandIDEInfoCompiledSrcs...) 2204 dpInfo.SrcJars = append(dpInfo.SrcJars, j.compiledSrcJars.Strings()...) 2205 dpInfo.SrcJars = append(dpInfo.SrcJars, j.annoSrcJars.Strings()...) 2206 dpInfo.Deps = append(dpInfo.Deps, j.CompilerDeps()...) 2207 dpInfo.Aidl_include_dirs = append(dpInfo.Aidl_include_dirs, j.deviceProperties.Aidl.Include_dirs...) 2208 dpInfo.Static_libs = append(dpInfo.Static_libs, j.staticLibs(ctx)...) 2209 dpInfo.Libs = append(dpInfo.Libs, j.properties.Libs...) 2210} 2211 2212func (j *Module) CompilerDeps() []string { 2213 return j.compileDepNames 2214} 2215 2216func (j *Module) hasCode(ctx android.ModuleContext) bool { 2217 srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs) 2218 return len(srcFiles) > 0 || len(ctx.GetDirectDepsProxyWithTag(staticLibTag)) > 0 2219} 2220 2221// Implements android.ApexModule 2222func (m *Module) GetDepInSameApexChecker() android.DepInSameApexChecker { 2223 return JavaDepInSameApexChecker{} 2224} 2225 2226type JavaDepInSameApexChecker struct { 2227 android.BaseDepInSameApexChecker 2228} 2229 2230func (m JavaDepInSameApexChecker) OutgoingDepIsInSameApex(tag blueprint.DependencyTag) bool { 2231 return depIsInSameApex(tag) 2232} 2233 2234// Implements android.ApexModule 2235func (j *Module) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { 2236 sdkVersionSpec := j.SdkVersion(ctx) 2237 minSdkVersion := j.MinSdkVersion(ctx) 2238 2239 // If the module is compiling against core (via sdk_version), skip comparison check. 2240 if sdkVersionSpec.Kind == android.SdkCore { 2241 return android.MinApiLevel 2242 } 2243 2244 return minSdkVersion 2245} 2246 2247func (j *Module) Stem() string { 2248 if j.stem == "" { 2249 panic("Stem() called before stem property was set") 2250 } 2251 return j.stem 2252} 2253 2254func (j *Module) JacocoReportClassesFile() android.Path { 2255 return j.jacocoReportClassesFile 2256} 2257 2258func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) { 2259 var fromDeps []depset.DepSet[android.Path] 2260 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { 2261 tag := ctx.OtherModuleDependencyTag(module) 2262 if tag == staticLibTag { 2263 if depInfo, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { 2264 fromDeps = append(fromDeps, depInfo.TransitiveSrcFiles) 2265 } 2266 } 2267 }) 2268 2269 j.transitiveSrcFiles = depset.New(depset.POSTORDER, mine, fromDeps) 2270} 2271 2272func (j *Module) IsInstallable() bool { 2273 return Bool(j.properties.Installable) 2274} 2275 2276type sdkLinkType int 2277 2278const ( 2279 // TODO(jiyong) rename these for better readability. Make the allowed 2280 // and disallowed link types explicit 2281 // order is important here. See rank() 2282 javaCore sdkLinkType = iota 2283 javaSdk 2284 javaSystem 2285 javaModule 2286 javaSystemServer 2287 javaPlatform 2288) 2289 2290func (lt sdkLinkType) String() string { 2291 switch lt { 2292 case javaCore: 2293 return "core Java API" 2294 case javaSdk: 2295 return "Android API" 2296 case javaSystem: 2297 return "system API" 2298 case javaModule: 2299 return "module API" 2300 case javaSystemServer: 2301 return "system server API" 2302 case javaPlatform: 2303 return "private API" 2304 default: 2305 panic(fmt.Errorf("unrecognized linktype: %d", lt)) 2306 } 2307} 2308 2309// rank determines the total order among sdkLinkType. An SDK link type of rank A can link to 2310// another SDK link type of rank B only when B <= A. For example, a module linking to Android SDK 2311// can't statically depend on modules that use Platform API. 2312func (lt sdkLinkType) rank() int { 2313 return int(lt) 2314} 2315 2316type moduleWithSdkDep interface { 2317 android.Module 2318 getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) 2319} 2320 2321func sdkLinkTypeFromSdkKind(k android.SdkKind) sdkLinkType { 2322 switch k { 2323 case android.SdkCore: 2324 return javaCore 2325 case android.SdkSystem: 2326 return javaSystem 2327 case android.SdkPublic: 2328 return javaSdk 2329 case android.SdkModule: 2330 return javaModule 2331 case android.SdkSystemServer: 2332 return javaSystemServer 2333 case android.SdkPrivate, android.SdkNone, android.SdkCorePlatform, android.SdkTest: 2334 return javaPlatform 2335 default: 2336 return javaSdk 2337 } 2338} 2339 2340func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) { 2341 switch name { 2342 case android.SdkCore.DefaultJavaLibraryName(), 2343 "legacy.core.platform.api.stubs", 2344 "stable.core.platform.api.stubs", 2345 "stub-annotations", "private-stub-annotations-jar", 2346 "core-lambda-stubs", 2347 "core-generated-annotation-stubs", 2348 // jacocoagent only uses core APIs, but has to specify a non-core sdk_version so it can use 2349 // a prebuilt SDK to avoid circular dependencies when it statically included in the bootclasspath. 2350 "jacocoagent": 2351 return javaCore, true 2352 case android.SdkPublic.DefaultJavaLibraryName(): 2353 return javaSdk, true 2354 case android.SdkSystem.DefaultJavaLibraryName(): 2355 return javaSystem, true 2356 case android.SdkModule.DefaultJavaLibraryName(): 2357 return javaModule, true 2358 case android.SdkSystemServer.DefaultJavaLibraryName(): 2359 return javaSystemServer, true 2360 case android.SdkTest.DefaultJavaLibraryName(): 2361 return javaSystem, true 2362 } 2363 2364 if stub, linkType := moduleStubLinkType(m); stub { 2365 return linkType, true 2366 } 2367 2368 ver := m.SdkVersion(ctx) 2369 if !ver.Valid() { 2370 panic(fmt.Errorf("sdk_version is invalid. got %q", ver.Raw)) 2371 } 2372 2373 return sdkLinkTypeFromSdkKind(ver.Kind), false 2374} 2375 2376// checkSdkLinkType make sures the given dependency doesn't have a lower SDK link type rank than 2377// this module's. See the comment on rank() for details and an example. 2378func (j *Module) checkSdkLinkType( 2379 ctx android.ModuleContext, dep android.ModuleProxy) { 2380 if ctx.Host() { 2381 return 2382 } 2383 2384 myLinkType, stubs := j.getSdkLinkType(ctx, ctx.ModuleName()) 2385 if stubs { 2386 return 2387 } 2388 info, ok := android.OtherModuleProvider(ctx, dep, JavaInfoProvider) 2389 if !ok || info.ModuleWithSdkDepInfo == nil { 2390 panic(fmt.Errorf("dependency doesn't have ModuleWithSdkDepInfo: %v", dep)) 2391 } 2392 2393 depLinkType := info.ModuleWithSdkDepInfo.SdkLinkType 2394 2395 if myLinkType.rank() < depLinkType.rank() { 2396 ctx.ModuleErrorf("compiles against %v, but dependency %q is compiling against %v. "+ 2397 "In order to fix this, consider adjusting sdk_version: OR platform_apis: "+ 2398 "property of the source or target module so that target module is built "+ 2399 "with the same or smaller API set when compared to the source.", 2400 myLinkType, ctx.OtherModuleName(dep), depLinkType) 2401 } 2402} 2403 2404func (j *Module) collectDeps(ctx android.ModuleContext) deps { 2405 var deps deps 2406 2407 sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName()) 2408 2409 j.collectTransitiveHeaderJarsForR8(ctx) 2410 2411 var transitiveBootClasspathHeaderJars []depset.DepSet[android.Path] 2412 var transitiveClasspathHeaderJars []depset.DepSet[android.Path] 2413 var transitiveJava9ClasspathHeaderJars []depset.DepSet[android.Path] 2414 var transitiveStaticJarsHeaderLibs []depset.DepSet[android.Path] 2415 var transitiveStaticJarsImplementationLibs []depset.DepSet[android.Path] 2416 var transitiveStaticJarsResourceLibs []depset.DepSet[android.Path] 2417 2418 ctx.VisitDirectDepsProxy(func(module android.ModuleProxy) { 2419 otherName := ctx.OtherModuleName(module) 2420 tag := ctx.OtherModuleDependencyTag(module) 2421 2422 if IsJniDepTag(tag) { 2423 // Handled by AndroidApp.collectAppDeps 2424 return 2425 } 2426 if tag == certificateTag { 2427 // Handled by AndroidApp.collectAppDeps 2428 return 2429 } 2430 2431 if sdkInfo, ok := android.OtherModuleProvider(ctx, module, SdkLibraryInfoProvider); ok { 2432 switch tag { 2433 case sdkLibTag, libTag, staticLibTag: 2434 generatingLibsString := android.PrettyConcat( 2435 getGeneratingLibs(ctx, j.SdkVersion(ctx), module.Name(), sdkInfo), true, "or") 2436 ctx.ModuleErrorf("cannot depend directly on java_sdk_library %q; try depending on %s instead", module.Name(), generatingLibsString) 2437 } 2438 } else if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { 2439 if sdkLinkType != javaPlatform { 2440 if syspropDep, ok := android.OtherModuleProvider(ctx, module, SyspropPublicStubInfoProvider); ok { 2441 // dep is a sysprop implementation library, but this module is not linking against 2442 // the platform, so it gets the sysprop public stubs library instead. Replace 2443 // dep with the JavaInfo from the SyspropPublicStubInfoProvider. 2444 dep = syspropDep.JavaInfo 2445 } 2446 } 2447 switch tag { 2448 case bootClasspathTag: 2449 deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...) 2450 transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) 2451 case sdkLibTag, libTag, instrumentationForTag: 2452 if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok { 2453 ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName) 2454 } 2455 deps.classpath = append(deps.classpath, dep.HeaderJars...) 2456 deps.dexClasspath = append(deps.dexClasspath, dep.HeaderJars...) 2457 if len(dep.RepackagedHeaderJars) == 1 && !slices.Contains(dep.HeaderJars, dep.RepackagedHeaderJars[0]) { 2458 deps.classpath = append(deps.classpath, dep.RepackagedHeaderJars...) 2459 deps.dexClasspath = append(deps.dexClasspath, dep.RepackagedHeaderJars...) 2460 } 2461 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) 2462 addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...) 2463 deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine 2464 2465 transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) 2466 case java9LibTag: 2467 deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...) 2468 transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) 2469 case staticLibTag: 2470 if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok { 2471 ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName) 2472 } 2473 deps.classpath = append(deps.classpath, dep.HeaderJars...) 2474 deps.staticJars = append(deps.staticJars, dep.ImplementationJars...) 2475 deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars...) 2476 deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars...) 2477 deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) 2478 addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...) 2479 // Turbine doesn't run annotation processors, so any module that uses an 2480 // annotation processor that generates API is incompatible with the turbine 2481 // optimization. 2482 deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine 2483 deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...) 2484 2485 transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars) 2486 transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, dep.TransitiveStaticLibsHeaderJars) 2487 transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, dep.TransitiveStaticLibsImplementationJars) 2488 transitiveStaticJarsResourceLibs = append(transitiveStaticJarsResourceLibs, dep.TransitiveStaticLibsResourceJars) 2489 case pluginTag: 2490 if plugin, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok { 2491 if plugin.ProcessorClass != nil { 2492 addPlugins(&deps, dep.ImplementationAndResourcesJars, *plugin.ProcessorClass) 2493 } else { 2494 addPlugins(&deps, dep.ImplementationAndResourcesJars) 2495 } 2496 // Turbine doesn't run annotation processors, so any module that uses an 2497 // annotation processor that generates API is incompatible with the turbine 2498 // optimization. 2499 deps.disableTurbine = deps.disableTurbine || plugin.GeneratesApi 2500 } else { 2501 ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName) 2502 } 2503 case errorpronePluginTag: 2504 if _, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok { 2505 deps.errorProneProcessorPath = append(deps.errorProneProcessorPath, dep.ImplementationAndResourcesJars...) 2506 } else { 2507 ctx.PropertyErrorf("plugins", "%q is not a java_plugin module", otherName) 2508 } 2509 case exportedPluginTag: 2510 if plugin, ok := android.OtherModuleProvider(ctx, module, JavaPluginInfoProvider); ok { 2511 j.exportedPluginJars = append(j.exportedPluginJars, dep.ImplementationAndResourcesJars...) 2512 if plugin.ProcessorClass != nil { 2513 j.exportedPluginClasses = append(j.exportedPluginClasses, *plugin.ProcessorClass) 2514 } 2515 // Turbine doesn't run annotation processors, so any module that uses an 2516 // annotation processor that generates API is incompatible with the turbine 2517 // optimization. 2518 j.exportedDisableTurbine = plugin.GeneratesApi 2519 } else { 2520 ctx.PropertyErrorf("exported_plugins", "%q is not a java_plugin module", otherName) 2521 } 2522 case kotlinPluginTag: 2523 if _, ok := android.OtherModuleProvider(ctx, module, KotlinPluginInfoProvider); ok { 2524 deps.kotlinPlugins = append(deps.kotlinPlugins, dep.ImplementationAndResourcesJars...) 2525 } else { 2526 ctx.PropertyErrorf("kotlin_plugins", "%q is not a kotlin_plugin module", otherName) 2527 } 2528 case syspropPublicStubDepTag: 2529 // This is a sysprop implementation library, forward the JavaInfoProvider from 2530 // the corresponding sysprop public stub library as SyspropPublicStubInfoProvider. 2531 android.SetProvider(ctx, SyspropPublicStubInfoProvider, SyspropPublicStubInfo{ 2532 JavaInfo: dep, 2533 }) 2534 } 2535 } else if dep, ok := android.OtherModuleProvider(ctx, module, android.SourceFilesInfoProvider); ok { 2536 switch tag { 2537 case sdkLibTag, libTag: 2538 checkProducesJars(ctx, dep, module) 2539 deps.classpath = append(deps.classpath, dep.Srcs...) 2540 deps.dexClasspath = append(deps.classpath, dep.Srcs...) 2541 transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, 2542 depset.New(depset.PREORDER, dep.Srcs, nil)) 2543 case staticLibTag: 2544 checkProducesJars(ctx, dep, module) 2545 deps.classpath = append(deps.classpath, dep.Srcs...) 2546 deps.staticJars = append(deps.staticJars, dep.Srcs...) 2547 deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs...) 2548 2549 depHeaderJars := depset.New(depset.PREORDER, dep.Srcs, nil) 2550 transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, depHeaderJars) 2551 transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, depHeaderJars) 2552 transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, depHeaderJars) 2553 } 2554 } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok { 2555 switch tag { 2556 case staticLibTag: 2557 deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.IntermediateCacheOutputPaths...) 2558 } 2559 } else { 2560 switch tag { 2561 case bootClasspathTag: 2562 // If a system modules dependency has been added to the bootclasspath 2563 // then add its libs to the bootclasspath. 2564 if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok { 2565 deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars...) 2566 transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, 2567 sm.TransitiveStaticLibsHeaderJars) 2568 } else { 2569 ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider", 2570 ctx.OtherModuleName(module)) 2571 } 2572 2573 case systemModulesTag: 2574 if deps.systemModules != nil { 2575 panic("Found two system module dependencies") 2576 } 2577 if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok { 2578 deps.systemModules = &systemModules{sm.OutputDir, sm.OutputDirDeps} 2579 } else { 2580 ctx.PropertyErrorf("system modules dependency %q does not provide SystemModulesProvider", 2581 ctx.OtherModuleName(module)) 2582 } 2583 2584 case instrumentationForTag: 2585 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)) 2586 } 2587 } 2588 2589 if android.InList(tag, compileDependencyTags) { 2590 // Add the dependency name to compileDepNames so that it can be recorded in module_bp_java_deps.json 2591 j.compileDepNames = append(j.compileDepNames, otherName) 2592 } 2593 2594 addCLCFromDep(ctx, module, j.classLoaderContexts) 2595 addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary) 2596 }) 2597 2598 deps.transitiveStaticLibsHeaderJars = transitiveStaticJarsHeaderLibs 2599 deps.transitiveStaticLibsImplementationJars = transitiveStaticJarsImplementationLibs 2600 deps.transitiveStaticLibsResourceJars = transitiveStaticJarsResourceLibs 2601 2602 depSet := depset.New(depset.PREORDER, nil, transitiveClasspathHeaderJars) 2603 deps.classpath = depSet.ToList() 2604 depSet = depset.New(depset.PREORDER, nil, transitiveBootClasspathHeaderJars) 2605 deps.bootClasspath = depSet.ToList() 2606 depSet = depset.New(depset.PREORDER, nil, transitiveJava9ClasspathHeaderJars) 2607 deps.java9Classpath = depSet.ToList() 2608 2609 if ctx.Device() { 2610 sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) 2611 if sdkDep.invalidVersion { 2612 ctx.AddMissingDependencies(sdkDep.bootclasspath) 2613 ctx.AddMissingDependencies(sdkDep.java9Classpath) 2614 } else if sdkDep.useFiles { 2615 // sdkDep.jar is actually equivalent to turbine header.jar. 2616 deps.classpath = append(slices.Clone(classpath(sdkDep.jars)), deps.classpath...) 2617 deps.dexClasspath = append(slices.Clone(classpath(sdkDep.jars)), deps.dexClasspath...) 2618 deps.aidlPreprocess = sdkDep.aidl 2619 // Add the sdk module dependency to `compileDepNames`. 2620 // This ensures that the dependency is reported in `module_bp_java_deps.json` 2621 // TODO (b/358608607): Move this to decodeSdkDep 2622 sdkSpec := android.SdkContext(j).SdkVersion(ctx) 2623 j.compileDepNames = append(j.compileDepNames, fmt.Sprintf("sdk_%s_%s_android", sdkSpec.Kind.String(), sdkSpec.ApiLevel.String())) 2624 } else { 2625 deps.aidlPreprocess = sdkDep.aidl 2626 } 2627 } 2628 2629 return deps 2630} 2631 2632// Provider for jarjar renaming rules. 2633// 2634// Modules can set their jarjar renaming rules with addJarJarRenameRule, and those renamings will be 2635// passed to all rdeps. The typical way that these renamings will NOT be inherited is when a module 2636// links against stubs -- these are not passed through stubs. The classes will remain unrenamed on 2637// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then 2638// be renamed from that module. 2639// TODO: Add another property to suppress the forwarding of 2640type DependencyUse int 2641 2642const ( 2643 RenameUseInvalid DependencyUse = iota 2644 RenameUseInclude 2645 RenameUseExclude 2646) 2647 2648type JarJarProviderData struct { 2649 // Mapping of class names: original --> renamed. If the value is "", the class will be 2650 // renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has 2651 // attribute). Rdeps of that module will inherit the renaming. 2652 Rename map[string]string 2653} 2654 2655func (this JarJarProviderData) GetDebugString() string { 2656 result := "" 2657 for _, k := range android.SortedKeys(this.Rename) { 2658 v := this.Rename[k] 2659 if strings.Contains(k, "android.companion.virtual.flags.FakeFeatureFlagsImpl") { 2660 result += k + "-->" + v + ";" 2661 } 2662 } 2663 return result 2664} 2665 2666var JarJarProvider = blueprint.NewProvider[JarJarProviderData]() 2667 2668var overridableJarJarPrefix = "com.android.internal.hidden_from_bootclasspath" 2669 2670func init() { 2671 android.SetJarJarPrefixHandler(mergeJarJarPrefixes) 2672 2673 gob.Register(BaseJarJarProviderData{}) 2674} 2675 2676// BaseJarJarProviderData contains information that will propagate across dependencies regardless of 2677// whether they are java modules or not. 2678type BaseJarJarProviderData struct { 2679 JarJarProviderData JarJarProviderData 2680} 2681 2682func (this BaseJarJarProviderData) GetDebugString() string { 2683 return this.JarJarProviderData.GetDebugString() 2684} 2685 2686var BaseJarJarProvider = blueprint.NewProvider[BaseJarJarProviderData]() 2687 2688// mergeJarJarPrefixes is called immediately before module.GenerateAndroidBuildActions is called. 2689// Since there won't be a JarJarProvider, we create the BaseJarJarProvider if any of our deps have 2690// either JarJarProvider or BaseJarJarProvider. 2691func mergeJarJarPrefixes(ctx android.ModuleContext) { 2692 mod := ctx.Module() 2693 // Explicitly avoid propagating into some module types. 2694 switch reflect.TypeOf(mod).String() { 2695 case "*java.Droidstubs": 2696 return 2697 } 2698 jarJarData := collectDirectDepsProviders(ctx) 2699 if jarJarData != nil { 2700 providerData := BaseJarJarProviderData{ 2701 JarJarProviderData: *jarJarData, 2702 } 2703 android.SetProvider(ctx, BaseJarJarProvider, providerData) 2704 } 2705 2706} 2707 2708// Add a jarjar renaming rule to this module, to be inherited to all dependent modules. 2709func (module *Module) addJarJarRenameRule(original string, renamed string) { 2710 if module.jarjarRenameRules == nil { 2711 module.jarjarRenameRules = make(map[string]string) 2712 } 2713 module.jarjarRenameRules[original] = renamed 2714} 2715 2716func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) { 2717 // Gather repackage information from deps 2718 // If the dep jas a JarJarProvider, it is used. Otherwise, any BaseJarJarProvider is used. 2719 2720 module := ctx.Module() 2721 moduleName := module.Name() 2722 2723 ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) { 2724 tag := ctx.OtherModuleDependencyTag(m) 2725 // This logic mirrors that in (*Module).collectDeps above. There are several places 2726 // where we explicitly return RenameUseExclude, even though it is the default, to 2727 // indicate that it has been verified to be the case. 2728 // 2729 // Note well: there are probably cases that are getting to the unconditional return 2730 // and are therefore wrong. 2731 shouldIncludeRenames := func() DependencyUse { 2732 if moduleName == m.Name() { 2733 return RenameUseInclude // If we have the same module name, include the renames. 2734 } 2735 if sc, ok := module.(android.SdkContext); ok { 2736 if ctx.Device() { 2737 sdkDep := decodeSdkDep(ctx, sc) 2738 if !sdkDep.invalidVersion && sdkDep.useFiles { 2739 return RenameUseExclude 2740 } 2741 } 2742 } 2743 if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag { 2744 return RenameUseExclude 2745 } 2746 if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok { 2747 switch tag { 2748 case sdkLibTag, libTag: 2749 return RenameUseExclude // matches collectDeps() 2750 } 2751 return RenameUseInvalid // dep is not used in collectDeps() 2752 } else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok { 2753 switch ji.StubsLinkType { 2754 case Stubs: 2755 return RenameUseExclude 2756 case Implementation: 2757 return RenameUseInclude 2758 default: 2759 //fmt.Printf("collectDirectDepsProviders: %v -> %v StubsLinkType unknown\n", module, m) 2760 // Fall through to the heuristic logic. 2761 } 2762 if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok { 2763 // Probably a java_aconfig_library module. 2764 return RenameUseInclude 2765 } 2766 switch tag { 2767 case bootClasspathTag: 2768 return RenameUseExclude 2769 case sdkLibTag, libTag, instrumentationForTag: 2770 return RenameUseInclude 2771 case java9LibTag: 2772 return RenameUseExclude 2773 case staticLibTag: 2774 return RenameUseInclude 2775 case pluginTag: 2776 return RenameUseInclude 2777 case errorpronePluginTag: 2778 return RenameUseInclude 2779 case exportedPluginTag: 2780 return RenameUseInclude 2781 case kotlinPluginTag: 2782 return RenameUseInclude 2783 default: 2784 return RenameUseExclude 2785 } 2786 } else if _, ok := android.OtherModuleProvider(ctx, m, android.SourceFilesInfoProvider); ok { 2787 switch tag { 2788 case sdkLibTag, libTag, staticLibTag: 2789 return RenameUseInclude 2790 default: 2791 return RenameUseExclude 2792 } 2793 } else if _, ok := android.OtherModuleProvider(ctx, m, android.CodegenInfoProvider); ok { 2794 return RenameUseInclude 2795 } else { 2796 switch tag { 2797 case bootClasspathTag: 2798 return RenameUseExclude 2799 case systemModulesTag: 2800 return RenameUseInclude 2801 } 2802 } 2803 // If we got here, choose the safer option, which may lead to a build failure, rather 2804 // than runtime failures on the device. 2805 return RenameUseExclude 2806 } 2807 2808 if result == nil { 2809 result = &JarJarProviderData{ 2810 Rename: make(map[string]string), 2811 } 2812 } 2813 how := shouldIncludeRenames() 2814 if how != RenameUseInclude { 2815 // Nothing to merge. 2816 return 2817 } 2818 2819 merge := func(theirs *JarJarProviderData) { 2820 for orig, renamed := range theirs.Rename { 2821 if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" { 2822 result.Rename[orig] = renamed 2823 } else if preexisting != "" && renamed != "" && preexisting != renamed { 2824 if strings.HasPrefix(preexisting, overridableJarJarPrefix) { 2825 result.Rename[orig] = renamed 2826 } else if !strings.HasPrefix(renamed, overridableJarJarPrefix) { 2827 ctx.ModuleErrorf("1. Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting, ctx.ModuleName(), m.Name()) 2828 continue 2829 } 2830 } 2831 } 2832 } 2833 if theirs, ok := android.OtherModuleProvider(ctx, m, JarJarProvider); ok { 2834 merge(&theirs) 2835 } else if theirs, ok := android.OtherModuleProvider(ctx, m, BaseJarJarProvider); ok { 2836 // TODO: if every java.Module should have a JarJarProvider, and we find only the 2837 // BaseJarJarProvider, then there is a bug. Consider seeing if m can be cast 2838 // to java.Module. 2839 merge(&theirs.JarJarProviderData) 2840 } 2841 }) 2842 return 2843} 2844 2845func (this Module) GetDebugString() string { 2846 return "sdk_version=" + proptools.String(this.deviceProperties.Sdk_version) 2847} 2848 2849// Merge the jarjar rules we inherit from our dependencies, any that have been added directly to 2850// us, and if it's been set, apply the jarjar_prefix property to rename them. 2851func (module *Module) collectJarJarRules(ctx android.ModuleContext) *JarJarProviderData { 2852 // Gather repackage information from deps 2853 result := collectDirectDepsProviders(ctx) 2854 2855 add := func(orig string, renamed string) { 2856 if result == nil { 2857 result = &JarJarProviderData{ 2858 Rename: make(map[string]string), 2859 } 2860 } 2861 if renamed != "" { 2862 if preexisting, exists := (*result).Rename[orig]; exists && preexisting != renamed { 2863 ctx.ModuleErrorf("Conflicting jarjar rules inherited for class: %s (%s and %s)", orig, renamed, preexisting) 2864 return 2865 } 2866 } 2867 (*result).Rename[orig] = renamed 2868 } 2869 2870 // Update that with entries we've stored for ourself 2871 for orig, renamed := range module.jarjarRenameRules { 2872 add(orig, renamed) 2873 } 2874 2875 // Update that with entries given in the jarjar_rename property. 2876 for _, orig := range module.properties.Jarjar_rename { 2877 add(orig, "") 2878 } 2879 2880 // If there are no renamings, then jarjar_prefix does nothing, so skip the extra work. 2881 if result == nil { 2882 return nil 2883 } 2884 2885 // If they've given us a jarjar_prefix property, then we will use that to rename any classes 2886 // that have not yet been renamed. 2887 prefix := proptools.String(module.properties.Jarjar_prefix) 2888 if prefix != "" { 2889 if prefix[0] == '.' { 2890 ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not start with '.'") 2891 return nil 2892 } 2893 if prefix[len(prefix)-1] == '.' { 2894 ctx.PropertyErrorf("jarjar_prefix", "jarjar_prefix can not end with '.'") 2895 return nil 2896 } 2897 2898 var updated map[string]string 2899 for orig, renamed := range (*result).Rename { 2900 if renamed == "" { 2901 if updated == nil { 2902 updated = make(map[string]string) 2903 } 2904 updated[orig] = prefix + "." + orig 2905 } 2906 } 2907 for orig, renamed := range updated { 2908 (*result).Rename[orig] = renamed 2909 } 2910 } 2911 2912 return result 2913} 2914 2915// Get the jarjar rule text for a given provider for the fully resolved rules. Classes that map 2916// to "" won't be in this list because they shouldn't be renamed yet. 2917func getJarJarRuleText(provider *JarJarProviderData) string { 2918 result := strings.Builder{} 2919 for _, orig := range android.SortedKeys(provider.Rename) { 2920 renamed := provider.Rename[orig] 2921 if renamed != "" { 2922 result.WriteString("rule ") 2923 result.WriteString(orig) 2924 result.WriteString(" ") 2925 result.WriteString(renamed) 2926 result.WriteString("\n") 2927 } 2928 } 2929 return result.String() 2930} 2931 2932// Repackage the flags if the jarjar rule txt for the flags is generated 2933func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) (android.Path, bool) { 2934 if j.repackageJarjarRules == nil { 2935 return infile, false 2936 } 2937 repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info, jarName) 2938 TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules) 2939 return repackagedJarjarFile, true 2940} 2941 2942func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string, useShards bool) (android.Path, bool) { 2943 if j.expandJarjarRules == nil { 2944 return infile, false 2945 } 2946 jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName) 2947 2948 totalShards := 1 2949 if useShards { 2950 totalShardsStr := j.properties.Jarjar_shards.GetOrDefault(ctx, "1") 2951 ts, err := strconv.Atoi(totalShardsStr) 2952 if err != nil { 2953 ctx.PropertyErrorf("jarjar_shards", "jarjar_shards must be an integer represented as a string") 2954 return infile, false 2955 } 2956 totalShards = ts 2957 } 2958 TransformJarJarWithShards(ctx, jarjarFile, infile, j.expandJarjarRules, totalShards) 2959 return jarjarFile, true 2960 2961} 2962 2963func addPlugins(deps *deps, pluginJars android.Paths, pluginClasses ...string) { 2964 deps.processorPath = append(deps.processorPath, pluginJars...) 2965 deps.processorClasses = append(deps.processorClasses, pluginClasses...) 2966} 2967 2968// TODO(b/132357300) Generalize SdkLibrarComponentDependency to non-SDK libraries and merge with 2969// this interface. 2970type ProvidesUsesLib interface { 2971 ProvidesUsesLib() *string 2972} 2973 2974func (j *Module) ProvidesUsesLib() *string { 2975 return j.usesLibraryProperties.Provides_uses_lib 2976} 2977 2978type ModuleWithStem interface { 2979 Stem() string 2980} 2981 2982var _ ModuleWithStem = (*Module)(nil) 2983 2984type ModuleWithUsesLibrary interface { 2985 UsesLibrary() *usesLibrary 2986} 2987 2988func (j *Module) UsesLibrary() *usesLibrary { 2989 return &j.usesLibrary 2990} 2991 2992var _ ModuleWithUsesLibrary = (*Module)(nil) 2993