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