1// Copyright 2015 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package java 16 17// This file contains the module types for compiling Java for Android, and converts the properties 18// into the flags and filenames necessary to pass to the Module. The final creation of the rules 19// is handled in builder.go 20 21import ( 22 "fmt" 23 "path/filepath" 24 "strings" 25 26 "android/soong/bazel" 27 28 "github.com/google/blueprint" 29 "github.com/google/blueprint/proptools" 30 31 "android/soong/android" 32 "android/soong/cc" 33 "android/soong/dexpreopt" 34 "android/soong/java/config" 35 "android/soong/tradefed" 36) 37 38func init() { 39 registerJavaBuildComponents(android.InitRegistrationContext) 40 41 RegisterJavaSdkMemberTypes() 42} 43 44func registerJavaBuildComponents(ctx android.RegistrationContext) { 45 ctx.RegisterModuleType("java_defaults", DefaultsFactory) 46 47 ctx.RegisterModuleType("java_library", LibraryFactory) 48 ctx.RegisterModuleType("java_library_static", LibraryStaticFactory) 49 ctx.RegisterModuleType("java_library_host", LibraryHostFactory) 50 ctx.RegisterModuleType("java_binary", BinaryFactory) 51 ctx.RegisterModuleType("java_binary_host", BinaryHostFactory) 52 ctx.RegisterModuleType("java_test", TestFactory) 53 ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory) 54 ctx.RegisterModuleType("java_test_host", TestHostFactory) 55 ctx.RegisterModuleType("java_test_import", JavaTestImportFactory) 56 ctx.RegisterModuleType("java_import", ImportFactory) 57 ctx.RegisterModuleType("java_import_host", ImportFactoryHost) 58 ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory) 59 ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory) 60 ctx.RegisterModuleType("dex_import", DexImportFactory) 61 62 // This mutator registers dependencies on dex2oat for modules that should be 63 // dexpreopted. This is done late when the final variants have been 64 // established, to not get the dependencies split into the wrong variants and 65 // to support the checks in dexpreoptDisabled(). 66 ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { 67 ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel() 68 }) 69 70 ctx.RegisterSingletonType("logtags", LogtagsSingleton) 71 ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) 72} 73 74func RegisterJavaSdkMemberTypes() { 75 // Register sdk member types. 76 android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) 77 android.RegisterSdkMemberType(javaLibsSdkMemberType) 78 android.RegisterSdkMemberType(javaBootLibsSdkMemberType) 79 android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType) 80 android.RegisterSdkMemberType(javaTestSdkMemberType) 81} 82 83var ( 84 // Supports adding java header libraries to module_exports and sdk. 85 javaHeaderLibsSdkMemberType = &librarySdkMemberType{ 86 android.SdkMemberTypeBase{ 87 PropertyName: "java_header_libs", 88 SupportsSdk: true, 89 }, 90 func(_ android.SdkMemberContext, j *Library) android.Path { 91 headerJars := j.HeaderJars() 92 if len(headerJars) != 1 { 93 panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) 94 } 95 96 return headerJars[0] 97 }, 98 sdkSnapshotFilePathForJar, 99 copyEverythingToSnapshot, 100 } 101 102 // Export implementation classes jar as part of the sdk. 103 exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path { 104 implementationJars := j.ImplementationAndResourcesJars() 105 if len(implementationJars) != 1 { 106 panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) 107 } 108 return implementationJars[0] 109 } 110 111 // Supports adding java implementation libraries to module_exports but not sdk. 112 javaLibsSdkMemberType = &librarySdkMemberType{ 113 android.SdkMemberTypeBase{ 114 PropertyName: "java_libs", 115 }, 116 exportImplementationClassesJar, 117 sdkSnapshotFilePathForJar, 118 copyEverythingToSnapshot, 119 } 120 121 snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool { 122 // In the S build the build will break if updatable-media does not provide a full implementation 123 // jar. That issue was fixed in Tiramisu by b/229932396. 124 if ctx.IsTargetBuildBeforeTiramisu() && ctx.Name() == "updatable-media" { 125 return true 126 } 127 128 return false 129 } 130 131 // Supports adding java boot libraries to module_exports and sdk. 132 // 133 // The build has some implicit dependencies (via the boot jars configuration) on a number of 134 // modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are 135 // provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise 136 // used outside those mainline modules. 137 // 138 // As they are not needed outside the mainline modules adding them to the sdk/module-exports as 139 // either java_libs, or java_header_libs would end up exporting more information than was strictly 140 // necessary. The java_boot_libs property to allow those modules to be exported as part of the 141 // sdk/module_exports without exposing any unnecessary information. 142 javaBootLibsSdkMemberType = &librarySdkMemberType{ 143 android.SdkMemberTypeBase{ 144 PropertyName: "java_boot_libs", 145 SupportsSdk: true, 146 }, 147 func(ctx android.SdkMemberContext, j *Library) android.Path { 148 if snapshotRequiresImplementationJar(ctx) { 149 return exportImplementationClassesJar(ctx, j) 150 } 151 152 // Java boot libs are only provided in the SDK to provide access to their dex implementation 153 // jar for use by dexpreopting and boot jars package check. They do not need to provide an 154 // actual implementation jar but the java_import will need a file that exists so just copy an 155 // empty file. Any attempt to use that file as a jar will cause a build error. 156 return ctx.SnapshotBuilder().EmptyFile() 157 }, 158 func(ctx android.SdkMemberContext, osPrefix, name string) string { 159 if snapshotRequiresImplementationJar(ctx) { 160 return sdkSnapshotFilePathForJar(ctx, osPrefix, name) 161 } 162 163 // Create a special name for the implementation jar to try and provide some useful information 164 // to a developer that attempts to compile against this. 165 // TODO(b/175714559): Provide a proper error message in Soong not ninja. 166 return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) 167 }, 168 onlyCopyJarToSnapshot, 169 } 170 171 // Supports adding java systemserver libraries to module_exports and sdk. 172 // 173 // The build has some implicit dependencies (via the systemserver jars configuration) on a number 174 // of modules that are part of the java systemserver classpath and which are provided by mainline 175 // modules but which are not otherwise used outside those mainline modules. 176 // 177 // As they are not needed outside the mainline modules adding them to the sdk/module-exports as 178 // either java_libs, or java_header_libs would end up exporting more information than was strictly 179 // necessary. The java_systemserver_libs property to allow those modules to be exported as part of 180 // the sdk/module_exports without exposing any unnecessary information. 181 javaSystemserverLibsSdkMemberType = &librarySdkMemberType{ 182 android.SdkMemberTypeBase{ 183 PropertyName: "java_systemserver_libs", 184 SupportsSdk: true, 185 186 // This was only added in Tiramisu. 187 SupportedBuildReleaseSpecification: "Tiramisu+", 188 }, 189 func(ctx android.SdkMemberContext, j *Library) android.Path { 190 // Java systemserver libs are only provided in the SDK to provide access to their dex 191 // implementation jar for use by dexpreopting. They do not need to provide an actual 192 // implementation jar but the java_import will need a file that exists so just copy an empty 193 // file. Any attempt to use that file as a jar will cause a build error. 194 return ctx.SnapshotBuilder().EmptyFile() 195 }, 196 func(_ android.SdkMemberContext, osPrefix, name string) string { 197 // Create a special name for the implementation jar to try and provide some useful information 198 // to a developer that attempts to compile against this. 199 // TODO(b/175714559): Provide a proper error message in Soong not ninja. 200 return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) 201 }, 202 onlyCopyJarToSnapshot, 203 } 204 205 // Supports adding java test libraries to module_exports but not sdk. 206 javaTestSdkMemberType = &testSdkMemberType{ 207 SdkMemberTypeBase: android.SdkMemberTypeBase{ 208 PropertyName: "java_tests", 209 }, 210 } 211) 212 213// JavaInfo contains information about a java module for use by modules that depend on it. 214type JavaInfo struct { 215 // HeaderJars is a list of jars that can be passed as the javac classpath in order to link 216 // against this module. If empty, ImplementationJars should be used instead. 217 HeaderJars android.Paths 218 219 // ImplementationAndResourceJars is a list of jars that contain the implementations of classes 220 // in the module as well as any resources included in the module. 221 ImplementationAndResourcesJars android.Paths 222 223 // ImplementationJars is a list of jars that contain the implementations of classes in the 224 //module. 225 ImplementationJars android.Paths 226 227 // ResourceJars is a list of jars that contain the resources included in the module. 228 ResourceJars android.Paths 229 230 // AidlIncludeDirs is a list of directories that should be passed to the aidl tool when 231 // depending on this module. 232 AidlIncludeDirs android.Paths 233 234 // SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this 235 // module. 236 SrcJarArgs []string 237 238 // SrcJarDeps is a list of paths to depend on when packaging the sources of this module. 239 SrcJarDeps android.Paths 240 241 // ExportedPlugins is a list of paths that should be used as annotation processors for any 242 // module that depends on this module. 243 ExportedPlugins android.Paths 244 245 // ExportedPluginClasses is a list of classes that should be run as annotation processors for 246 // any module that depends on this module. 247 ExportedPluginClasses []string 248 249 // ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs, 250 // requiring disbling turbine for any modules that depend on it. 251 ExportedPluginDisableTurbine bool 252 253 // JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be 254 // instrumented by jacoco. 255 JacocoReportClassesFile android.Path 256} 257 258var JavaInfoProvider = blueprint.NewProvider(JavaInfo{}) 259 260// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to 261// the sysprop implementation library. 262type SyspropPublicStubInfo struct { 263 // JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to 264 // the sysprop implementation library. 265 JavaInfo JavaInfo 266} 267 268var SyspropPublicStubInfoProvider = blueprint.NewProvider(SyspropPublicStubInfo{}) 269 270// Methods that need to be implemented for a module that is added to apex java_libs property. 271type ApexDependency interface { 272 HeaderJars() android.Paths 273 ImplementationAndResourcesJars() android.Paths 274} 275 276// Provides build path and install path to DEX jars. 277type UsesLibraryDependency interface { 278 DexJarBuildPath() OptionalDexJarPath 279 DexJarInstallPath() android.Path 280 ClassLoaderContexts() dexpreopt.ClassLoaderContextMap 281} 282 283// TODO(jungjw): Move this to kythe.go once it's created. 284type xref interface { 285 XrefJavaFiles() android.Paths 286} 287 288func (j *Module) XrefJavaFiles() android.Paths { 289 return j.kytheFiles 290} 291 292type dependencyTag struct { 293 blueprint.BaseDependencyTag 294 name string 295 296 // True if the dependency is relinked at runtime. 297 runtimeLinked bool 298 299 // True if the dependency is a toolchain, for example an annotation processor. 300 toolchain bool 301} 302 303// installDependencyTag is a dependency tag that is annotated to cause the installed files of the 304// dependency to be installed when the parent module is installed. 305type installDependencyTag struct { 306 blueprint.BaseDependencyTag 307 android.InstallAlwaysNeededDependencyTag 308 name string 309} 310 311func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { 312 if d.runtimeLinked { 313 return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} 314 } else if d.toolchain { 315 return []android.LicenseAnnotation{android.LicenseAnnotationToolchain} 316 } 317 return nil 318} 319 320var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} 321 322type usesLibraryDependencyTag struct { 323 dependencyTag 324 325 // SDK version in which the library appared as a standalone library. 326 sdkVersion int 327 328 // If the dependency is optional or required. 329 optional bool 330 331 // Whether this is an implicit dependency inferred by Soong, or an explicit one added via 332 // `uses_libs`/`optional_uses_libs` properties. 333 implicit bool 334} 335 336func makeUsesLibraryDependencyTag(sdkVersion int, optional bool, implicit bool) usesLibraryDependencyTag { 337 return usesLibraryDependencyTag{ 338 dependencyTag: dependencyTag{ 339 name: fmt.Sprintf("uses-library-%d", sdkVersion), 340 runtimeLinked: true, 341 }, 342 sdkVersion: sdkVersion, 343 optional: optional, 344 implicit: implicit, 345 } 346} 347 348func IsJniDepTag(depTag blueprint.DependencyTag) bool { 349 return depTag == jniLibTag 350} 351 352var ( 353 dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} 354 dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"} 355 staticLibTag = dependencyTag{name: "staticlib"} 356 libTag = dependencyTag{name: "javalib", runtimeLinked: true} 357 java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true} 358 pluginTag = dependencyTag{name: "plugin", toolchain: true} 359 errorpronePluginTag = dependencyTag{name: "errorprone-plugin", toolchain: true} 360 exportedPluginTag = dependencyTag{name: "exported-plugin", toolchain: true} 361 bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true} 362 systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true} 363 frameworkResTag = dependencyTag{name: "framework-res"} 364 kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib", runtimeLinked: true} 365 kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations", runtimeLinked: true} 366 kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true} 367 proguardRaiseTag = dependencyTag{name: "proguard-raise"} 368 certificateTag = dependencyTag{name: "certificate"} 369 instrumentationForTag = dependencyTag{name: "instrumentation_for"} 370 extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true} 371 jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true} 372 syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} 373 jniInstallTag = installDependencyTag{name: "jni install"} 374 binaryInstallTag = installDependencyTag{name: "binary install"} 375) 376 377func IsLibDepTag(depTag blueprint.DependencyTag) bool { 378 return depTag == libTag 379} 380 381func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool { 382 return depTag == staticLibTag 383} 384 385type sdkDep struct { 386 useModule, useFiles, invalidVersion bool 387 388 // The modules that will be added to the bootclasspath when targeting 1.8 or lower 389 bootclasspath []string 390 391 // The default system modules to use. Will be an empty string if no system 392 // modules are to be used. 393 systemModules string 394 395 // The modules that will be added to the classpath regardless of the Java language level targeted 396 classpath []string 397 398 // The modules that will be added ot the classpath when targeting 1.9 or higher 399 // (normally these will be on the bootclasspath when targeting 1.8 or lower) 400 java9Classpath []string 401 402 frameworkResModule string 403 404 jars android.Paths 405 aidl android.OptionalPath 406 407 noStandardLibs, noFrameworksLibs bool 408} 409 410func (s sdkDep) hasStandardLibs() bool { 411 return !s.noStandardLibs 412} 413 414func (s sdkDep) hasFrameworkLibs() bool { 415 return !s.noStandardLibs && !s.noFrameworksLibs 416} 417 418type jniLib struct { 419 name string 420 path android.Path 421 target android.Target 422 coverageFile android.OptionalPath 423 unstrippedFile android.Path 424} 425 426func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) { 427 sdkDep := decodeSdkDep(ctx, sdkContext) 428 if sdkDep.useModule { 429 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) 430 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) 431 ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...) 432 if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { 433 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...) 434 } 435 if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() { 436 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...) 437 } 438 } 439 if sdkDep.systemModules != "" { 440 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) 441 } 442} 443 444type deps struct { 445 // bootClasspath is the list of jars that form the boot classpath (generally the java.* and 446 // android.* classes) for tools that still use it. javac targeting 1.9 or higher uses 447 // systemModules and java9Classpath instead. 448 bootClasspath classpath 449 450 // classpath is the list of jars that form the classpath for javac and kotlinc rules. It 451 // contains header jars for all static and non-static dependencies. 452 classpath classpath 453 454 // dexClasspath is the list of jars that form the classpath for d8 and r8 rules. It contains 455 // header jars for all non-static dependencies. Static dependencies have already been 456 // combined into the program jar. 457 dexClasspath classpath 458 459 // java9Classpath is the list of jars that will be added to the classpath when targeting 460 // 1.9 or higher. It generally contains the android.* classes, while the java.* classes 461 // are provided by systemModules. 462 java9Classpath classpath 463 464 processorPath classpath 465 errorProneProcessorPath classpath 466 processorClasses []string 467 staticJars android.Paths 468 staticHeaderJars android.Paths 469 staticResourceJars android.Paths 470 aidlIncludeDirs android.Paths 471 srcs android.Paths 472 srcJars android.Paths 473 systemModules *systemModules 474 aidlPreprocess android.OptionalPath 475 kotlinStdlib android.Paths 476 kotlinAnnotations android.Paths 477 kotlinPlugins android.Paths 478 479 disableTurbine bool 480} 481 482func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) { 483 for _, f := range dep.Srcs() { 484 if f.Ext() != ".jar" { 485 ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency", 486 ctx.OtherModuleName(dep.(blueprint.Module))) 487 } 488 } 489} 490 491func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext android.SdkContext) javaVersion { 492 if javaVersion != "" { 493 return normalizeJavaVersion(ctx, javaVersion) 494 } else if ctx.Device() { 495 return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) 496 } else { 497 return JAVA_VERSION_11 498 } 499} 500 501type javaVersion int 502 503const ( 504 JAVA_VERSION_UNSUPPORTED = 0 505 JAVA_VERSION_6 = 6 506 JAVA_VERSION_7 = 7 507 JAVA_VERSION_8 = 8 508 JAVA_VERSION_9 = 9 509 JAVA_VERSION_11 = 11 510) 511 512func (v javaVersion) String() string { 513 switch v { 514 case JAVA_VERSION_6: 515 return "1.6" 516 case JAVA_VERSION_7: 517 return "1.7" 518 case JAVA_VERSION_8: 519 return "1.8" 520 case JAVA_VERSION_9: 521 return "1.9" 522 case JAVA_VERSION_11: 523 return "11" 524 default: 525 return "unsupported" 526 } 527} 528 529func (v javaVersion) StringForKotlinc() string { 530 // $ ./external/kotlinc/bin/kotlinc -jvm-target foo 531 // error: unknown JVM target version: foo 532 // Supported versions: 1.6, 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 533 switch v { 534 case JAVA_VERSION_7: 535 return "1.6" 536 case JAVA_VERSION_9: 537 return "9" 538 default: 539 return v.String() 540 } 541} 542 543// Returns true if javac targeting this version uses system modules instead of a bootclasspath. 544func (v javaVersion) usesJavaModules() bool { 545 return v >= 9 546} 547 548func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion { 549 switch javaVersion { 550 case "1.6", "6": 551 return JAVA_VERSION_6 552 case "1.7", "7": 553 return JAVA_VERSION_7 554 case "1.8", "8": 555 return JAVA_VERSION_8 556 case "1.9", "9": 557 return JAVA_VERSION_9 558 case "11": 559 return JAVA_VERSION_11 560 case "10": 561 ctx.PropertyErrorf("java_version", "Java language levels 10 is not supported") 562 return JAVA_VERSION_UNSUPPORTED 563 default: 564 ctx.PropertyErrorf("java_version", "Unrecognized Java language level") 565 return JAVA_VERSION_UNSUPPORTED 566 } 567} 568 569// 570// Java libraries (.jar file) 571// 572 573type Library struct { 574 Module 575 576 InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) 577} 578 579var _ android.ApexModule = (*Library)(nil) 580 581// Provides access to the list of permitted packages from apex boot jars. 582type PermittedPackagesForUpdatableBootJars interface { 583 PermittedPackagesForUpdatableBootJars() []string 584} 585 586var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil) 587 588func (j *Library) PermittedPackagesForUpdatableBootJars() []string { 589 return j.properties.Permitted_packages 590} 591 592func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { 593 // Store uncompressed (and aligned) any dex files from jars in APEXes. 594 if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { 595 return true 596 } 597 598 // Store uncompressed (and do not strip) dex files from boot class path jars. 599 if inList(ctx.ModuleName(), ctx.Config().BootJars()) { 600 return true 601 } 602 603 // Store uncompressed dex files that are preopted on /system. 604 if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, dexpreopter.installPath)) { 605 return true 606 } 607 if ctx.Config().UncompressPrivAppDex() && 608 inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) { 609 return true 610 } 611 612 return false 613} 614 615// Sets `dexer.dexProperties.Uncompress_dex` to the proper value. 616func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) { 617 if dexer.dexProperties.Uncompress_dex == nil { 618 // If the value was not force-set by the user, use reasonable default based on the module. 619 dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, dexpreopter)) 620 } 621} 622 623func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { 624 j.sdkVersion = j.SdkVersion(ctx) 625 j.minSdkVersion = j.MinSdkVersion(ctx) 626 j.maxSdkVersion = j.MaxSdkVersion(ctx) 627 628 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 629 if !apexInfo.IsForPlatform() { 630 j.hideApexVariantFromMake = true 631 } 632 633 j.checkSdkVersions(ctx) 634 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 635 ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) 636 j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary 637 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 638 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 639 j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx) 640 j.compile(ctx, nil) 641 642 // Collect the module directory for IDE info in java/jdeps.go. 643 j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) 644 645 exclusivelyForApex := !apexInfo.IsForPlatform() 646 if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex { 647 var extraInstallDeps android.Paths 648 if j.InstallMixin != nil { 649 extraInstallDeps = j.InstallMixin(ctx, j.outputFile) 650 } 651 hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host() 652 if hostDexNeeded { 653 j.hostdexInstallFile = ctx.InstallFile( 654 android.PathForHostDexInstall(ctx, "framework"), 655 j.Stem()+"-hostdex.jar", j.outputFile) 656 } 657 var installDir android.InstallPath 658 if ctx.InstallInTestcases() { 659 var archDir string 660 if !ctx.Host() { 661 archDir = ctx.DeviceConfig().DeviceArch() 662 } 663 installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) 664 } else { 665 installDir = android.PathForModuleInstall(ctx, "framework") 666 } 667 j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) 668 } 669} 670 671func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { 672 j.deps(ctx) 673 j.usesLibrary.deps(ctx, false) 674} 675 676const ( 677 aidlIncludeDir = "aidl" 678 javaDir = "java" 679 jarFileSuffix = ".jar" 680 testConfigSuffix = "-AndroidTest.xml" 681) 682 683// path to the jar file of a java library. Relative to <sdk_root>/<api_dir> 684func sdkSnapshotFilePathForJar(_ android.SdkMemberContext, osPrefix, name string) string { 685 return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix) 686} 687 688func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string { 689 return filepath.Join(javaDir, osPrefix, name+suffix) 690} 691 692type librarySdkMemberType struct { 693 android.SdkMemberTypeBase 694 695 // Function to retrieve the appropriate output jar (implementation or header) from 696 // the library. 697 jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path 698 699 // Function to compute the snapshot relative path to which the named library's 700 // jar should be copied. 701 snapshotPathGetter func(ctx android.SdkMemberContext, osPrefix, name string) string 702 703 // True if only the jar should be copied to the snapshot, false if the jar plus any additional 704 // files like aidl files should also be copied. 705 onlyCopyJarToSnapshot bool 706} 707 708const ( 709 onlyCopyJarToSnapshot = true 710 copyEverythingToSnapshot = false 711) 712 713func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { 714 ctx.AddVariationDependencies(nil, dependencyTag, names...) 715} 716 717func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { 718 _, ok := module.(*Library) 719 return ok 720} 721 722func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 723 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import") 724} 725 726func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 727 return &librarySdkMemberProperties{} 728} 729 730type librarySdkMemberProperties struct { 731 android.SdkMemberPropertiesBase 732 733 JarToExport android.Path `android:"arch_variant"` 734 AidlIncludeDirs android.Paths 735 736 // The list of permitted packages that need to be passed to the prebuilts as they are used to 737 // create the updatable-bcp-packages.txt file. 738 PermittedPackages []string 739} 740 741func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 742 j := variant.(*Library) 743 744 p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) 745 746 p.AidlIncludeDirs = j.AidlIncludeDirs() 747 748 p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars() 749} 750 751func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 752 builder := ctx.SnapshotBuilder() 753 754 memberType := ctx.MemberType().(*librarySdkMemberType) 755 756 exportedJar := p.JarToExport 757 if exportedJar != nil { 758 // Delegate the creation of the snapshot relative path to the member type. 759 snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(ctx, p.OsPrefix(), ctx.Name()) 760 761 // Copy the exported jar to the snapshot. 762 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 763 764 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 765 } 766 767 if len(p.PermittedPackages) > 0 { 768 propertySet.AddProperty("permitted_packages", p.PermittedPackages) 769 } 770 771 // Do not copy anything else to the snapshot. 772 if memberType.onlyCopyJarToSnapshot { 773 return 774 } 775 776 aidlIncludeDirs := p.AidlIncludeDirs 777 if len(aidlIncludeDirs) != 0 { 778 sdkModuleContext := ctx.SdkModuleContext() 779 for _, dir := range aidlIncludeDirs { 780 // TODO(jiyong): copy parcelable declarations only 781 aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil) 782 for _, file := range aidlFiles { 783 builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file)) 784 } 785 } 786 787 // TODO(b/151933053) - add aidl include dirs property 788 } 789} 790 791// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well. 792// 793// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were 794// compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used 795// as a `static_libs` dependency of another module. 796// 797// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on 798// a device. 799// 800// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 801// compiled against the host bootclasspath. 802func LibraryFactory() android.Module { 803 module := &Library{} 804 805 module.addHostAndDeviceProperties() 806 807 module.initModuleAndImport(module) 808 809 android.InitApexModule(module) 810 android.InitSdkAwareModule(module) 811 android.InitBazelModule(module) 812 InitJavaModule(module, android.HostAndDeviceSupported) 813 return module 814} 815 816// java_library_static is an obsolete alias for java_library. 817func LibraryStaticFactory() android.Module { 818 return LibraryFactory() 819} 820 821// java_library_host builds and links sources into a `.jar` file for the host. 822// 823// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were 824// compiled against the host bootclasspath. 825func LibraryHostFactory() android.Module { 826 module := &Library{} 827 828 module.addHostProperties() 829 830 module.Module.properties.Installable = proptools.BoolPtr(true) 831 832 android.InitApexModule(module) 833 android.InitSdkAwareModule(module) 834 android.InitBazelModule(module) 835 InitJavaModule(module, android.HostSupported) 836 return module 837} 838 839// 840// Java Tests 841// 842 843// Test option struct. 844type TestOptions struct { 845 // a list of extra test configuration files that should be installed with the module. 846 Extra_test_configs []string `android:"path,arch_variant"` 847 848 // If the test is a hostside(no device required) unittest that shall be run during presubmit check. 849 Unit_test *bool 850} 851 852type testProperties struct { 853 // list of compatibility suites (for example "cts", "vts") that the module should be 854 // installed into. 855 Test_suites []string `android:"arch_variant"` 856 857 // the name of the test configuration (for example "AndroidTest.xml") that should be 858 // installed with the module. 859 Test_config *string `android:"path,arch_variant"` 860 861 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 862 // should be installed with the module. 863 Test_config_template *string `android:"path,arch_variant"` 864 865 // list of files or filegroup modules that provide data that should be installed alongside 866 // the test 867 Data []string `android:"path"` 868 869 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 870 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 871 // explicitly. 872 Auto_gen_config *bool 873 874 // Add parameterized mainline modules to auto generated test config. The options will be 875 // handled by TradeFed to do downloading and installing the specified modules on the device. 876 Test_mainline_modules []string 877 878 // Test options. 879 Test_options TestOptions 880 881 // Names of modules containing JNI libraries that should be installed alongside the test. 882 Jni_libs []string 883 884 // Install the test into a folder named for the module in all test suites. 885 Per_testcase_directory *bool 886} 887 888type hostTestProperties struct { 889 // list of native binary modules that should be installed alongside the test 890 Data_native_bins []string `android:"arch_variant"` 891 892 // list of device binary modules that should be installed alongside the test 893 // This property only adds the first variant of the dependency 894 Data_device_bins_first []string `android:"arch_variant"` 895 896 // list of device binary modules that should be installed alongside the test 897 // This property adds 64bit AND 32bit variants of the dependency 898 Data_device_bins_both []string `android:"arch_variant"` 899 900 // list of device binary modules that should be installed alongside the test 901 // This property only adds 64bit variants of the dependency 902 Data_device_bins_64 []string `android:"arch_variant"` 903 904 // list of device binary modules that should be installed alongside the test 905 // This property adds 32bit variants of the dependency if available, or else 906 // defaults to the 64bit variant 907 Data_device_bins_prefer32 []string `android:"arch_variant"` 908 909 // list of device binary modules that should be installed alongside the test 910 // This property only adds 32bit variants of the dependency 911 Data_device_bins_32 []string `android:"arch_variant"` 912} 913 914type testHelperLibraryProperties struct { 915 // list of compatibility suites (for example "cts", "vts") that the module should be 916 // installed into. 917 Test_suites []string `android:"arch_variant"` 918 919 // Install the test into a folder named for the module in all test suites. 920 Per_testcase_directory *bool 921} 922 923type prebuiltTestProperties struct { 924 // list of compatibility suites (for example "cts", "vts") that the module should be 925 // installed into. 926 Test_suites []string `android:"arch_variant"` 927 928 // the name of the test configuration (for example "AndroidTest.xml") that should be 929 // installed with the module. 930 Test_config *string `android:"path,arch_variant"` 931} 932 933type Test struct { 934 Library 935 936 testProperties testProperties 937 938 testConfig android.Path 939 extraTestConfigs android.Paths 940 data android.Paths 941} 942 943type TestHost struct { 944 Test 945 946 testHostProperties hostTestProperties 947} 948 949type TestHelperLibrary struct { 950 Library 951 952 testHelperLibraryProperties testHelperLibraryProperties 953} 954 955type JavaTestImport struct { 956 Import 957 958 prebuiltTestProperties prebuiltTestProperties 959 960 testConfig android.Path 961 dexJarFile android.Path 962} 963 964func (j *Test) InstallInTestcases() bool { 965 // Host java tests install into $(HOST_OUT_JAVA_LIBRARIES), and then are copied into 966 // testcases by base_rules.mk. 967 return !j.Host() 968} 969 970func (j *TestHelperLibrary) InstallInTestcases() bool { 971 return true 972} 973 974func (j *JavaTestImport) InstallInTestcases() bool { 975 return true 976} 977 978func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) { 979 if len(j.testHostProperties.Data_device_bins_first) > 0 { 980 deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() 981 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_first...) 982 } 983 984 var maybeAndroid32Target *android.Target 985 var maybeAndroid64Target *android.Target 986 android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32") 987 android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64") 988 if len(android32TargetList) > 0 { 989 maybeAndroid32Target = &android32TargetList[0] 990 } 991 if len(android64TargetList) > 0 { 992 maybeAndroid64Target = &android64TargetList[0] 993 } 994 995 if len(j.testHostProperties.Data_device_bins_both) > 0 { 996 if maybeAndroid32Target == nil && maybeAndroid64Target == nil { 997 ctx.PropertyErrorf("data_device_bins_both", "no device targets available. Targets: %q", ctx.Config().Targets) 998 return 999 } 1000 if maybeAndroid32Target != nil { 1001 ctx.AddFarVariationDependencies( 1002 maybeAndroid32Target.Variations(), 1003 dataDeviceBinsTag, 1004 j.testHostProperties.Data_device_bins_both..., 1005 ) 1006 } 1007 if maybeAndroid64Target != nil { 1008 ctx.AddFarVariationDependencies( 1009 maybeAndroid64Target.Variations(), 1010 dataDeviceBinsTag, 1011 j.testHostProperties.Data_device_bins_both..., 1012 ) 1013 } 1014 } 1015 1016 if len(j.testHostProperties.Data_device_bins_prefer32) > 0 { 1017 if maybeAndroid32Target != nil { 1018 ctx.AddFarVariationDependencies( 1019 maybeAndroid32Target.Variations(), 1020 dataDeviceBinsTag, 1021 j.testHostProperties.Data_device_bins_prefer32..., 1022 ) 1023 } else { 1024 if maybeAndroid64Target == nil { 1025 ctx.PropertyErrorf("data_device_bins_prefer32", "no device targets available. Targets: %q", ctx.Config().Targets) 1026 return 1027 } 1028 ctx.AddFarVariationDependencies( 1029 maybeAndroid64Target.Variations(), 1030 dataDeviceBinsTag, 1031 j.testHostProperties.Data_device_bins_prefer32..., 1032 ) 1033 } 1034 } 1035 1036 if len(j.testHostProperties.Data_device_bins_32) > 0 { 1037 if maybeAndroid32Target == nil { 1038 ctx.PropertyErrorf("data_device_bins_32", "cannot find 32bit device target. Targets: %q", ctx.Config().Targets) 1039 return 1040 } 1041 deviceVariations := maybeAndroid32Target.Variations() 1042 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_32...) 1043 } 1044 1045 if len(j.testHostProperties.Data_device_bins_64) > 0 { 1046 if maybeAndroid64Target == nil { 1047 ctx.PropertyErrorf("data_device_bins_64", "cannot find 64bit device target. Targets: %q", ctx.Config().Targets) 1048 return 1049 } 1050 deviceVariations := maybeAndroid64Target.Variations() 1051 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_64...) 1052 } 1053} 1054 1055func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { 1056 if len(j.testHostProperties.Data_native_bins) > 0 { 1057 for _, target := range ctx.MultiTargets() { 1058 ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...) 1059 } 1060 } 1061 1062 if len(j.testProperties.Jni_libs) > 0 { 1063 for _, target := range ctx.MultiTargets() { 1064 sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) 1065 ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...) 1066 } 1067 } 1068 1069 j.addDataDeviceBinsDeps(ctx) 1070 1071 j.deps(ctx) 1072} 1073 1074func (j *TestHost) AddExtraResource(p android.Path) { 1075 j.extraResources = append(j.extraResources, p) 1076} 1077 1078func (j *TestHost) dataDeviceBins() []string { 1079 ret := make([]string, 0, 1080 len(j.testHostProperties.Data_device_bins_first)+ 1081 len(j.testHostProperties.Data_device_bins_both)+ 1082 len(j.testHostProperties.Data_device_bins_prefer32)+ 1083 len(j.testHostProperties.Data_device_bins_32)+ 1084 len(j.testHostProperties.Data_device_bins_64), 1085 ) 1086 1087 ret = append(ret, j.testHostProperties.Data_device_bins_first...) 1088 ret = append(ret, j.testHostProperties.Data_device_bins_both...) 1089 ret = append(ret, j.testHostProperties.Data_device_bins_prefer32...) 1090 ret = append(ret, j.testHostProperties.Data_device_bins_32...) 1091 ret = append(ret, j.testHostProperties.Data_device_bins_64...) 1092 1093 return ret 1094} 1095 1096func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1097 var configs []tradefed.Config 1098 dataDeviceBins := j.dataDeviceBins() 1099 if len(dataDeviceBins) > 0 { 1100 // add Tradefed configuration to push device bins to device for testing 1101 remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name()) 1102 options := []tradefed.Option{{Name: "cleanup", Value: "true"}} 1103 for _, bin := range dataDeviceBins { 1104 fullPath := filepath.Join(remoteDir, bin) 1105 options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath}) 1106 } 1107 configs = append(configs, tradefed.Object{ 1108 Type: "target_preparer", 1109 Class: "com.android.tradefed.targetprep.PushFilePreparer", 1110 Options: options, 1111 }) 1112 } 1113 1114 j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) 1115} 1116 1117func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1118 j.generateAndroidBuildActionsWithConfig(ctx, nil) 1119} 1120 1121func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { 1122 if j.testProperties.Test_options.Unit_test == nil && ctx.Host() { 1123 // TODO(b/): Clean temporary heuristic to avoid unexpected onboarding. 1124 defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites) 1125 j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest) 1126 } 1127 1128 j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, 1129 j.testProperties.Test_suites, configs, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test) 1130 1131 j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data) 1132 1133 j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs) 1134 1135 ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) { 1136 j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) 1137 }) 1138 1139 ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) { 1140 j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) 1141 }) 1142 1143 ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) { 1144 sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo) 1145 if sharedLibInfo.SharedLibrary != nil { 1146 // Copy to an intermediate output directory to append "lib[64]" to the path, 1147 // so that it's compatible with the default rpath values. 1148 var relPath string 1149 if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" { 1150 relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base()) 1151 } else { 1152 relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base()) 1153 } 1154 relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath) 1155 ctx.Build(pctx, android.BuildParams{ 1156 Rule: android.Cp, 1157 Input: sharedLibInfo.SharedLibrary, 1158 Output: relocatedLib, 1159 }) 1160 j.data = append(j.data, relocatedLib) 1161 } else { 1162 ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep)) 1163 } 1164 }) 1165 1166 j.Library.GenerateAndroidBuildActions(ctx) 1167} 1168 1169func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1170 j.Library.GenerateAndroidBuildActions(ctx) 1171} 1172 1173func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1174 j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil, 1175 j.prebuiltTestProperties.Test_suites, nil, nil, nil) 1176 1177 j.Import.GenerateAndroidBuildActions(ctx) 1178} 1179 1180type testSdkMemberType struct { 1181 android.SdkMemberTypeBase 1182} 1183 1184func (mt *testSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { 1185 ctx.AddVariationDependencies(nil, dependencyTag, names...) 1186} 1187 1188func (mt *testSdkMemberType) IsInstance(module android.Module) bool { 1189 _, ok := module.(*Test) 1190 return ok 1191} 1192 1193func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 1194 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import") 1195} 1196 1197func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 1198 return &testSdkMemberProperties{} 1199} 1200 1201type testSdkMemberProperties struct { 1202 android.SdkMemberPropertiesBase 1203 1204 JarToExport android.Path 1205 TestConfig android.Path 1206} 1207 1208func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 1209 test := variant.(*Test) 1210 1211 implementationJars := test.ImplementationJars() 1212 if len(implementationJars) != 1 { 1213 panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name())) 1214 } 1215 1216 p.JarToExport = implementationJars[0] 1217 p.TestConfig = test.testConfig 1218} 1219 1220func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 1221 builder := ctx.SnapshotBuilder() 1222 1223 exportedJar := p.JarToExport 1224 if exportedJar != nil { 1225 snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(ctx, p.OsPrefix(), ctx.Name()) 1226 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 1227 1228 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 1229 } 1230 1231 testConfig := p.TestConfig 1232 if testConfig != nil { 1233 snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix) 1234 builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath) 1235 propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath) 1236 } 1237} 1238 1239// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and 1240// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file. 1241// 1242// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were 1243// compiled against the device bootclasspath. 1244// 1245// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 1246// compiled against the host bootclasspath. 1247func TestFactory() android.Module { 1248 module := &Test{} 1249 1250 module.addHostAndDeviceProperties() 1251 module.AddProperties(&module.testProperties) 1252 1253 module.Module.properties.Installable = proptools.BoolPtr(true) 1254 module.Module.dexpreopter.isTest = true 1255 module.Module.linter.test = true 1256 1257 android.InitSdkAwareModule(module) 1258 InitJavaModule(module, android.HostAndDeviceSupported) 1259 return module 1260} 1261 1262// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite. 1263func TestHelperLibraryFactory() android.Module { 1264 module := &TestHelperLibrary{} 1265 1266 module.addHostAndDeviceProperties() 1267 module.AddProperties(&module.testHelperLibraryProperties) 1268 1269 module.Module.properties.Installable = proptools.BoolPtr(true) 1270 module.Module.dexpreopter.isTest = true 1271 module.Module.linter.test = true 1272 1273 InitJavaModule(module, android.HostAndDeviceSupported) 1274 return module 1275} 1276 1277// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module 1278// and makes sure that it is added to the appropriate test suite. 1279// 1280// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were 1281// compiled against an Android classpath. 1282// 1283// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 1284// for host modules. 1285func JavaTestImportFactory() android.Module { 1286 module := &JavaTestImport{} 1287 1288 module.AddProperties( 1289 &module.Import.properties, 1290 &module.prebuiltTestProperties) 1291 1292 module.Import.properties.Installable = proptools.BoolPtr(true) 1293 1294 android.InitPrebuiltModule(module, &module.properties.Jars) 1295 android.InitApexModule(module) 1296 android.InitSdkAwareModule(module) 1297 InitJavaModule(module, android.HostAndDeviceSupported) 1298 return module 1299} 1300 1301// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to 1302// allow running the test with `atest` or a `TEST_MAPPING` file. 1303// 1304// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were 1305// compiled against the host bootclasspath. 1306func TestHostFactory() android.Module { 1307 module := &TestHost{} 1308 1309 module.addHostProperties() 1310 module.AddProperties(&module.testProperties) 1311 module.AddProperties(&module.testHostProperties) 1312 1313 InitTestHost( 1314 module, 1315 proptools.BoolPtr(true), 1316 nil, 1317 nil) 1318 1319 InitJavaModuleMultiTargets(module, android.HostSupported) 1320 1321 return module 1322} 1323 1324func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenConfig *bool) { 1325 th.properties.Installable = installable 1326 th.testProperties.Auto_gen_config = autoGenConfig 1327 th.testProperties.Test_suites = testSuites 1328} 1329 1330// 1331// Java Binaries (.jar file plus wrapper script) 1332// 1333 1334type binaryProperties struct { 1335 // installable script to execute the resulting jar 1336 Wrapper *string `android:"path,arch_variant"` 1337 1338 // Name of the class containing main to be inserted into the manifest as Main-Class. 1339 Main_class *string 1340 1341 // Names of modules containing JNI libraries that should be installed alongside the host 1342 // variant of the binary. 1343 Jni_libs []string `android:"arch_variant"` 1344} 1345 1346type Binary struct { 1347 Library 1348 1349 binaryProperties binaryProperties 1350 1351 isWrapperVariant bool 1352 1353 wrapperFile android.Path 1354 binaryFile android.InstallPath 1355} 1356 1357func (j *Binary) HostToolPath() android.OptionalPath { 1358 return android.OptionalPathForPath(j.binaryFile) 1359} 1360 1361func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1362 if ctx.Arch().ArchType == android.Common { 1363 // Compile the jar 1364 if j.binaryProperties.Main_class != nil { 1365 if j.properties.Manifest != nil { 1366 ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set") 1367 } 1368 manifestFile := android.PathForModuleOut(ctx, "manifest.txt") 1369 GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class)) 1370 j.overrideManifest = android.OptionalPathForPath(manifestFile) 1371 } 1372 1373 j.Library.GenerateAndroidBuildActions(ctx) 1374 } else { 1375 // Handle the binary wrapper 1376 j.isWrapperVariant = true 1377 1378 if j.binaryProperties.Wrapper != nil { 1379 j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper) 1380 } else { 1381 if ctx.Windows() { 1382 ctx.PropertyErrorf("wrapper", "wrapper is required for Windows") 1383 } 1384 1385 j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") 1386 } 1387 1388 ext := "" 1389 if ctx.Windows() { 1390 ext = ".bat" 1391 } 1392 1393 // The host installation rules make the installed wrapper depend on all the dependencies 1394 // of the wrapper variant, which will include the common variant's jar file and any JNI 1395 // libraries. This is verified by TestBinary. 1396 j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), 1397 ctx.ModuleName()+ext, j.wrapperFile) 1398 } 1399} 1400 1401func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { 1402 if ctx.Arch().ArchType == android.Common || ctx.BazelConversionMode() { 1403 j.deps(ctx) 1404 } 1405 if ctx.Arch().ArchType != android.Common || ctx.BazelConversionMode() { 1406 // These dependencies ensure the host installation rules will install the jar file and 1407 // the jni libraries when the wrapper is installed. 1408 ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) 1409 ctx.AddVariationDependencies( 1410 []blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}}, 1411 binaryInstallTag, ctx.ModuleName()) 1412 } 1413} 1414 1415// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host 1416// as well. 1417// 1418// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were 1419// compiled against the device bootclasspath. 1420// 1421// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 1422// compiled against the host bootclasspath. 1423func BinaryFactory() android.Module { 1424 module := &Binary{} 1425 1426 module.addHostAndDeviceProperties() 1427 module.AddProperties(&module.binaryProperties) 1428 1429 module.Module.properties.Installable = proptools.BoolPtr(true) 1430 1431 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) 1432 android.InitDefaultableModule(module) 1433 android.InitBazelModule(module) 1434 1435 return module 1436} 1437 1438// java_binary_host builds a `.jar` file and a shell script that executes it for the host. 1439// 1440// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were 1441// compiled against the host bootclasspath. 1442func BinaryHostFactory() android.Module { 1443 module := &Binary{} 1444 1445 module.addHostProperties() 1446 module.AddProperties(&module.binaryProperties) 1447 1448 module.Module.properties.Installable = proptools.BoolPtr(true) 1449 1450 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) 1451 android.InitDefaultableModule(module) 1452 android.InitBazelModule(module) 1453 return module 1454} 1455 1456// 1457// Java prebuilts 1458// 1459 1460type ImportProperties struct { 1461 Jars []string `android:"path,arch_variant"` 1462 1463 // The version of the SDK that the source prebuilt file was built against. Defaults to the 1464 // current version if not specified. 1465 Sdk_version *string 1466 1467 // The minimum version of the SDK that this module supports. Defaults to sdk_version if not 1468 // specified. 1469 Min_sdk_version *string 1470 1471 Installable *bool 1472 1473 // If not empty, classes are restricted to the specified packages and their sub-packages. 1474 Permitted_packages []string 1475 1476 // List of shared java libs that this module has dependencies to 1477 Libs []string 1478 1479 // List of files to remove from the jar file(s) 1480 Exclude_files []string 1481 1482 // List of directories to remove from the jar file(s) 1483 Exclude_dirs []string 1484 1485 // if set to true, run Jetifier against .jar file. Defaults to false. 1486 Jetifier *bool 1487 1488 // set the name of the output 1489 Stem *string 1490 1491 Aidl struct { 1492 // directories that should be added as include directories for any aidl sources of modules 1493 // that depend on this module, as well as to aidl for this module. 1494 Export_include_dirs []string 1495 } 1496} 1497 1498type Import struct { 1499 android.ModuleBase 1500 android.DefaultableModuleBase 1501 android.ApexModuleBase 1502 android.BazelModuleBase 1503 prebuilt android.Prebuilt 1504 android.SdkBase 1505 1506 // Functionality common to Module and Import. 1507 embeddableInModuleAndImport 1508 1509 hiddenAPI 1510 dexer 1511 dexpreopter 1512 1513 properties ImportProperties 1514 1515 // output file containing classes.dex and resources 1516 dexJarFile OptionalDexJarPath 1517 dexJarInstallFile android.Path 1518 1519 combinedClasspathFile android.Path 1520 classLoaderContexts dexpreopt.ClassLoaderContextMap 1521 exportAidlIncludeDirs android.Paths 1522 1523 hideApexVariantFromMake bool 1524 1525 sdkVersion android.SdkSpec 1526 minSdkVersion android.SdkSpec 1527} 1528 1529var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil) 1530 1531func (j *Import) PermittedPackagesForUpdatableBootJars() []string { 1532 return j.properties.Permitted_packages 1533} 1534 1535func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 1536 return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version)) 1537} 1538 1539func (j *Import) SystemModules() string { 1540 return "none" 1541} 1542 1543func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 1544 if j.properties.Min_sdk_version != nil { 1545 return android.SdkSpecFrom(ctx, *j.properties.Min_sdk_version) 1546 } 1547 return j.SdkVersion(ctx) 1548} 1549 1550func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 1551 return j.SdkVersion(ctx) 1552} 1553 1554func (j *Import) Prebuilt() *android.Prebuilt { 1555 return &j.prebuilt 1556} 1557 1558func (j *Import) PrebuiltSrcs() []string { 1559 return j.properties.Jars 1560} 1561 1562func (j *Import) Name() string { 1563 return j.prebuilt.Name(j.ModuleBase.Name()) 1564} 1565 1566func (j *Import) Stem() string { 1567 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 1568} 1569 1570func (a *Import) JacocoReportClassesFile() android.Path { 1571 return nil 1572} 1573 1574func (j *Import) LintDepSets() LintDepSets { 1575 return LintDepSets{} 1576} 1577 1578func (j *Import) getStrictUpdatabilityLinting() bool { 1579 return false 1580} 1581 1582func (j *Import) setStrictUpdatabilityLinting(bool) { 1583} 1584 1585func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { 1586 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) 1587 1588 if ctx.Device() && Bool(j.dexProperties.Compile_dex) { 1589 sdkDeps(ctx, android.SdkContext(j), j.dexer) 1590 } 1591} 1592 1593func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1594 j.sdkVersion = j.SdkVersion(ctx) 1595 j.minSdkVersion = j.MinSdkVersion(ctx) 1596 1597 if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() { 1598 j.hideApexVariantFromMake = true 1599 } 1600 1601 if ctx.Windows() { 1602 j.HideFromMake() 1603 } 1604 1605 jars := android.PathsForModuleSrc(ctx, j.properties.Jars) 1606 1607 jarName := j.Stem() + ".jar" 1608 outputFile := android.PathForModuleOut(ctx, "combined", jarName) 1609 TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{}, 1610 false, j.properties.Exclude_files, j.properties.Exclude_dirs) 1611 if Bool(j.properties.Jetifier) { 1612 inputFile := outputFile 1613 outputFile = android.PathForModuleOut(ctx, "jetifier", jarName) 1614 TransformJetifier(ctx, outputFile, inputFile) 1615 } 1616 j.combinedClasspathFile = outputFile 1617 j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) 1618 1619 var flags javaBuilderFlags 1620 1621 ctx.VisitDirectDeps(func(module android.Module) { 1622 tag := ctx.OtherModuleDependencyTag(module) 1623 1624 if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { 1625 dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) 1626 switch tag { 1627 case libTag: 1628 flags.classpath = append(flags.classpath, dep.HeaderJars...) 1629 flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...) 1630 case staticLibTag: 1631 flags.classpath = append(flags.classpath, dep.HeaderJars...) 1632 case bootClasspathTag: 1633 flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...) 1634 } 1635 } else if dep, ok := module.(SdkLibraryDependency); ok { 1636 switch tag { 1637 case libTag: 1638 flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...) 1639 } 1640 } 1641 1642 addCLCFromDep(ctx, module, j.classLoaderContexts) 1643 }) 1644 1645 if Bool(j.properties.Installable) { 1646 var installDir android.InstallPath 1647 if ctx.InstallInTestcases() { 1648 var archDir string 1649 if !ctx.Host() { 1650 archDir = ctx.DeviceConfig().DeviceArch() 1651 } 1652 installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) 1653 } else { 1654 installDir = android.PathForModuleInstall(ctx, "framework") 1655 } 1656 ctx.InstallFile(installDir, jarName, outputFile) 1657 } 1658 1659 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) 1660 1661 if ctx.Device() { 1662 // If this is a variant created for a prebuilt_apex then use the dex implementation jar 1663 // obtained from the associated deapexer module. 1664 ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 1665 if ai.ForPrebuiltApex { 1666 // Get the path of the dex implementation jar from the `deapexer` module. 1667 di := android.FindDeapexerProviderForModule(ctx) 1668 if di == nil { 1669 return // An error has been reported by FindDeapexerProviderForModule. 1670 } 1671 if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil { 1672 dexJarFile := makeDexJarPathFromPath(dexOutputPath) 1673 j.dexJarFile = dexJarFile 1674 installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName())) 1675 j.dexJarInstallFile = installPath 1676 1677 j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath) 1678 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 1679 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 1680 j.dexpreopt(ctx, dexOutputPath) 1681 1682 // Initialize the hiddenapi structure. 1683 j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex) 1684 } else { 1685 // This should never happen as a variant for a prebuilt_apex is only created if the 1686 // prebuilt_apex has been configured to export the java library dex file. 1687 ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName()) 1688 } 1689 } else if Bool(j.dexProperties.Compile_dex) { 1690 sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) 1691 if sdkDep.invalidVersion { 1692 ctx.AddMissingDependencies(sdkDep.bootclasspath) 1693 ctx.AddMissingDependencies(sdkDep.java9Classpath) 1694 } else if sdkDep.useFiles { 1695 // sdkDep.jar is actually equivalent to turbine header.jar. 1696 flags.classpath = append(flags.classpath, sdkDep.jars...) 1697 } 1698 1699 // Dex compilation 1700 1701 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 1702 ctx, android.PathForModuleInstall(ctx, "framework", jarName)) 1703 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 1704 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 1705 1706 var dexOutputFile android.OutputPath 1707 dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), outputFile, jarName) 1708 if ctx.Failed() { 1709 return 1710 } 1711 1712 // Initialize the hiddenapi structure. 1713 j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex) 1714 1715 // Encode hidden API flags in dex file. 1716 dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) 1717 1718 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 1719 j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName) 1720 } 1721 } 1722 1723 ctx.SetProvider(JavaInfoProvider, JavaInfo{ 1724 HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile), 1725 ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), 1726 ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile), 1727 AidlIncludeDirs: j.exportAidlIncludeDirs, 1728 }) 1729} 1730 1731func (j *Import) OutputFiles(tag string) (android.Paths, error) { 1732 switch tag { 1733 case "", ".jar": 1734 return android.Paths{j.combinedClasspathFile}, nil 1735 default: 1736 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 1737 } 1738} 1739 1740var _ android.OutputFileProducer = (*Import)(nil) 1741 1742func (j *Import) HeaderJars() android.Paths { 1743 if j.combinedClasspathFile == nil { 1744 return nil 1745 } 1746 return android.Paths{j.combinedClasspathFile} 1747} 1748 1749func (j *Import) ImplementationAndResourcesJars() android.Paths { 1750 if j.combinedClasspathFile == nil { 1751 return nil 1752 } 1753 return android.Paths{j.combinedClasspathFile} 1754} 1755 1756func (j *Import) DexJarBuildPath() OptionalDexJarPath { 1757 return j.dexJarFile 1758} 1759 1760func (j *Import) DexJarInstallPath() android.Path { 1761 return j.dexJarInstallFile 1762} 1763 1764func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 1765 return j.classLoaderContexts 1766} 1767 1768var _ android.ApexModule = (*Import)(nil) 1769 1770// Implements android.ApexModule 1771func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 1772 return j.depIsInSameApex(ctx, dep) 1773} 1774 1775// Implements android.ApexModule 1776func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 1777 sdkVersion android.ApiLevel) error { 1778 sdkSpec := j.MinSdkVersion(ctx) 1779 if !sdkSpec.Specified() { 1780 return fmt.Errorf("min_sdk_version is not specified") 1781 } 1782 if sdkSpec.Kind == android.SdkCore { 1783 return nil 1784 } 1785 if sdkSpec.ApiLevel.GreaterThan(sdkVersion) { 1786 return fmt.Errorf("newer SDK(%v)", sdkSpec.ApiLevel) 1787 } 1788 return nil 1789} 1790 1791// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or 1792// java_sdk_library_import with the specified base module name requires to be exported from a 1793// prebuilt_apex/apex_set. 1794func requiredFilesFromPrebuiltApexForImport(name string) []string { 1795 // Add the dex implementation jar to the set of exported files. 1796 return []string{ 1797 apexRootRelativePathToJavaLib(name), 1798 } 1799} 1800 1801// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for 1802// the java library with the specified name. 1803func apexRootRelativePathToJavaLib(name string) string { 1804 return filepath.Join("javalib", name+".jar") 1805} 1806 1807var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil) 1808 1809func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string { 1810 name := j.BaseModuleName() 1811 return requiredFilesFromPrebuiltApexForImport(name) 1812} 1813 1814// Add compile time check for interface implementation 1815var _ android.IDEInfo = (*Import)(nil) 1816var _ android.IDECustomizedModuleName = (*Import)(nil) 1817 1818// Collect information for opening IDE project files in java/jdeps.go. 1819 1820func (j *Import) IDEInfo(dpInfo *android.IdeInfo) { 1821 dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...) 1822} 1823 1824func (j *Import) IDECustomizedModuleName() string { 1825 // TODO(b/113562217): Extract the base module name from the Import name, often the Import name 1826 // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better 1827 // solution to get the Import name. 1828 return android.RemoveOptionalPrebuiltPrefix(j.Name()) 1829} 1830 1831var _ android.PrebuiltInterface = (*Import)(nil) 1832 1833func (j *Import) IsInstallable() bool { 1834 return Bool(j.properties.Installable) 1835} 1836 1837var _ DexpreopterInterface = (*Import)(nil) 1838 1839// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module. 1840// 1841// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were 1842// compiled against an Android classpath. 1843// 1844// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 1845// for host modules. 1846func ImportFactory() android.Module { 1847 module := &Import{} 1848 1849 module.AddProperties( 1850 &module.properties, 1851 &module.dexer.dexProperties, 1852 ) 1853 1854 module.initModuleAndImport(module) 1855 1856 module.dexProperties.Optimize.EnabledByDefault = false 1857 1858 android.InitPrebuiltModule(module, &module.properties.Jars) 1859 android.InitApexModule(module) 1860 android.InitSdkAwareModule(module) 1861 android.InitBazelModule(module) 1862 InitJavaModule(module, android.HostAndDeviceSupported) 1863 return module 1864} 1865 1866// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host 1867// module. 1868// 1869// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were 1870// compiled against a host bootclasspath. 1871func ImportFactoryHost() android.Module { 1872 module := &Import{} 1873 1874 module.AddProperties(&module.properties) 1875 1876 android.InitPrebuiltModule(module, &module.properties.Jars) 1877 android.InitApexModule(module) 1878 android.InitBazelModule(module) 1879 InitJavaModule(module, android.HostSupported) 1880 return module 1881} 1882 1883// dex_import module 1884 1885type DexImportProperties struct { 1886 Jars []string `android:"path"` 1887 1888 // set the name of the output 1889 Stem *string 1890} 1891 1892type DexImport struct { 1893 android.ModuleBase 1894 android.DefaultableModuleBase 1895 android.ApexModuleBase 1896 prebuilt android.Prebuilt 1897 1898 properties DexImportProperties 1899 1900 dexJarFile OptionalDexJarPath 1901 1902 dexpreopter 1903 1904 hideApexVariantFromMake bool 1905} 1906 1907func (j *DexImport) Prebuilt() *android.Prebuilt { 1908 return &j.prebuilt 1909} 1910 1911func (j *DexImport) PrebuiltSrcs() []string { 1912 return j.properties.Jars 1913} 1914 1915func (j *DexImport) Name() string { 1916 return j.prebuilt.Name(j.ModuleBase.Name()) 1917} 1918 1919func (j *DexImport) Stem() string { 1920 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 1921} 1922 1923func (a *DexImport) JacocoReportClassesFile() android.Path { 1924 return nil 1925} 1926 1927func (a *DexImport) LintDepSets() LintDepSets { 1928 return LintDepSets{} 1929} 1930 1931func (j *DexImport) IsInstallable() bool { 1932 return true 1933} 1934 1935func (j *DexImport) getStrictUpdatabilityLinting() bool { 1936 return false 1937} 1938 1939func (j *DexImport) setStrictUpdatabilityLinting(bool) { 1940} 1941 1942func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1943 if len(j.properties.Jars) != 1 { 1944 ctx.PropertyErrorf("jars", "exactly one jar must be provided") 1945 } 1946 1947 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 1948 if !apexInfo.IsForPlatform() { 1949 j.hideApexVariantFromMake = true 1950 } 1951 1952 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 1953 ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) 1954 j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) 1955 1956 inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") 1957 dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar") 1958 1959 if j.dexpreopter.uncompressedDex { 1960 rule := android.NewRuleBuilder(pctx, ctx) 1961 1962 temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned") 1963 rule.Temporary(temporary) 1964 1965 // use zip2zip to uncompress classes*.dex files 1966 rule.Command(). 1967 BuiltTool("zip2zip"). 1968 FlagWithInput("-i ", inputJar). 1969 FlagWithOutput("-o ", temporary). 1970 FlagWithArg("-0 ", "'classes*.dex'") 1971 1972 // use zipalign to align uncompressed classes*.dex files 1973 rule.Command(). 1974 BuiltTool("zipalign"). 1975 Flag("-f"). 1976 Text("4"). 1977 Input(temporary). 1978 Output(dexOutputFile) 1979 1980 rule.DeleteTemporaryFiles() 1981 1982 rule.Build("uncompress_dex", "uncompress dex") 1983 } else { 1984 ctx.Build(pctx, android.BuildParams{ 1985 Rule: android.Cp, 1986 Input: inputJar, 1987 Output: dexOutputFile, 1988 }) 1989 } 1990 1991 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 1992 1993 j.dexpreopt(ctx, dexOutputFile) 1994 1995 if apexInfo.IsForPlatform() { 1996 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 1997 j.Stem()+".jar", dexOutputFile) 1998 } 1999} 2000 2001func (j *DexImport) DexJarBuildPath() OptionalDexJarPath { 2002 return j.dexJarFile 2003} 2004 2005var _ android.ApexModule = (*DexImport)(nil) 2006 2007// Implements android.ApexModule 2008func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 2009 sdkVersion android.ApiLevel) error { 2010 // we don't check prebuilt modules for sdk_version 2011 return nil 2012} 2013 2014// dex_import imports a `.jar` file containing classes.dex files. 2015// 2016// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed 2017// to the device. 2018func DexImportFactory() android.Module { 2019 module := &DexImport{} 2020 2021 module.AddProperties(&module.properties) 2022 2023 android.InitPrebuiltModule(module, &module.properties.Jars) 2024 android.InitApexModule(module) 2025 InitJavaModule(module, android.DeviceSupported) 2026 return module 2027} 2028 2029// 2030// Defaults 2031// 2032type Defaults struct { 2033 android.ModuleBase 2034 android.DefaultsModuleBase 2035 android.ApexModuleBase 2036} 2037 2038// java_defaults provides a set of properties that can be inherited by other java or android modules. 2039// 2040// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`. Each 2041// property in the defaults module that exists in the depending module will be prepended to the depending module's 2042// value for that property. 2043// 2044// Example: 2045// 2046// java_defaults { 2047// name: "example_defaults", 2048// srcs: ["common/**/*.java"], 2049// javacflags: ["-Xlint:all"], 2050// aaptflags: ["--auto-add-overlay"], 2051// } 2052// 2053// java_library { 2054// name: "example", 2055// defaults: ["example_defaults"], 2056// srcs: ["example/**/*.java"], 2057// } 2058// 2059// is functionally identical to: 2060// 2061// java_library { 2062// name: "example", 2063// srcs: [ 2064// "common/**/*.java", 2065// "example/**/*.java", 2066// ], 2067// javacflags: ["-Xlint:all"], 2068// } 2069func DefaultsFactory() android.Module { 2070 module := &Defaults{} 2071 2072 module.AddProperties( 2073 &CommonProperties{}, 2074 &DeviceProperties{}, 2075 &OverridableDeviceProperties{}, 2076 &DexProperties{}, 2077 &DexpreoptProperties{}, 2078 &android.ProtoProperties{}, 2079 &aaptProperties{}, 2080 &androidLibraryProperties{}, 2081 &appProperties{}, 2082 &appTestProperties{}, 2083 &overridableAppProperties{}, 2084 &testProperties{}, 2085 &ImportProperties{}, 2086 &AARImportProperties{}, 2087 &sdkLibraryProperties{}, 2088 &commonToSdkLibraryAndImportProperties{}, 2089 &DexImportProperties{}, 2090 &android.ApexProperties{}, 2091 &RuntimeResourceOverlayProperties{}, 2092 &LintProperties{}, 2093 &appTestHelperAppProperties{}, 2094 ) 2095 2096 android.InitDefaultsModule(module) 2097 return module 2098} 2099 2100func kytheExtractJavaFactory() android.Singleton { 2101 return &kytheExtractJavaSingleton{} 2102} 2103 2104type kytheExtractJavaSingleton struct { 2105} 2106 2107func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) { 2108 var xrefTargets android.Paths 2109 ctx.VisitAllModules(func(module android.Module) { 2110 if javaModule, ok := module.(xref); ok { 2111 xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...) 2112 } 2113 }) 2114 // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets 2115 if len(xrefTargets) > 0 { 2116 ctx.Phony("xref_java", xrefTargets...) 2117 } 2118} 2119 2120var Bool = proptools.Bool 2121var BoolDefault = proptools.BoolDefault 2122var String = proptools.String 2123var inList = android.InList 2124 2125// Add class loader context (CLC) of a given dependency to the current CLC. 2126func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, 2127 clcMap dexpreopt.ClassLoaderContextMap) { 2128 2129 dep, ok := depModule.(UsesLibraryDependency) 2130 if !ok { 2131 return 2132 } 2133 2134 depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule)) 2135 2136 var sdkLib *string 2137 if lib, ok := depModule.(SdkLibraryDependency); ok && lib.sharedLibrary() { 2138 // A shared SDK library. This should be added as a top-level CLC element. 2139 sdkLib = &depName 2140 } else if ulib, ok := depModule.(ProvidesUsesLib); ok { 2141 // A non-SDK library disguised as an SDK library by the means of `provides_uses_lib` 2142 // property. This should be handled in the same way as a shared SDK library. 2143 sdkLib = ulib.ProvidesUsesLib() 2144 } 2145 2146 depTag := ctx.OtherModuleDependencyTag(depModule) 2147 if depTag == libTag { 2148 // Ok, propagate <uses-library> through non-static library dependencies. 2149 } else if tag, ok := depTag.(usesLibraryDependencyTag); ok && 2150 tag.sdkVersion == dexpreopt.AnySdkVersion && tag.implicit { 2151 // Ok, propagate <uses-library> through non-compatibility implicit <uses-library> 2152 // dependencies. 2153 } else if depTag == staticLibTag { 2154 // Propagate <uses-library> through static library dependencies, unless it is a component 2155 // library (such as stubs). Component libraries have a dependency on their SDK library, 2156 // which should not be pulled just because of a static component library. 2157 if sdkLib != nil { 2158 return 2159 } 2160 } else { 2161 // Don't propagate <uses-library> for other dependency tags. 2162 return 2163 } 2164 2165 // If this is an SDK (or SDK-like) library, then it should be added as a node in the CLC tree, 2166 // and its CLC should be added as subtree of that node. Otherwise the library is not a 2167 // <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies 2168 // from its CLC should be added to the current CLC. 2169 if sdkLib != nil { 2170 clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true, 2171 dep.DexJarBuildPath().PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) 2172 } else { 2173 clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) 2174 } 2175} 2176 2177type javaCommonAttributes struct { 2178 Srcs bazel.LabelListAttribute 2179 Plugins bazel.LabelListAttribute 2180 Javacopts bazel.StringListAttribute 2181} 2182 2183type javaDependencyLabels struct { 2184 // Dependencies which DO NOT contribute to the API visible to upstream dependencies. 2185 Deps bazel.LabelListAttribute 2186 // Dependencies which DO contribute to the API visible to upstream dependencies. 2187 StaticDeps bazel.LabelListAttribute 2188} 2189 2190// convertLibraryAttrsBp2Build converts a few shared attributes from java_* modules 2191// and also separates dependencies into dynamic dependencies and static dependencies. 2192// Each corresponding Bazel target type, can have a different method for handling 2193// dynamic vs. static dependencies, and so these are returned to the calling function. 2194type eventLogTagsAttributes struct { 2195 Srcs bazel.LabelListAttribute 2196} 2197 2198func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *javaDependencyLabels) { 2199 var srcs bazel.LabelListAttribute 2200 archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{}) 2201 for axis, configToProps := range archVariantProps { 2202 for config, _props := range configToProps { 2203 if archProps, ok := _props.(*CommonProperties); ok { 2204 archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs) 2205 srcs.SetSelectValue(axis, config, archSrcs) 2206 } 2207 } 2208 } 2209 2210 javaSrcPartition := "java" 2211 protoSrcPartition := "proto" 2212 logtagSrcPartition := "logtag" 2213 srcPartitions := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{ 2214 javaSrcPartition: bazel.LabelPartition{Extensions: []string{".java"}, Keep_remainder: true}, 2215 logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}}, 2216 protoSrcPartition: android.ProtoSrcLabelPartition, 2217 }) 2218 2219 javaSrcs := srcPartitions[javaSrcPartition] 2220 2221 var logtagsSrcs bazel.LabelList 2222 if !srcPartitions[logtagSrcPartition].IsEmpty() { 2223 logtagsLibName := m.Name() + "_logtags" 2224 logtagsSrcs = bazel.MakeLabelList([]bazel.Label{{Label: ":" + logtagsLibName}}) 2225 ctx.CreateBazelTargetModule( 2226 bazel.BazelTargetModuleProperties{ 2227 Rule_class: "event_log_tags", 2228 Bzl_load_location: "//build/make/tools:event_log_tags.bzl", 2229 }, 2230 android.CommonAttributes{Name: logtagsLibName}, 2231 &eventLogTagsAttributes{ 2232 Srcs: srcPartitions[logtagSrcPartition], 2233 }, 2234 ) 2235 } 2236 javaSrcs.Append(bazel.MakeLabelListAttribute(logtagsSrcs)) 2237 2238 var javacopts []string 2239 if m.properties.Javacflags != nil { 2240 javacopts = append(javacopts, m.properties.Javacflags...) 2241 } 2242 epEnabled := m.properties.Errorprone.Enabled 2243 //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable 2244 if Bool(epEnabled) { 2245 javacopts = append(javacopts, m.properties.Errorprone.Javacflags...) 2246 } 2247 2248 commonAttrs := &javaCommonAttributes{ 2249 Srcs: javaSrcs, 2250 Plugins: bazel.MakeLabelListAttribute( 2251 android.BazelLabelForModuleDeps(ctx, m.properties.Plugins), 2252 ), 2253 Javacopts: bazel.MakeStringListAttribute(javacopts), 2254 } 2255 2256 depLabels := &javaDependencyLabels{} 2257 2258 var deps bazel.LabelList 2259 if m.properties.Libs != nil { 2260 deps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Libs)) 2261 } 2262 2263 var staticDeps bazel.LabelList 2264 if m.properties.Static_libs != nil { 2265 staticDeps.Append(android.BazelLabelForModuleDeps(ctx, m.properties.Static_libs)) 2266 } 2267 2268 protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition]) 2269 // Soong does not differentiate between a java_library and the Bazel equivalent of 2270 // a java_proto_library + proto_library pair. Instead, in Soong proto sources are 2271 // listed directly in the srcs of a java_library, and the classes produced 2272 // by protoc are included directly in the resulting JAR. Thus upstream dependencies 2273 // that depend on a java_library with proto sources can link directly to the protobuf API, 2274 // and so this should be a static dependency. 2275 staticDeps.Add(protoDepLabel) 2276 2277 depLabels.Deps = bazel.MakeLabelListAttribute(deps) 2278 depLabels.StaticDeps = bazel.MakeLabelListAttribute(staticDeps) 2279 2280 return commonAttrs, depLabels 2281} 2282 2283type javaLibraryAttributes struct { 2284 *javaCommonAttributes 2285 Deps bazel.LabelListAttribute 2286 Exports bazel.LabelListAttribute 2287} 2288 2289func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { 2290 commonAttrs, depLabels := m.convertLibraryAttrsBp2Build(ctx) 2291 2292 deps := depLabels.Deps 2293 if !commonAttrs.Srcs.IsEmpty() { 2294 deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them 2295 2296 sdkVersion := m.SdkVersion(ctx) 2297 if sdkVersion.Kind == android.SdkPublic && sdkVersion.ApiLevel == android.FutureApiLevel { 2298 // TODO(b/220869005) remove forced dependency on current public android.jar 2299 deps.Add(bazel.MakeLabelAttribute("//prebuilts/sdk:public_current_android_sdk_java_import")) 2300 } 2301 } else if !depLabels.Deps.IsEmpty() { 2302 ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") 2303 } 2304 2305 attrs := &javaLibraryAttributes{ 2306 javaCommonAttributes: commonAttrs, 2307 Deps: deps, 2308 Exports: depLabels.StaticDeps, 2309 } 2310 2311 props := bazel.BazelTargetModuleProperties{ 2312 Rule_class: "java_library", 2313 Bzl_load_location: "//build/bazel/rules/java:library.bzl", 2314 } 2315 2316 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) 2317} 2318 2319type javaBinaryHostAttributes struct { 2320 *javaCommonAttributes 2321 Deps bazel.LabelListAttribute 2322 Runtime_deps bazel.LabelListAttribute 2323 Main_class string 2324 Jvm_flags bazel.StringListAttribute 2325} 2326 2327// JavaBinaryHostBp2Build is for java_binary_host bp2build. 2328func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { 2329 commonAttrs, depLabels := m.convertLibraryAttrsBp2Build(ctx) 2330 2331 deps := depLabels.Deps 2332 deps.Append(depLabels.StaticDeps) 2333 if m.binaryProperties.Jni_libs != nil { 2334 deps.Append(bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs))) 2335 } 2336 2337 var runtimeDeps bazel.LabelListAttribute 2338 if commonAttrs.Srcs.IsEmpty() { 2339 // if there are no sources, then the dependencies can only be used at runtime 2340 runtimeDeps = deps 2341 deps = bazel.LabelListAttribute{} 2342 } 2343 2344 mainClass := "" 2345 if m.binaryProperties.Main_class != nil { 2346 mainClass = *m.binaryProperties.Main_class 2347 } 2348 if m.properties.Manifest != nil { 2349 mainClassInManifest, err := android.GetMainClassInManifest(ctx.Config(), android.PathForModuleSrc(ctx, *m.properties.Manifest).String()) 2350 if err != nil { 2351 return 2352 } 2353 mainClass = mainClassInManifest 2354 } 2355 2356 attrs := &javaBinaryHostAttributes{ 2357 javaCommonAttributes: commonAttrs, 2358 Deps: deps, 2359 Runtime_deps: runtimeDeps, 2360 Main_class: mainClass, 2361 } 2362 2363 // Attribute jvm_flags 2364 if m.binaryProperties.Jni_libs != nil { 2365 jniLibPackages := map[string]bool{} 2366 for _, jniLibLabel := range android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs).Includes { 2367 jniLibPackage := jniLibLabel.Label 2368 indexOfColon := strings.Index(jniLibLabel.Label, ":") 2369 if indexOfColon > 0 { 2370 // JNI lib from other package 2371 jniLibPackage = jniLibLabel.Label[2:indexOfColon] 2372 } else if indexOfColon == 0 { 2373 // JNI lib in the same package of java_binary 2374 packageOfCurrentModule := m.GetBazelLabel(ctx, m) 2375 jniLibPackage = packageOfCurrentModule[2:strings.Index(packageOfCurrentModule, ":")] 2376 } 2377 if _, inMap := jniLibPackages[jniLibPackage]; !inMap { 2378 jniLibPackages[jniLibPackage] = true 2379 } 2380 } 2381 jniLibPaths := []string{} 2382 for jniLibPackage, _ := range jniLibPackages { 2383 // See cs/f:.*/third_party/bazel/.*java_stub_template.txt for the use of RUNPATH 2384 jniLibPaths = append(jniLibPaths, "$${RUNPATH}"+jniLibPackage) 2385 } 2386 attrs.Jvm_flags = bazel.MakeStringListAttribute([]string{"-Djava.library.path=" + strings.Join(jniLibPaths, ":")}) 2387 } 2388 2389 props := bazel.BazelTargetModuleProperties{ 2390 Rule_class: "java_binary", 2391 } 2392 2393 // Create the BazelTargetModule. 2394 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) 2395} 2396 2397type bazelJavaImportAttributes struct { 2398 Jars bazel.LabelListAttribute 2399} 2400 2401// java_import bp2Build converter. 2402func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) { 2403 var jars bazel.LabelListAttribute 2404 archVariantProps := i.GetArchVariantProperties(ctx, &ImportProperties{}) 2405 for axis, configToProps := range archVariantProps { 2406 for config, _props := range configToProps { 2407 if archProps, ok := _props.(*ImportProperties); ok { 2408 archJars := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Jars, []string(nil)) 2409 jars.SetSelectValue(axis, config, archJars) 2410 } 2411 } 2412 } 2413 2414 attrs := &bazelJavaImportAttributes{ 2415 Jars: jars, 2416 } 2417 props := bazel.BazelTargetModuleProperties{Rule_class: "java_import"} 2418 2419 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: android.RemoveOptionalPrebuiltPrefix(i.Name())}, attrs) 2420 2421} 2422