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 "android/soong/bazel/cquery" 28 "android/soong/remoteexec" 29 30 "github.com/google/blueprint" 31 "github.com/google/blueprint/proptools" 32 33 "android/soong/android" 34 "android/soong/cc" 35 "android/soong/dexpreopt" 36 "android/soong/java/config" 37 "android/soong/tradefed" 38) 39 40func init() { 41 registerJavaBuildComponents(android.InitRegistrationContext) 42 43 RegisterJavaSdkMemberTypes() 44} 45 46func registerJavaBuildComponents(ctx android.RegistrationContext) { 47 ctx.RegisterModuleType("java_defaults", DefaultsFactory) 48 49 ctx.RegisterModuleType("java_library", LibraryFactory) 50 ctx.RegisterModuleType("java_library_static", LibraryStaticFactory) 51 ctx.RegisterModuleType("java_library_host", LibraryHostFactory) 52 ctx.RegisterModuleType("java_binary", BinaryFactory) 53 ctx.RegisterModuleType("java_binary_host", BinaryHostFactory) 54 ctx.RegisterModuleType("java_test", TestFactory) 55 ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory) 56 ctx.RegisterModuleType("java_test_host", TestHostFactory) 57 ctx.RegisterModuleType("java_test_import", JavaTestImportFactory) 58 ctx.RegisterModuleType("java_import", ImportFactory) 59 ctx.RegisterModuleType("java_import_host", ImportFactoryHost) 60 ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory) 61 ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory) 62 ctx.RegisterModuleType("dex_import", DexImportFactory) 63 ctx.RegisterModuleType("java_api_library", ApiLibraryFactory) 64 ctx.RegisterModuleType("java_api_contribution", ApiContributionFactory) 65 66 // This mutator registers dependencies on dex2oat for modules that should be 67 // dexpreopted. This is done late when the final variants have been 68 // established, to not get the dependencies split into the wrong variants and 69 // to support the checks in dexpreoptDisabled(). 70 ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { 71 ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel() 72 // needs access to ApexInfoProvider which is available after variant creation 73 ctx.BottomUp("jacoco_deps", jacocoDepsMutator).Parallel() 74 }) 75 76 ctx.RegisterSingletonType("logtags", LogtagsSingleton) 77 ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) 78} 79 80func RegisterJavaSdkMemberTypes() { 81 // Register sdk member types. 82 android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) 83 android.RegisterSdkMemberType(javaLibsSdkMemberType) 84 android.RegisterSdkMemberType(javaBootLibsSdkMemberType) 85 android.RegisterSdkMemberType(javaSystemserverLibsSdkMemberType) 86 android.RegisterSdkMemberType(javaTestSdkMemberType) 87} 88 89var ( 90 // Supports adding java header libraries to module_exports and sdk. 91 javaHeaderLibsSdkMemberType = &librarySdkMemberType{ 92 android.SdkMemberTypeBase{ 93 PropertyName: "java_header_libs", 94 SupportsSdk: true, 95 }, 96 func(_ android.SdkMemberContext, j *Library) android.Path { 97 headerJars := j.HeaderJars() 98 if len(headerJars) != 1 { 99 panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) 100 } 101 102 return headerJars[0] 103 }, 104 sdkSnapshotFilePathForJar, 105 copyEverythingToSnapshot, 106 } 107 108 // Export implementation classes jar as part of the sdk. 109 exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path { 110 implementationJars := j.ImplementationAndResourcesJars() 111 if len(implementationJars) != 1 { 112 panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) 113 } 114 return implementationJars[0] 115 } 116 117 // Supports adding java implementation libraries to module_exports but not sdk. 118 javaLibsSdkMemberType = &librarySdkMemberType{ 119 android.SdkMemberTypeBase{ 120 PropertyName: "java_libs", 121 }, 122 exportImplementationClassesJar, 123 sdkSnapshotFilePathForJar, 124 copyEverythingToSnapshot, 125 } 126 127 snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool { 128 // In the S build the build will break if updatable-media does not provide a full implementation 129 // jar. That issue was fixed in Tiramisu by b/229932396. 130 if ctx.IsTargetBuildBeforeTiramisu() && ctx.Name() == "updatable-media" { 131 return true 132 } 133 134 return false 135 } 136 137 // Supports adding java boot libraries to module_exports and sdk. 138 // 139 // The build has some implicit dependencies (via the boot jars configuration) on a number of 140 // modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are 141 // provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise 142 // used outside those mainline modules. 143 // 144 // As they are not needed outside the mainline modules adding them to the sdk/module-exports as 145 // either java_libs, or java_header_libs would end up exporting more information than was strictly 146 // necessary. The java_boot_libs property to allow those modules to be exported as part of the 147 // sdk/module_exports without exposing any unnecessary information. 148 javaBootLibsSdkMemberType = &librarySdkMemberType{ 149 android.SdkMemberTypeBase{ 150 PropertyName: "java_boot_libs", 151 SupportsSdk: true, 152 }, 153 func(ctx android.SdkMemberContext, j *Library) android.Path { 154 if snapshotRequiresImplementationJar(ctx) { 155 return exportImplementationClassesJar(ctx, j) 156 } 157 158 // Java boot libs are only provided in the SDK to provide access to their dex implementation 159 // jar for use by dexpreopting and boot jars package check. They do not need to provide an 160 // actual implementation jar but the java_import will need a file that exists so just copy an 161 // empty file. Any attempt to use that file as a jar will cause a build error. 162 return ctx.SnapshotBuilder().EmptyFile() 163 }, 164 func(ctx android.SdkMemberContext, osPrefix, name string) string { 165 if snapshotRequiresImplementationJar(ctx) { 166 return sdkSnapshotFilePathForJar(ctx, osPrefix, name) 167 } 168 169 // Create a special name for the implementation jar to try and provide some useful information 170 // to a developer that attempts to compile against this. 171 // TODO(b/175714559): Provide a proper error message in Soong not ninja. 172 return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) 173 }, 174 onlyCopyJarToSnapshot, 175 } 176 177 // Supports adding java systemserver libraries to module_exports and sdk. 178 // 179 // The build has some implicit dependencies (via the systemserver jars configuration) on a number 180 // of modules that are part of the java systemserver classpath and which are provided by mainline 181 // modules but which are not otherwise used outside those mainline modules. 182 // 183 // As they are not needed outside the mainline modules adding them to the sdk/module-exports as 184 // either java_libs, or java_header_libs would end up exporting more information than was strictly 185 // necessary. The java_systemserver_libs property to allow those modules to be exported as part of 186 // the sdk/module_exports without exposing any unnecessary information. 187 javaSystemserverLibsSdkMemberType = &librarySdkMemberType{ 188 android.SdkMemberTypeBase{ 189 PropertyName: "java_systemserver_libs", 190 SupportsSdk: true, 191 192 // This was only added in Tiramisu. 193 SupportedBuildReleaseSpecification: "Tiramisu+", 194 }, 195 func(ctx android.SdkMemberContext, j *Library) android.Path { 196 // Java systemserver libs are only provided in the SDK to provide access to their dex 197 // implementation jar for use by dexpreopting. They do not need to provide an actual 198 // implementation jar but the java_import will need a file that exists so just copy an empty 199 // file. Any attempt to use that file as a jar will cause a build error. 200 return ctx.SnapshotBuilder().EmptyFile() 201 }, 202 func(_ android.SdkMemberContext, osPrefix, name string) string { 203 // Create a special name for the implementation jar to try and provide some useful information 204 // to a developer that attempts to compile against this. 205 // TODO(b/175714559): Provide a proper error message in Soong not ninja. 206 return filepath.Join(osPrefix, "java_systemserver_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) 207 }, 208 onlyCopyJarToSnapshot, 209 } 210 211 // Supports adding java test libraries to module_exports but not sdk. 212 javaTestSdkMemberType = &testSdkMemberType{ 213 SdkMemberTypeBase: android.SdkMemberTypeBase{ 214 PropertyName: "java_tests", 215 }, 216 } 217 218 // Rule for generating device binary default wrapper 219 deviceBinaryWrapper = pctx.StaticRule("deviceBinaryWrapper", blueprint.RuleParams{ 220 Command: `echo -e '#!/system/bin/sh\n` + 221 `export CLASSPATH=/system/framework/$jar_name\n` + 222 `exec app_process /$partition/bin $main_class "$$@"'> ${out}`, 223 Description: "Generating device binary wrapper ${jar_name}", 224 }, "jar_name", "partition", "main_class") 225) 226 227// JavaInfo contains information about a java module for use by modules that depend on it. 228type JavaInfo struct { 229 // HeaderJars is a list of jars that can be passed as the javac classpath in order to link 230 // against this module. If empty, ImplementationJars should be used instead. 231 HeaderJars android.Paths 232 233 // set of header jars for all transitive libs deps 234 TransitiveLibsHeaderJars *android.DepSet 235 236 // set of header jars for all transitive static libs deps 237 TransitiveStaticLibsHeaderJars *android.DepSet 238 239 // ImplementationAndResourceJars is a list of jars that contain the implementations of classes 240 // in the module as well as any resources included in the module. 241 ImplementationAndResourcesJars android.Paths 242 243 // ImplementationJars is a list of jars that contain the implementations of classes in the 244 //module. 245 ImplementationJars android.Paths 246 247 // ResourceJars is a list of jars that contain the resources included in the module. 248 ResourceJars android.Paths 249 250 // AidlIncludeDirs is a list of directories that should be passed to the aidl tool when 251 // depending on this module. 252 AidlIncludeDirs android.Paths 253 254 // SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this 255 // module. 256 SrcJarArgs []string 257 258 // SrcJarDeps is a list of paths to depend on when packaging the sources of this module. 259 SrcJarDeps android.Paths 260 261 // ExportedPlugins is a list of paths that should be used as annotation processors for any 262 // module that depends on this module. 263 ExportedPlugins android.Paths 264 265 // ExportedPluginClasses is a list of classes that should be run as annotation processors for 266 // any module that depends on this module. 267 ExportedPluginClasses []string 268 269 // ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs, 270 // requiring disbling turbine for any modules that depend on it. 271 ExportedPluginDisableTurbine bool 272 273 // JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be 274 // instrumented by jacoco. 275 JacocoReportClassesFile android.Path 276} 277 278var JavaInfoProvider = blueprint.NewProvider(JavaInfo{}) 279 280// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to 281// the sysprop implementation library. 282type SyspropPublicStubInfo struct { 283 // JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to 284 // the sysprop implementation library. 285 JavaInfo JavaInfo 286} 287 288var SyspropPublicStubInfoProvider = blueprint.NewProvider(SyspropPublicStubInfo{}) 289 290// Methods that need to be implemented for a module that is added to apex java_libs property. 291type ApexDependency interface { 292 HeaderJars() android.Paths 293 ImplementationAndResourcesJars() android.Paths 294} 295 296// Provides build path and install path to DEX jars. 297type UsesLibraryDependency interface { 298 DexJarBuildPath() OptionalDexJarPath 299 DexJarInstallPath() android.Path 300 ClassLoaderContexts() dexpreopt.ClassLoaderContextMap 301} 302 303// Provides transitive Proguard flag files to downstream DEX jars. 304type LibraryDependency interface { 305 ExportedProguardFlagFiles() android.Paths 306} 307 308// TODO(jungjw): Move this to kythe.go once it's created. 309type xref interface { 310 XrefJavaFiles() android.Paths 311} 312 313func (j *Module) XrefJavaFiles() android.Paths { 314 return j.kytheFiles 315} 316 317type dependencyTag struct { 318 blueprint.BaseDependencyTag 319 name string 320 321 // True if the dependency is relinked at runtime. 322 runtimeLinked bool 323 324 // True if the dependency is a toolchain, for example an annotation processor. 325 toolchain bool 326} 327 328// installDependencyTag is a dependency tag that is annotated to cause the installed files of the 329// dependency to be installed when the parent module is installed. 330type installDependencyTag struct { 331 blueprint.BaseDependencyTag 332 android.InstallAlwaysNeededDependencyTag 333 name string 334} 335 336func (d dependencyTag) LicenseAnnotations() []android.LicenseAnnotation { 337 if d.runtimeLinked { 338 return []android.LicenseAnnotation{android.LicenseAnnotationSharedDependency} 339 } else if d.toolchain { 340 return []android.LicenseAnnotation{android.LicenseAnnotationToolchain} 341 } 342 return nil 343} 344 345var _ android.LicenseAnnotationsDependencyTag = dependencyTag{} 346 347type usesLibraryDependencyTag struct { 348 dependencyTag 349 sdkVersion int // SDK version in which the library appared as a standalone library. 350 optional bool // If the dependency is optional or required. 351} 352 353func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag { 354 return usesLibraryDependencyTag{ 355 dependencyTag: dependencyTag{ 356 name: fmt.Sprintf("uses-library-%d", sdkVersion), 357 runtimeLinked: true, 358 }, 359 sdkVersion: sdkVersion, 360 optional: optional, 361 } 362} 363 364func IsJniDepTag(depTag blueprint.DependencyTag) bool { 365 return depTag == jniLibTag 366} 367 368var ( 369 dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} 370 dataDeviceBinsTag = dependencyTag{name: "dataDeviceBins"} 371 staticLibTag = dependencyTag{name: "staticlib"} 372 libTag = dependencyTag{name: "javalib", runtimeLinked: true} 373 sdkLibTag = dependencyTag{name: "sdklib", runtimeLinked: true} 374 java9LibTag = dependencyTag{name: "java9lib", runtimeLinked: true} 375 pluginTag = dependencyTag{name: "plugin", toolchain: true} 376 errorpronePluginTag = dependencyTag{name: "errorprone-plugin", toolchain: true} 377 exportedPluginTag = dependencyTag{name: "exported-plugin", toolchain: true} 378 bootClasspathTag = dependencyTag{name: "bootclasspath", runtimeLinked: true} 379 systemModulesTag = dependencyTag{name: "system modules", runtimeLinked: true} 380 frameworkResTag = dependencyTag{name: "framework-res"} 381 kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib", runtimeLinked: true} 382 kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations", runtimeLinked: true} 383 kotlinPluginTag = dependencyTag{name: "kotlin-plugin", toolchain: true} 384 proguardRaiseTag = dependencyTag{name: "proguard-raise"} 385 certificateTag = dependencyTag{name: "certificate"} 386 instrumentationForTag = dependencyTag{name: "instrumentation_for"} 387 extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true} 388 jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true} 389 r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true} 390 syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} 391 javaApiContributionTag = dependencyTag{name: "java-api-contribution"} 392 depApiSrcsTag = dependencyTag{name: "dep-api-srcs"} 393 jniInstallTag = installDependencyTag{name: "jni install"} 394 binaryInstallTag = installDependencyTag{name: "binary install"} 395 usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false) 396 usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true) 397 usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true) 398 usesLibCompat29ReqTag = makeUsesLibraryDependencyTag(29, false) 399 usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true) 400) 401 402func IsLibDepTag(depTag blueprint.DependencyTag) bool { 403 return depTag == libTag || depTag == sdkLibTag 404} 405 406func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool { 407 return depTag == staticLibTag 408} 409 410type sdkDep struct { 411 useModule, useFiles, invalidVersion bool 412 413 // The modules that will be added to the bootclasspath when targeting 1.8 or lower 414 bootclasspath []string 415 416 // The default system modules to use. Will be an empty string if no system 417 // modules are to be used. 418 systemModules string 419 420 // The modules that will be added to the classpath regardless of the Java language level targeted 421 classpath []string 422 423 // The modules that will be added ot the classpath when targeting 1.9 or higher 424 // (normally these will be on the bootclasspath when targeting 1.8 or lower) 425 java9Classpath []string 426 427 frameworkResModule string 428 429 jars android.Paths 430 aidl android.OptionalPath 431 432 noStandardLibs, noFrameworksLibs bool 433} 434 435func (s sdkDep) hasStandardLibs() bool { 436 return !s.noStandardLibs 437} 438 439func (s sdkDep) hasFrameworkLibs() bool { 440 return !s.noStandardLibs && !s.noFrameworksLibs 441} 442 443type jniLib struct { 444 name string 445 path android.Path 446 target android.Target 447 coverageFile android.OptionalPath 448 unstrippedFile android.Path 449 partition string 450} 451 452func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) { 453 sdkDep := decodeSdkDep(ctx, sdkContext) 454 if sdkDep.useModule { 455 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) 456 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) 457 ctx.AddVariationDependencies(nil, sdkLibTag, sdkDep.classpath...) 458 if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { 459 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...) 460 } 461 if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() { 462 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...) 463 } 464 } 465 if sdkDep.systemModules != "" { 466 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) 467 } 468} 469 470type deps struct { 471 // bootClasspath is the list of jars that form the boot classpath (generally the java.* and 472 // android.* classes) for tools that still use it. javac targeting 1.9 or higher uses 473 // systemModules and java9Classpath instead. 474 bootClasspath classpath 475 476 // classpath is the list of jars that form the classpath for javac and kotlinc rules. It 477 // contains header jars for all static and non-static dependencies. 478 classpath classpath 479 480 // dexClasspath is the list of jars that form the classpath for d8 and r8 rules. It contains 481 // header jars for all non-static dependencies. Static dependencies have already been 482 // combined into the program jar. 483 dexClasspath classpath 484 485 // java9Classpath is the list of jars that will be added to the classpath when targeting 486 // 1.9 or higher. It generally contains the android.* classes, while the java.* classes 487 // are provided by systemModules. 488 java9Classpath classpath 489 490 processorPath classpath 491 errorProneProcessorPath classpath 492 processorClasses []string 493 staticJars android.Paths 494 staticHeaderJars android.Paths 495 staticResourceJars android.Paths 496 aidlIncludeDirs android.Paths 497 srcs android.Paths 498 srcJars android.Paths 499 systemModules *systemModules 500 aidlPreprocess android.OptionalPath 501 kotlinStdlib android.Paths 502 kotlinAnnotations android.Paths 503 kotlinPlugins android.Paths 504 505 disableTurbine bool 506} 507 508func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) { 509 for _, f := range dep.Srcs() { 510 if f.Ext() != ".jar" { 511 ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency", 512 ctx.OtherModuleName(dep.(blueprint.Module))) 513 } 514 } 515} 516 517func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext android.SdkContext) javaVersion { 518 if javaVersion != "" { 519 return normalizeJavaVersion(ctx, javaVersion) 520 } else if ctx.Device() { 521 return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) 522 } else { 523 return JAVA_VERSION_17 524 } 525} 526 527// Java version for stubs generation 528func getStubsJavaVersion() javaVersion { 529 return JAVA_VERSION_8 530} 531 532type javaVersion int 533 534const ( 535 JAVA_VERSION_UNSUPPORTED = 0 536 JAVA_VERSION_6 = 6 537 JAVA_VERSION_7 = 7 538 JAVA_VERSION_8 = 8 539 JAVA_VERSION_9 = 9 540 JAVA_VERSION_11 = 11 541 JAVA_VERSION_17 = 17 542) 543 544func (v javaVersion) String() string { 545 switch v { 546 case JAVA_VERSION_6: 547 return "1.6" 548 case JAVA_VERSION_7: 549 return "1.7" 550 case JAVA_VERSION_8: 551 return "1.8" 552 case JAVA_VERSION_9: 553 return "1.9" 554 case JAVA_VERSION_11: 555 return "11" 556 case JAVA_VERSION_17: 557 return "17" 558 default: 559 return "unsupported" 560 } 561} 562 563func (v javaVersion) StringForKotlinc() string { 564 // $ ./external/kotlinc/bin/kotlinc -jvm-target foo 565 // error: unknown JVM target version: foo 566 // Supported versions: 1.6, 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 567 switch v { 568 case JAVA_VERSION_7: 569 return "1.6" 570 case JAVA_VERSION_9: 571 return "9" 572 default: 573 return v.String() 574 } 575} 576 577// Returns true if javac targeting this version uses system modules instead of a bootclasspath. 578func (v javaVersion) usesJavaModules() bool { 579 return v >= 9 580} 581 582func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion { 583 switch javaVersion { 584 case "1.6", "6": 585 return JAVA_VERSION_6 586 case "1.7", "7": 587 return JAVA_VERSION_7 588 case "1.8", "8": 589 return JAVA_VERSION_8 590 case "1.9", "9": 591 return JAVA_VERSION_9 592 case "11": 593 return JAVA_VERSION_11 594 case "17": 595 return JAVA_VERSION_17 596 case "10", "12", "13", "14", "15", "16": 597 ctx.PropertyErrorf("java_version", "Java language level %s is not supported", javaVersion) 598 return JAVA_VERSION_UNSUPPORTED 599 default: 600 ctx.PropertyErrorf("java_version", "Unrecognized Java language level") 601 return JAVA_VERSION_UNSUPPORTED 602 } 603} 604 605// 606// Java libraries (.jar file) 607// 608 609type Library struct { 610 Module 611 612 exportedProguardFlagFiles android.Paths 613 614 InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) 615} 616 617var _ LibraryDependency = (*Library)(nil) 618 619func (j *Library) ExportedProguardFlagFiles() android.Paths { 620 return j.exportedProguardFlagFiles 621} 622 623var _ android.ApexModule = (*Library)(nil) 624 625// Provides access to the list of permitted packages from apex boot jars. 626type PermittedPackagesForUpdatableBootJars interface { 627 PermittedPackagesForUpdatableBootJars() []string 628} 629 630var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil) 631 632func (j *Library) PermittedPackagesForUpdatableBootJars() []string { 633 return j.properties.Permitted_packages 634} 635 636func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { 637 // Store uncompressed (and aligned) any dex files from jars in APEXes. 638 if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { 639 return true 640 } 641 642 // Store uncompressed (and do not strip) dex files from boot class path jars. 643 if inList(ctx.ModuleName(), ctx.Config().BootJars()) { 644 return true 645 } 646 647 // Store uncompressed dex files that are preopted on /system. 648 if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !dexpreopter.odexOnSystemOther(ctx, dexpreopter.installPath)) { 649 return true 650 } 651 if ctx.Config().UncompressPrivAppDex() && 652 inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) { 653 return true 654 } 655 656 return false 657} 658 659// Sets `dexer.dexProperties.Uncompress_dex` to the proper value. 660func setUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter, dexer *dexer) { 661 if dexer.dexProperties.Uncompress_dex == nil { 662 // If the value was not force-set by the user, use reasonable default based on the module. 663 dexer.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, dexpreopter)) 664 } 665} 666 667func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { 668 669 j.provideHiddenAPIPropertyInfo(ctx) 670 671 j.sdkVersion = j.SdkVersion(ctx) 672 j.minSdkVersion = j.MinSdkVersion(ctx) 673 j.maxSdkVersion = j.MaxSdkVersion(ctx) 674 675 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 676 if !apexInfo.IsForPlatform() { 677 j.hideApexVariantFromMake = true 678 } 679 680 j.checkSdkVersions(ctx) 681 if ctx.Device() { 682 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 683 ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) 684 j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary 685 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 686 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 687 j.classLoaderContexts = j.usesLibrary.classLoaderContextForUsesLibDeps(ctx) 688 } 689 j.compile(ctx, nil) 690 691 // Collect the module directory for IDE info in java/jdeps.go. 692 j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) 693 694 exclusivelyForApex := !apexInfo.IsForPlatform() 695 if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex { 696 var extraInstallDeps android.Paths 697 if j.InstallMixin != nil { 698 extraInstallDeps = j.InstallMixin(ctx, j.outputFile) 699 } 700 hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host() 701 if hostDexNeeded { 702 j.hostdexInstallFile = ctx.InstallFile( 703 android.PathForHostDexInstall(ctx, "framework"), 704 j.Stem()+"-hostdex.jar", j.outputFile) 705 } 706 var installDir android.InstallPath 707 if ctx.InstallInTestcases() { 708 var archDir string 709 if !ctx.Host() { 710 archDir = ctx.DeviceConfig().DeviceArch() 711 } 712 installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) 713 } else { 714 installDir = android.PathForModuleInstall(ctx, "framework") 715 } 716 j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...) 717 } 718 719 j.exportedProguardFlagFiles = append(j.exportedProguardFlagFiles, 720 android.PathsForModuleSrc(ctx, j.dexProperties.Optimize.Proguard_flags_files)...) 721 ctx.VisitDirectDeps(func(m android.Module) { 722 if lib, ok := m.(LibraryDependency); ok && ctx.OtherModuleDependencyTag(m) == staticLibTag { 723 j.exportedProguardFlagFiles = append(j.exportedProguardFlagFiles, lib.ExportedProguardFlagFiles()...) 724 } 725 }) 726 j.exportedProguardFlagFiles = android.FirstUniquePaths(j.exportedProguardFlagFiles) 727} 728 729func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { 730 j.deps(ctx) 731 j.usesLibrary.deps(ctx, false) 732} 733 734const ( 735 aidlIncludeDir = "aidl" 736 javaDir = "java" 737 jarFileSuffix = ".jar" 738 testConfigSuffix = "-AndroidTest.xml" 739) 740 741// path to the jar file of a java library. Relative to <sdk_root>/<api_dir> 742func sdkSnapshotFilePathForJar(_ android.SdkMemberContext, osPrefix, name string) string { 743 return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix) 744} 745 746func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string { 747 return filepath.Join(javaDir, osPrefix, name+suffix) 748} 749 750type librarySdkMemberType struct { 751 android.SdkMemberTypeBase 752 753 // Function to retrieve the appropriate output jar (implementation or header) from 754 // the library. 755 jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path 756 757 // Function to compute the snapshot relative path to which the named library's 758 // jar should be copied. 759 snapshotPathGetter func(ctx android.SdkMemberContext, osPrefix, name string) string 760 761 // True if only the jar should be copied to the snapshot, false if the jar plus any additional 762 // files like aidl files should also be copied. 763 onlyCopyJarToSnapshot bool 764} 765 766const ( 767 onlyCopyJarToSnapshot = true 768 copyEverythingToSnapshot = false 769) 770 771func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { 772 ctx.AddVariationDependencies(nil, dependencyTag, names...) 773} 774 775func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { 776 _, ok := module.(*Library) 777 return ok 778} 779 780func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 781 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import") 782} 783 784func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 785 return &librarySdkMemberProperties{} 786} 787 788type librarySdkMemberProperties struct { 789 android.SdkMemberPropertiesBase 790 791 JarToExport android.Path `android:"arch_variant"` 792 AidlIncludeDirs android.Paths 793 794 // The list of permitted packages that need to be passed to the prebuilts as they are used to 795 // create the updatable-bcp-packages.txt file. 796 PermittedPackages []string 797 798 // The value of the min_sdk_version property, translated into a number where possible. 799 MinSdkVersion *string `supported_build_releases:"Tiramisu+"` 800 801 DexPreoptProfileGuided *bool `supported_build_releases:"UpsideDownCake+"` 802} 803 804func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 805 j := variant.(*Library) 806 807 p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) 808 809 p.AidlIncludeDirs = j.AidlIncludeDirs() 810 811 p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars() 812 813 // If the min_sdk_version was set then add the canonical representation of the API level to the 814 // snapshot. 815 if j.deviceProperties.Min_sdk_version != nil { 816 canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.String()) 817 p.MinSdkVersion = proptools.StringPtr(canonical) 818 } 819 820 if j.dexpreopter.dexpreoptProperties.Dex_preopt_result.Profile_guided { 821 p.DexPreoptProfileGuided = proptools.BoolPtr(true) 822 } 823} 824 825func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 826 builder := ctx.SnapshotBuilder() 827 828 memberType := ctx.MemberType().(*librarySdkMemberType) 829 830 exportedJar := p.JarToExport 831 if exportedJar != nil { 832 // Delegate the creation of the snapshot relative path to the member type. 833 snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(ctx, p.OsPrefix(), ctx.Name()) 834 835 // Copy the exported jar to the snapshot. 836 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 837 838 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 839 } 840 841 if p.MinSdkVersion != nil { 842 propertySet.AddProperty("min_sdk_version", *p.MinSdkVersion) 843 } 844 845 if len(p.PermittedPackages) > 0 { 846 propertySet.AddProperty("permitted_packages", p.PermittedPackages) 847 } 848 849 dexPreoptSet := propertySet.AddPropertySet("dex_preopt") 850 if p.DexPreoptProfileGuided != nil { 851 dexPreoptSet.AddProperty("profile_guided", proptools.Bool(p.DexPreoptProfileGuided)) 852 } 853 854 // Do not copy anything else to the snapshot. 855 if memberType.onlyCopyJarToSnapshot { 856 return 857 } 858 859 aidlIncludeDirs := p.AidlIncludeDirs 860 if len(aidlIncludeDirs) != 0 { 861 sdkModuleContext := ctx.SdkModuleContext() 862 for _, dir := range aidlIncludeDirs { 863 // TODO(jiyong): copy parcelable declarations only 864 aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil) 865 for _, file := range aidlFiles { 866 builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file)) 867 } 868 } 869 870 // TODO(b/151933053) - add aidl include dirs property 871 } 872} 873 874// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well. 875// 876// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were 877// compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used 878// as a `static_libs` dependency of another module. 879// 880// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on 881// a device. 882// 883// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 884// compiled against the host bootclasspath. 885func LibraryFactory() android.Module { 886 module := &Library{} 887 888 module.addHostAndDeviceProperties() 889 890 module.initModuleAndImport(module) 891 892 android.InitApexModule(module) 893 android.InitBazelModule(module) 894 InitJavaModule(module, android.HostAndDeviceSupported) 895 return module 896} 897 898// java_library_static is an obsolete alias for java_library. 899func LibraryStaticFactory() android.Module { 900 return LibraryFactory() 901} 902 903// java_library_host builds and links sources into a `.jar` file for the host. 904// 905// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were 906// compiled against the host bootclasspath. 907func LibraryHostFactory() android.Module { 908 module := &Library{} 909 910 module.addHostProperties() 911 912 module.Module.properties.Installable = proptools.BoolPtr(true) 913 914 android.InitApexModule(module) 915 android.InitBazelModule(module) 916 InitJavaModule(module, android.HostSupported) 917 return module 918} 919 920// 921// Java Tests 922// 923 924// Test option struct. 925type TestOptions struct { 926 android.CommonTestOptions 927 928 // a list of extra test configuration files that should be installed with the module. 929 Extra_test_configs []string `android:"path,arch_variant"` 930 931 // Extra <option> tags to add to the auto generated test xml file. The "key" 932 // is optional in each of these. 933 Tradefed_options []tradefed.Option 934} 935 936type testProperties struct { 937 // list of compatibility suites (for example "cts", "vts") that the module should be 938 // installed into. 939 Test_suites []string `android:"arch_variant"` 940 941 // the name of the test configuration (for example "AndroidTest.xml") that should be 942 // installed with the module. 943 Test_config *string `android:"path,arch_variant"` 944 945 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 946 // should be installed with the module. 947 Test_config_template *string `android:"path,arch_variant"` 948 949 // list of files or filegroup modules that provide data that should be installed alongside 950 // the test 951 Data []string `android:"path"` 952 953 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 954 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 955 // explicitly. 956 Auto_gen_config *bool 957 958 // Add parameterized mainline modules to auto generated test config. The options will be 959 // handled by TradeFed to do downloading and installing the specified modules on the device. 960 Test_mainline_modules []string 961 962 // Test options. 963 Test_options TestOptions 964 965 // Names of modules containing JNI libraries that should be installed alongside the test. 966 Jni_libs []string 967 968 // Install the test into a folder named for the module in all test suites. 969 Per_testcase_directory *bool 970} 971 972type hostTestProperties struct { 973 // list of native binary modules that should be installed alongside the test 974 Data_native_bins []string `android:"arch_variant"` 975 976 // list of device binary modules that should be installed alongside the test 977 // This property only adds the first variant of the dependency 978 Data_device_bins_first []string `android:"arch_variant"` 979 980 // list of device binary modules that should be installed alongside the test 981 // This property adds 64bit AND 32bit variants of the dependency 982 Data_device_bins_both []string `android:"arch_variant"` 983 984 // list of device binary modules that should be installed alongside the test 985 // This property only adds 64bit variants of the dependency 986 Data_device_bins_64 []string `android:"arch_variant"` 987 988 // list of device binary modules that should be installed alongside the test 989 // This property adds 32bit variants of the dependency if available, or else 990 // defaults to the 64bit variant 991 Data_device_bins_prefer32 []string `android:"arch_variant"` 992 993 // list of device binary modules that should be installed alongside the test 994 // This property only adds 32bit variants of the dependency 995 Data_device_bins_32 []string `android:"arch_variant"` 996} 997 998type testHelperLibraryProperties struct { 999 // list of compatibility suites (for example "cts", "vts") that the module should be 1000 // installed into. 1001 Test_suites []string `android:"arch_variant"` 1002 1003 // Install the test into a folder named for the module in all test suites. 1004 Per_testcase_directory *bool 1005} 1006 1007type prebuiltTestProperties struct { 1008 // list of compatibility suites (for example "cts", "vts") that the module should be 1009 // installed into. 1010 Test_suites []string `android:"arch_variant"` 1011 1012 // the name of the test configuration (for example "AndroidTest.xml") that should be 1013 // installed with the module. 1014 Test_config *string `android:"path,arch_variant"` 1015} 1016 1017type Test struct { 1018 Library 1019 1020 testProperties testProperties 1021 1022 testConfig android.Path 1023 extraTestConfigs android.Paths 1024 data android.Paths 1025} 1026 1027type TestHost struct { 1028 Test 1029 1030 testHostProperties hostTestProperties 1031} 1032 1033type TestHelperLibrary struct { 1034 Library 1035 1036 testHelperLibraryProperties testHelperLibraryProperties 1037} 1038 1039type JavaTestImport struct { 1040 Import 1041 1042 prebuiltTestProperties prebuiltTestProperties 1043 1044 testConfig android.Path 1045 dexJarFile android.Path 1046} 1047 1048func (j *Test) InstallInTestcases() bool { 1049 // Host java tests install into $(HOST_OUT_JAVA_LIBRARIES), and then are copied into 1050 // testcases by base_rules.mk. 1051 return !j.Host() 1052} 1053 1054func (j *TestHelperLibrary) InstallInTestcases() bool { 1055 return true 1056} 1057 1058func (j *JavaTestImport) InstallInTestcases() bool { 1059 return true 1060} 1061 1062func (j *TestHost) addDataDeviceBinsDeps(ctx android.BottomUpMutatorContext) { 1063 if len(j.testHostProperties.Data_device_bins_first) > 0 { 1064 deviceVariations := ctx.Config().AndroidFirstDeviceTarget.Variations() 1065 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_first...) 1066 } 1067 1068 var maybeAndroid32Target *android.Target 1069 var maybeAndroid64Target *android.Target 1070 android32TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib32") 1071 android64TargetList := android.FirstTarget(ctx.Config().Targets[android.Android], "lib64") 1072 if len(android32TargetList) > 0 { 1073 maybeAndroid32Target = &android32TargetList[0] 1074 } 1075 if len(android64TargetList) > 0 { 1076 maybeAndroid64Target = &android64TargetList[0] 1077 } 1078 1079 if len(j.testHostProperties.Data_device_bins_both) > 0 { 1080 if maybeAndroid32Target == nil && maybeAndroid64Target == nil { 1081 ctx.PropertyErrorf("data_device_bins_both", "no device targets available. Targets: %q", ctx.Config().Targets) 1082 return 1083 } 1084 if maybeAndroid32Target != nil { 1085 ctx.AddFarVariationDependencies( 1086 maybeAndroid32Target.Variations(), 1087 dataDeviceBinsTag, 1088 j.testHostProperties.Data_device_bins_both..., 1089 ) 1090 } 1091 if maybeAndroid64Target != nil { 1092 ctx.AddFarVariationDependencies( 1093 maybeAndroid64Target.Variations(), 1094 dataDeviceBinsTag, 1095 j.testHostProperties.Data_device_bins_both..., 1096 ) 1097 } 1098 } 1099 1100 if len(j.testHostProperties.Data_device_bins_prefer32) > 0 { 1101 if maybeAndroid32Target != nil { 1102 ctx.AddFarVariationDependencies( 1103 maybeAndroid32Target.Variations(), 1104 dataDeviceBinsTag, 1105 j.testHostProperties.Data_device_bins_prefer32..., 1106 ) 1107 } else { 1108 if maybeAndroid64Target == nil { 1109 ctx.PropertyErrorf("data_device_bins_prefer32", "no device targets available. Targets: %q", ctx.Config().Targets) 1110 return 1111 } 1112 ctx.AddFarVariationDependencies( 1113 maybeAndroid64Target.Variations(), 1114 dataDeviceBinsTag, 1115 j.testHostProperties.Data_device_bins_prefer32..., 1116 ) 1117 } 1118 } 1119 1120 if len(j.testHostProperties.Data_device_bins_32) > 0 { 1121 if maybeAndroid32Target == nil { 1122 ctx.PropertyErrorf("data_device_bins_32", "cannot find 32bit device target. Targets: %q", ctx.Config().Targets) 1123 return 1124 } 1125 deviceVariations := maybeAndroid32Target.Variations() 1126 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_32...) 1127 } 1128 1129 if len(j.testHostProperties.Data_device_bins_64) > 0 { 1130 if maybeAndroid64Target == nil { 1131 ctx.PropertyErrorf("data_device_bins_64", "cannot find 64bit device target. Targets: %q", ctx.Config().Targets) 1132 return 1133 } 1134 deviceVariations := maybeAndroid64Target.Variations() 1135 ctx.AddFarVariationDependencies(deviceVariations, dataDeviceBinsTag, j.testHostProperties.Data_device_bins_64...) 1136 } 1137} 1138 1139func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { 1140 if len(j.testHostProperties.Data_native_bins) > 0 { 1141 for _, target := range ctx.MultiTargets() { 1142 ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...) 1143 } 1144 } 1145 1146 if len(j.testProperties.Jni_libs) > 0 { 1147 for _, target := range ctx.MultiTargets() { 1148 sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) 1149 ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...) 1150 } 1151 } 1152 1153 j.addDataDeviceBinsDeps(ctx) 1154 j.deps(ctx) 1155} 1156 1157func (j *TestHost) AddExtraResource(p android.Path) { 1158 j.extraResources = append(j.extraResources, p) 1159} 1160 1161func (j *TestHost) dataDeviceBins() []string { 1162 ret := make([]string, 0, 1163 len(j.testHostProperties.Data_device_bins_first)+ 1164 len(j.testHostProperties.Data_device_bins_both)+ 1165 len(j.testHostProperties.Data_device_bins_prefer32)+ 1166 len(j.testHostProperties.Data_device_bins_32)+ 1167 len(j.testHostProperties.Data_device_bins_64), 1168 ) 1169 1170 ret = append(ret, j.testHostProperties.Data_device_bins_first...) 1171 ret = append(ret, j.testHostProperties.Data_device_bins_both...) 1172 ret = append(ret, j.testHostProperties.Data_device_bins_prefer32...) 1173 ret = append(ret, j.testHostProperties.Data_device_bins_32...) 1174 ret = append(ret, j.testHostProperties.Data_device_bins_64...) 1175 1176 return ret 1177} 1178 1179func (j *TestHost) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1180 var configs []tradefed.Config 1181 dataDeviceBins := j.dataDeviceBins() 1182 if len(dataDeviceBins) > 0 { 1183 // add Tradefed configuration to push device bins to device for testing 1184 remoteDir := filepath.Join("/data/local/tests/unrestricted/", j.Name()) 1185 options := []tradefed.Option{{Name: "cleanup", Value: "true"}} 1186 for _, bin := range dataDeviceBins { 1187 fullPath := filepath.Join(remoteDir, bin) 1188 options = append(options, tradefed.Option{Name: "push-file", Key: bin, Value: fullPath}) 1189 } 1190 configs = append(configs, tradefed.Object{ 1191 Type: "target_preparer", 1192 Class: "com.android.tradefed.targetprep.PushFilePreparer", 1193 Options: options, 1194 }) 1195 } 1196 1197 j.Test.generateAndroidBuildActionsWithConfig(ctx, configs) 1198} 1199 1200func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1201 j.generateAndroidBuildActionsWithConfig(ctx, nil) 1202} 1203 1204func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, configs []tradefed.Config) { 1205 if j.testProperties.Test_options.Unit_test == nil && ctx.Host() { 1206 // TODO(b/): Clean temporary heuristic to avoid unexpected onboarding. 1207 defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites) 1208 j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest) 1209 } 1210 j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ 1211 TestConfigProp: j.testProperties.Test_config, 1212 TestConfigTemplateProp: j.testProperties.Test_config_template, 1213 TestSuites: j.testProperties.Test_suites, 1214 Config: configs, 1215 OptionsForAutogenerated: j.testProperties.Test_options.Tradefed_options, 1216 AutoGenConfig: j.testProperties.Auto_gen_config, 1217 UnitTest: j.testProperties.Test_options.Unit_test, 1218 DeviceTemplate: "${JavaTestConfigTemplate}", 1219 HostTemplate: "${JavaHostTestConfigTemplate}", 1220 HostUnitTestTemplate: "${JavaHostUnitTestConfigTemplate}", 1221 }) 1222 1223 j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data) 1224 1225 j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs) 1226 1227 ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) { 1228 j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) 1229 }) 1230 1231 ctx.VisitDirectDepsWithTag(dataDeviceBinsTag, func(dep android.Module) { 1232 j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) 1233 }) 1234 1235 ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) { 1236 sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo) 1237 if sharedLibInfo.SharedLibrary != nil { 1238 // Copy to an intermediate output directory to append "lib[64]" to the path, 1239 // so that it's compatible with the default rpath values. 1240 var relPath string 1241 if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" { 1242 relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base()) 1243 } else { 1244 relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base()) 1245 } 1246 relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath) 1247 ctx.Build(pctx, android.BuildParams{ 1248 Rule: android.Cp, 1249 Input: sharedLibInfo.SharedLibrary, 1250 Output: relocatedLib, 1251 }) 1252 j.data = append(j.data, relocatedLib) 1253 } else { 1254 ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep)) 1255 } 1256 }) 1257 1258 j.Library.GenerateAndroidBuildActions(ctx) 1259} 1260 1261func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1262 j.Library.GenerateAndroidBuildActions(ctx) 1263} 1264 1265func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1266 j.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ 1267 TestConfigProp: j.prebuiltTestProperties.Test_config, 1268 TestSuites: j.prebuiltTestProperties.Test_suites, 1269 DeviceTemplate: "${JavaTestConfigTemplate}", 1270 HostTemplate: "${JavaHostTestConfigTemplate}", 1271 HostUnitTestTemplate: "${JavaHostUnitTestConfigTemplate}", 1272 }) 1273 1274 j.Import.GenerateAndroidBuildActions(ctx) 1275} 1276 1277type testSdkMemberType struct { 1278 android.SdkMemberTypeBase 1279} 1280 1281func (mt *testSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { 1282 ctx.AddVariationDependencies(nil, dependencyTag, names...) 1283} 1284 1285func (mt *testSdkMemberType) IsInstance(module android.Module) bool { 1286 _, ok := module.(*Test) 1287 return ok 1288} 1289 1290func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 1291 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import") 1292} 1293 1294func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 1295 return &testSdkMemberProperties{} 1296} 1297 1298type testSdkMemberProperties struct { 1299 android.SdkMemberPropertiesBase 1300 1301 JarToExport android.Path 1302 TestConfig android.Path 1303} 1304 1305func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 1306 test := variant.(*Test) 1307 1308 implementationJars := test.ImplementationJars() 1309 if len(implementationJars) != 1 { 1310 panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name())) 1311 } 1312 1313 p.JarToExport = implementationJars[0] 1314 p.TestConfig = test.testConfig 1315} 1316 1317func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 1318 builder := ctx.SnapshotBuilder() 1319 1320 exportedJar := p.JarToExport 1321 if exportedJar != nil { 1322 snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(ctx, p.OsPrefix(), ctx.Name()) 1323 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 1324 1325 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 1326 } 1327 1328 testConfig := p.TestConfig 1329 if testConfig != nil { 1330 snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix) 1331 builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath) 1332 propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath) 1333 } 1334} 1335 1336// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and 1337// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file. 1338// 1339// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were 1340// compiled against the device bootclasspath. 1341// 1342// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 1343// compiled against the host bootclasspath. 1344func TestFactory() android.Module { 1345 module := &Test{} 1346 1347 module.addHostAndDeviceProperties() 1348 module.AddProperties(&module.testProperties) 1349 1350 module.Module.properties.Installable = proptools.BoolPtr(true) 1351 module.Module.dexpreopter.isTest = true 1352 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) 1353 1354 InitJavaModule(module, android.HostAndDeviceSupported) 1355 return module 1356} 1357 1358// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite. 1359func TestHelperLibraryFactory() android.Module { 1360 module := &TestHelperLibrary{} 1361 1362 module.addHostAndDeviceProperties() 1363 module.AddProperties(&module.testHelperLibraryProperties) 1364 1365 module.Module.properties.Installable = proptools.BoolPtr(true) 1366 module.Module.dexpreopter.isTest = true 1367 module.Module.linter.properties.Lint.Test = proptools.BoolPtr(true) 1368 1369 InitJavaModule(module, android.HostAndDeviceSupported) 1370 return module 1371} 1372 1373// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module 1374// and makes sure that it is added to the appropriate test suite. 1375// 1376// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were 1377// compiled against an Android classpath. 1378// 1379// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 1380// for host modules. 1381func JavaTestImportFactory() android.Module { 1382 module := &JavaTestImport{} 1383 1384 module.AddProperties( 1385 &module.Import.properties, 1386 &module.prebuiltTestProperties) 1387 1388 module.Import.properties.Installable = proptools.BoolPtr(true) 1389 1390 android.InitPrebuiltModule(module, &module.properties.Jars) 1391 android.InitApexModule(module) 1392 InitJavaModule(module, android.HostAndDeviceSupported) 1393 return module 1394} 1395 1396// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to 1397// allow running the test with `atest` or a `TEST_MAPPING` file. 1398// 1399// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were 1400// compiled against the host bootclasspath. 1401func TestHostFactory() android.Module { 1402 module := &TestHost{} 1403 1404 module.addHostProperties() 1405 module.AddProperties(&module.testProperties) 1406 module.AddProperties(&module.testHostProperties) 1407 1408 InitTestHost( 1409 module, 1410 proptools.BoolPtr(true), 1411 nil, 1412 nil) 1413 1414 InitJavaModuleMultiTargets(module, android.HostSupported) 1415 1416 return module 1417} 1418 1419func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenConfig *bool) { 1420 th.properties.Installable = installable 1421 th.testProperties.Auto_gen_config = autoGenConfig 1422 th.testProperties.Test_suites = testSuites 1423} 1424 1425// 1426// Java Binaries (.jar file plus wrapper script) 1427// 1428 1429type binaryProperties struct { 1430 // installable script to execute the resulting jar 1431 Wrapper *string `android:"path,arch_variant"` 1432 1433 // Name of the class containing main to be inserted into the manifest as Main-Class. 1434 Main_class *string 1435 1436 // Names of modules containing JNI libraries that should be installed alongside the host 1437 // variant of the binary. 1438 Jni_libs []string `android:"arch_variant"` 1439} 1440 1441type Binary struct { 1442 Library 1443 1444 binaryProperties binaryProperties 1445 1446 isWrapperVariant bool 1447 1448 wrapperFile android.Path 1449 binaryFile android.InstallPath 1450} 1451 1452func (j *Binary) HostToolPath() android.OptionalPath { 1453 return android.OptionalPathForPath(j.binaryFile) 1454} 1455 1456func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1457 if ctx.Arch().ArchType == android.Common { 1458 // Compile the jar 1459 if j.binaryProperties.Main_class != nil { 1460 if j.properties.Manifest != nil { 1461 ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set") 1462 } 1463 manifestFile := android.PathForModuleOut(ctx, "manifest.txt") 1464 GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class)) 1465 j.overrideManifest = android.OptionalPathForPath(manifestFile) 1466 } 1467 1468 j.Library.GenerateAndroidBuildActions(ctx) 1469 } else { 1470 // Handle the binary wrapper 1471 j.isWrapperVariant = true 1472 1473 if j.binaryProperties.Wrapper != nil { 1474 j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper) 1475 } else { 1476 if ctx.Windows() { 1477 ctx.PropertyErrorf("wrapper", "wrapper is required for Windows") 1478 } 1479 1480 if ctx.Device() { 1481 // device binary should have a main_class property if it does not 1482 // have a specific wrapper, so that a default wrapper can 1483 // be generated for it. 1484 if j.binaryProperties.Main_class == nil { 1485 ctx.PropertyErrorf("main_class", "main_class property "+ 1486 "is required for device binary if no default wrapper is assigned") 1487 } else { 1488 wrapper := android.PathForModuleOut(ctx, ctx.ModuleName()+".sh") 1489 jarName := j.Stem() + ".jar" 1490 partition := j.PartitionTag(ctx.DeviceConfig()) 1491 ctx.Build(pctx, android.BuildParams{ 1492 Rule: deviceBinaryWrapper, 1493 Output: wrapper, 1494 Args: map[string]string{ 1495 "jar_name": jarName, 1496 "partition": partition, 1497 "main_class": String(j.binaryProperties.Main_class), 1498 }, 1499 }) 1500 j.wrapperFile = wrapper 1501 } 1502 } else { 1503 j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") 1504 } 1505 } 1506 1507 ext := "" 1508 if ctx.Windows() { 1509 ext = ".bat" 1510 } 1511 1512 // The host installation rules make the installed wrapper depend on all the dependencies 1513 // of the wrapper variant, which will include the common variant's jar file and any JNI 1514 // libraries. This is verified by TestBinary. 1515 j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), 1516 ctx.ModuleName()+ext, j.wrapperFile) 1517 } 1518} 1519 1520func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { 1521 if ctx.Arch().ArchType == android.Common { 1522 j.deps(ctx) 1523 } 1524 if ctx.Arch().ArchType != android.Common { 1525 // These dependencies ensure the host installation rules will install the jar file and 1526 // the jni libraries when the wrapper is installed. 1527 ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) 1528 ctx.AddVariationDependencies( 1529 []blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}}, 1530 binaryInstallTag, ctx.ModuleName()) 1531 } 1532} 1533 1534// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host 1535// as well. 1536// 1537// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were 1538// compiled against the device bootclasspath. 1539// 1540// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 1541// compiled against the host bootclasspath. 1542func BinaryFactory() android.Module { 1543 module := &Binary{} 1544 1545 module.addHostAndDeviceProperties() 1546 module.AddProperties(&module.binaryProperties) 1547 1548 module.Module.properties.Installable = proptools.BoolPtr(true) 1549 1550 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) 1551 android.InitDefaultableModule(module) 1552 android.InitBazelModule(module) 1553 1554 return module 1555} 1556 1557// java_binary_host builds a `.jar` file and a shell script that executes it for the host. 1558// 1559// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were 1560// compiled against the host bootclasspath. 1561func BinaryHostFactory() android.Module { 1562 module := &Binary{} 1563 1564 module.addHostProperties() 1565 module.AddProperties(&module.binaryProperties) 1566 1567 module.Module.properties.Installable = proptools.BoolPtr(true) 1568 1569 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) 1570 android.InitDefaultableModule(module) 1571 android.InitBazelModule(module) 1572 return module 1573} 1574 1575type JavaApiContribution struct { 1576 android.ModuleBase 1577 android.DefaultableModuleBase 1578 1579 properties struct { 1580 // name of the API surface 1581 Api_surface *string 1582 1583 // relative path to the API signature text file 1584 Api_file *string `android:"path"` 1585 } 1586} 1587 1588func ApiContributionFactory() android.Module { 1589 module := &JavaApiContribution{} 1590 android.InitAndroidModule(module) 1591 android.InitDefaultableModule(module) 1592 module.AddProperties(&module.properties) 1593 return module 1594} 1595 1596type JavaApiImportInfo struct { 1597 ApiFile android.Path 1598} 1599 1600var JavaApiImportProvider = blueprint.NewProvider(JavaApiImportInfo{}) 1601 1602func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1603 var apiFile android.Path = nil 1604 if apiFileString := ap.properties.Api_file; apiFileString != nil { 1605 apiFile = android.PathForModuleSrc(ctx, String(apiFileString)) 1606 } 1607 1608 ctx.SetProvider(JavaApiImportProvider, JavaApiImportInfo{ 1609 ApiFile: apiFile, 1610 }) 1611} 1612 1613type JavaApiLibraryDepsInfo struct { 1614 JavaInfo 1615 StubsSrcJar android.Path 1616} 1617 1618var JavaApiLibraryDepsProvider = blueprint.NewProvider(JavaApiLibraryDepsInfo{}) 1619 1620type ApiLibrary struct { 1621 android.ModuleBase 1622 android.DefaultableModuleBase 1623 1624 hiddenAPI 1625 dexer 1626 1627 properties JavaApiLibraryProperties 1628 1629 stubsSrcJar android.WritablePath 1630 stubsJar android.WritablePath 1631 stubsJarWithoutStaticLibs android.WritablePath 1632 extractedSrcJar android.WritablePath 1633 // .dex of stubs, used for hiddenapi processing 1634 dexJarFile OptionalDexJarPath 1635} 1636 1637type JavaApiLibraryProperties struct { 1638 // name of the API surface 1639 Api_surface *string 1640 1641 // list of Java API contribution modules that consists this API surface 1642 // This is a list of Soong modules 1643 Api_contributions []string 1644 1645 // list of api.txt files relative to this directory that contribute to the 1646 // API surface. 1647 // This is a list of relative paths 1648 Api_files []string 1649 1650 // List of flags to be passed to the javac compiler to generate jar file 1651 Javacflags []string 1652 1653 // List of shared java libs that this module has dependencies to and 1654 // should be passed as classpath in javac invocation 1655 Libs []string 1656 1657 // List of java libs that this module has static dependencies to and will be 1658 // merge zipped after metalava invocation 1659 Static_libs []string 1660 1661 // Java Api library to provide the full API surface text files and jar file. 1662 // If this property is set, the provided full API surface text files and 1663 // jar file are passed to metalava invocation. 1664 Dep_api_srcs *string 1665} 1666 1667func ApiLibraryFactory() android.Module { 1668 module := &ApiLibrary{} 1669 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibCommon) 1670 module.AddProperties(&module.properties) 1671 android.InitDefaultableModule(module) 1672 return module 1673} 1674 1675func (al *ApiLibrary) ApiSurface() *string { 1676 return al.properties.Api_surface 1677} 1678 1679func (al *ApiLibrary) StubsJar() android.Path { 1680 return al.stubsJar 1681} 1682 1683func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, 1684 srcs android.Paths, homeDir android.WritablePath) *android.RuleBuilderCommand { 1685 rule.Command().Text("rm -rf").Flag(homeDir.String()) 1686 rule.Command().Text("mkdir -p").Flag(homeDir.String()) 1687 1688 cmd := rule.Command() 1689 cmd.FlagWithArg("ANDROID_PREFS_ROOT=", homeDir.String()) 1690 1691 if metalavaUseRbe(ctx) { 1692 rule.Remoteable(android.RemoteRuleSupports{RBE: true}) 1693 execStrategy := ctx.Config().GetenvWithDefault("RBE_METALAVA_EXEC_STRATEGY", remoteexec.LocalExecStrategy) 1694 labels := map[string]string{"type": "tool", "name": "metalava"} 1695 1696 pool := ctx.Config().GetenvWithDefault("RBE_METALAVA_POOL", "java16") 1697 rule.Rewrapper(&remoteexec.REParams{ 1698 Labels: labels, 1699 ExecStrategy: execStrategy, 1700 ToolchainInputs: []string{config.JavaCmd(ctx).String()}, 1701 Platform: map[string]string{remoteexec.PoolKey: pool}, 1702 }) 1703 } 1704 1705 cmd.BuiltTool("metalava").ImplicitTool(ctx.Config().HostJavaToolPath(ctx, "metalava.jar")). 1706 Flag(config.JavacVmFlags). 1707 Flag("-J--add-opens=java.base/java.util=ALL-UNNAMED"). 1708 FlagWithArg("-encoding ", "UTF-8"). 1709 FlagWithInputList("--source-files ", srcs, " ") 1710 1711 cmd.Flag("--no-banner"). 1712 Flag("--color"). 1713 Flag("--quiet"). 1714 Flag("--format=v2"). 1715 Flag("--include-annotations"). 1716 // The flag makes nullability issues as warnings rather than errors by replacing 1717 // @Nullable/@NonNull in the listed packages APIs with @RecentlyNullable/@RecentlyNonNull, 1718 // and these packages are meant to have everything annotated 1719 // @RecentlyNullable/@RecentlyNonNull. 1720 FlagWithArg("--force-convert-to-warning-nullability-annotations ", "+*:-android.*:+android.icu.*:-dalvik.*"). 1721 FlagWithArg("--repeat-errors-max ", "10"). 1722 FlagWithArg("--hide ", "UnresolvedImport"). 1723 FlagWithArg("--hide ", "InvalidNullabilityOverride"). 1724 FlagWithArg("--hide ", "ChangedDefault") 1725 1726 return cmd 1727} 1728 1729func (al *ApiLibrary) HeaderJars() android.Paths { 1730 return android.Paths{al.stubsJar} 1731} 1732 1733func (al *ApiLibrary) OutputDirAndDeps() (android.Path, android.Paths) { 1734 return nil, nil 1735} 1736 1737func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBuilderCommand, stubsDir android.OptionalPath) { 1738 if stubsDir.Valid() { 1739 cmd.FlagWithArg("--stubs ", stubsDir.String()) 1740 } 1741} 1742 1743// This method extracts the stub java files from the srcjar file provided from dep_api_srcs module 1744// and replaces the java stubs generated by invoking metalava in this module. 1745// This method is used because metalava can generate compilable from-text stubs only when 1746// the codebase encompasses all classes listed in the input API text file, but a class can extend 1747// a class that is not within the same API domain. 1748func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.RuleBuilder, stubsDir android.OptionalPath, depApiSrcsSrcJar android.Path) { 1749 generatedStubsList := android.PathForModuleOut(ctx, "metalava", "sources.txt") 1750 unzippedSrcJarDir := android.PathForModuleOut(ctx, "metalava", "unzipDir") 1751 1752 rule.Command(). 1753 BuiltTool("list_files"). 1754 Text(stubsDir.String()). 1755 FlagWithOutput("--out ", generatedStubsList). 1756 FlagWithArg("--extensions ", ".java"). 1757 FlagWithArg("--root ", unzippedSrcJarDir.String()) 1758 1759 rule.Command(). 1760 Text("unzip"). 1761 Flag("-q"). 1762 Input(depApiSrcsSrcJar). 1763 FlagWithArg("-d ", unzippedSrcJarDir.String()) 1764 1765 rule.Command(). 1766 BuiltTool("soong_zip"). 1767 Flag("-srcjar"). 1768 Flag("-write_if_changed"). 1769 FlagWithArg("-C ", unzippedSrcJarDir.String()). 1770 FlagWithInput("-l ", generatedStubsList). 1771 FlagWithOutput("-o ", al.stubsSrcJar) 1772} 1773 1774func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { 1775 apiContributions := al.properties.Api_contributions 1776 for _, apiContributionName := range apiContributions { 1777 ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName) 1778 } 1779 ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...) 1780 ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...) 1781 if al.properties.Dep_api_srcs != nil { 1782 ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Dep_api_srcs)) 1783 } 1784} 1785 1786func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1787 1788 rule := android.NewRuleBuilder(pctx, ctx) 1789 1790 rule.Sbox(android.PathForModuleOut(ctx, "metalava"), 1791 android.PathForModuleOut(ctx, "metalava.sbox.textproto")). 1792 SandboxInputs() 1793 1794 var stubsDir android.OptionalPath 1795 stubsDir = android.OptionalPathForPath(android.PathForModuleOut(ctx, "metalava", "stubsDir")) 1796 rule.Command().Text("rm -rf").Text(stubsDir.String()) 1797 rule.Command().Text("mkdir -p").Text(stubsDir.String()) 1798 1799 homeDir := android.PathForModuleOut(ctx, "metalava", "home") 1800 1801 var srcFiles android.Paths 1802 var classPaths android.Paths 1803 var staticLibs android.Paths 1804 var depApiSrcsStubsSrcJar android.Path 1805 ctx.VisitDirectDeps(func(dep android.Module) { 1806 tag := ctx.OtherModuleDependencyTag(dep) 1807 switch tag { 1808 case javaApiContributionTag: 1809 provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo) 1810 providerApiFile := provider.ApiFile 1811 if providerApiFile == nil { 1812 ctx.ModuleErrorf("Error: %s has an empty api file.", dep.Name()) 1813 } 1814 srcFiles = append(srcFiles, android.PathForSource(ctx, providerApiFile.String())) 1815 case libTag: 1816 provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) 1817 classPaths = append(classPaths, provider.HeaderJars...) 1818 case staticLibTag: 1819 provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) 1820 staticLibs = append(staticLibs, provider.HeaderJars...) 1821 case depApiSrcsTag: 1822 provider := ctx.OtherModuleProvider(dep, JavaApiLibraryDepsProvider).(JavaApiLibraryDepsInfo) 1823 classPaths = append(classPaths, provider.HeaderJars...) 1824 depApiSrcsStubsSrcJar = provider.StubsSrcJar 1825 } 1826 }) 1827 1828 // Add the api_files inputs 1829 for _, api := range al.properties.Api_files { 1830 // Use MaybeExistentPathForSource since the api file might not exist during analysis. 1831 // This will be provided by the orchestrator in the combined execution. 1832 srcFiles = append(srcFiles, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), api)) 1833 } 1834 1835 if srcFiles == nil { 1836 ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName()) 1837 } 1838 1839 cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir) 1840 1841 al.stubsFlags(ctx, cmd, stubsDir) 1842 1843 al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar") 1844 1845 if depApiSrcsStubsSrcJar != nil { 1846 al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsSrcJar) 1847 } else { 1848 rule.Command(). 1849 BuiltTool("soong_zip"). 1850 Flag("-write_if_changed"). 1851 Flag("-jar"). 1852 FlagWithOutput("-o ", al.stubsSrcJar). 1853 FlagWithArg("-C ", stubsDir.String()). 1854 FlagWithArg("-D ", stubsDir.String()) 1855 } 1856 1857 rule.Build("metalava", "metalava merged") 1858 1859 al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, ctx.ModuleName(), "stubs.jar") 1860 al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName())) 1861 1862 var flags javaBuilderFlags 1863 flags.javaVersion = getStubsJavaVersion() 1864 flags.javacFlags = strings.Join(al.properties.Javacflags, " ") 1865 flags.classpath = classpath(classPaths) 1866 1867 TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{}, 1868 android.Paths{al.stubsSrcJar}, flags, android.Paths{}) 1869 1870 builder := android.NewRuleBuilder(pctx, ctx) 1871 builder.Command(). 1872 BuiltTool("merge_zips"). 1873 Output(al.stubsJar). 1874 Inputs(android.Paths{al.stubsJarWithoutStaticLibs}). 1875 Inputs(staticLibs) 1876 builder.Build("merge_zips", "merge jar files") 1877 1878 // compile stubs to .dex for hiddenapi processing 1879 dexParams := &compileDexParams{ 1880 flags: javaBuilderFlags{}, 1881 sdkVersion: al.SdkVersion(ctx), 1882 minSdkVersion: al.MinSdkVersion(ctx), 1883 classesJar: al.stubsJar, 1884 jarName: ctx.ModuleName() + ".jar", 1885 } 1886 dexOutputFile := al.dexer.compileDex(ctx, dexParams) 1887 uncompressed := true 1888 al.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), al.stubsJar, &uncompressed) 1889 dexOutputFile = al.hiddenAPIEncodeDex(ctx, dexOutputFile) 1890 al.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 1891 1892 ctx.Phony(ctx.ModuleName(), al.stubsJar) 1893 1894 ctx.SetProvider(JavaInfoProvider, JavaInfo{ 1895 HeaderJars: android.PathsIfNonNil(al.stubsJar), 1896 ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar), 1897 ImplementationJars: android.PathsIfNonNil(al.stubsJar), 1898 AidlIncludeDirs: android.Paths{}, 1899 }) 1900 1901 ctx.SetProvider(JavaApiLibraryDepsProvider, JavaApiLibraryDepsInfo{ 1902 JavaInfo: JavaInfo{ 1903 HeaderJars: android.PathsIfNonNil(al.stubsJar), 1904 }, 1905 StubsSrcJar: al.stubsSrcJar, 1906 }) 1907} 1908 1909func (al *ApiLibrary) DexJarBuildPath() OptionalDexJarPath { 1910 return al.dexJarFile 1911} 1912 1913func (al *ApiLibrary) DexJarInstallPath() android.Path { 1914 return al.dexJarFile.Path() 1915} 1916 1917func (al *ApiLibrary) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 1918 return nil 1919} 1920 1921// java_api_library constitutes the sdk, and does not build against one 1922func (al *ApiLibrary) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 1923 return android.SdkSpecNone 1924} 1925 1926// java_api_library is always at "current". Return FutureApiLevel 1927func (al *ApiLibrary) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 1928 return android.FutureApiLevel 1929} 1930 1931// implement the following interfaces for hiddenapi processing 1932var _ hiddenAPIModule = (*ApiLibrary)(nil) 1933var _ UsesLibraryDependency = (*ApiLibrary)(nil) 1934 1935// 1936// Java prebuilts 1937// 1938 1939type ImportProperties struct { 1940 Jars []string `android:"path,arch_variant"` 1941 1942 // The version of the SDK that the source prebuilt file was built against. Defaults to the 1943 // current version if not specified. 1944 Sdk_version *string 1945 1946 // The minimum version of the SDK that this module supports. Defaults to sdk_version if not 1947 // specified. 1948 Min_sdk_version *string 1949 1950 // The max sdk version placeholder used to replace maxSdkVersion attributes on permission 1951 // and uses-permission tags in manifest_fixer. 1952 Replace_max_sdk_version_placeholder *string 1953 1954 Installable *bool 1955 1956 // If not empty, classes are restricted to the specified packages and their sub-packages. 1957 Permitted_packages []string 1958 1959 // List of shared java libs that this module has dependencies to 1960 Libs []string 1961 1962 // List of files to remove from the jar file(s) 1963 Exclude_files []string 1964 1965 // List of directories to remove from the jar file(s) 1966 Exclude_dirs []string 1967 1968 // if set to true, run Jetifier against .jar file. Defaults to false. 1969 Jetifier *bool 1970 1971 // set the name of the output 1972 Stem *string 1973 1974 Aidl struct { 1975 // directories that should be added as include directories for any aidl sources of modules 1976 // that depend on this module, as well as to aidl for this module. 1977 Export_include_dirs []string 1978 } 1979} 1980 1981type Import struct { 1982 android.ModuleBase 1983 android.DefaultableModuleBase 1984 android.ApexModuleBase 1985 android.BazelModuleBase 1986 prebuilt android.Prebuilt 1987 1988 // Functionality common to Module and Import. 1989 embeddableInModuleAndImport 1990 1991 hiddenAPI 1992 dexer 1993 dexpreopter 1994 1995 properties ImportProperties 1996 1997 // output file containing classes.dex and resources 1998 dexJarFile OptionalDexJarPath 1999 dexJarInstallFile android.Path 2000 2001 combinedClasspathFile android.Path 2002 classLoaderContexts dexpreopt.ClassLoaderContextMap 2003 exportAidlIncludeDirs android.Paths 2004 2005 hideApexVariantFromMake bool 2006 2007 sdkVersion android.SdkSpec 2008 minSdkVersion android.ApiLevel 2009} 2010 2011var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil) 2012 2013func (j *Import) PermittedPackagesForUpdatableBootJars() []string { 2014 return j.properties.Permitted_packages 2015} 2016 2017func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 2018 return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version)) 2019} 2020 2021func (j *Import) SystemModules() string { 2022 return "none" 2023} 2024 2025func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 2026 if j.properties.Min_sdk_version != nil { 2027 return android.ApiLevelFrom(ctx, *j.properties.Min_sdk_version) 2028 } 2029 return j.SdkVersion(ctx).ApiLevel 2030} 2031 2032func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.ApiLevel { 2033 if j.properties.Replace_max_sdk_version_placeholder != nil { 2034 return android.ApiLevelFrom(ctx, *j.properties.Replace_max_sdk_version_placeholder) 2035 } 2036 // Default is PrivateApiLevel 2037 return android.SdkSpecPrivate.ApiLevel 2038} 2039 2040func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel { 2041 return j.SdkVersion(ctx).ApiLevel 2042} 2043 2044func (j *Import) Prebuilt() *android.Prebuilt { 2045 return &j.prebuilt 2046} 2047 2048func (j *Import) PrebuiltSrcs() []string { 2049 return j.properties.Jars 2050} 2051 2052func (j *Import) Name() string { 2053 return j.prebuilt.Name(j.ModuleBase.Name()) 2054} 2055 2056func (j *Import) Stem() string { 2057 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 2058} 2059 2060func (a *Import) JacocoReportClassesFile() android.Path { 2061 return nil 2062} 2063 2064func (j *Import) LintDepSets() LintDepSets { 2065 return LintDepSets{} 2066} 2067 2068func (j *Import) getStrictUpdatabilityLinting() bool { 2069 return false 2070} 2071 2072func (j *Import) setStrictUpdatabilityLinting(bool) { 2073} 2074 2075func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { 2076 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) 2077 2078 if ctx.Device() && Bool(j.dexProperties.Compile_dex) { 2079 sdkDeps(ctx, android.SdkContext(j), j.dexer) 2080 } 2081} 2082 2083func (j *Import) commonBuildActions(ctx android.ModuleContext) { 2084 //TODO(b/231322772) these should come from Bazel once available 2085 j.sdkVersion = j.SdkVersion(ctx) 2086 j.minSdkVersion = j.MinSdkVersion(ctx) 2087 2088 if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() { 2089 j.hideApexVariantFromMake = true 2090 } 2091 2092 if ctx.Windows() { 2093 j.HideFromMake() 2094 } 2095} 2096 2097func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2098 j.commonBuildActions(ctx) 2099 2100 jars := android.PathsForModuleSrc(ctx, j.properties.Jars) 2101 2102 jarName := j.Stem() + ".jar" 2103 outputFile := android.PathForModuleOut(ctx, "combined", jarName) 2104 TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{}, 2105 false, j.properties.Exclude_files, j.properties.Exclude_dirs) 2106 if Bool(j.properties.Jetifier) { 2107 inputFile := outputFile 2108 outputFile = android.PathForModuleOut(ctx, "jetifier", jarName) 2109 TransformJetifier(ctx, outputFile, inputFile) 2110 } 2111 j.combinedClasspathFile = outputFile 2112 j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) 2113 2114 var flags javaBuilderFlags 2115 2116 j.collectTransitiveHeaderJars(ctx) 2117 ctx.VisitDirectDeps(func(module android.Module) { 2118 tag := ctx.OtherModuleDependencyTag(module) 2119 if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { 2120 dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) 2121 switch tag { 2122 case libTag, sdkLibTag: 2123 flags.classpath = append(flags.classpath, dep.HeaderJars...) 2124 flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...) 2125 case staticLibTag: 2126 flags.classpath = append(flags.classpath, dep.HeaderJars...) 2127 case bootClasspathTag: 2128 flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...) 2129 } 2130 } else if dep, ok := module.(SdkLibraryDependency); ok { 2131 switch tag { 2132 case libTag, sdkLibTag: 2133 flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...) 2134 } 2135 } 2136 2137 addCLCFromDep(ctx, module, j.classLoaderContexts) 2138 }) 2139 2140 j.maybeInstall(ctx, jarName, outputFile) 2141 2142 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) 2143 2144 if ctx.Device() { 2145 // If this is a variant created for a prebuilt_apex then use the dex implementation jar 2146 // obtained from the associated deapexer module. 2147 ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 2148 if ai.ForPrebuiltApex { 2149 // Get the path of the dex implementation jar from the `deapexer` module. 2150 di := android.FindDeapexerProviderForModule(ctx) 2151 if di == nil { 2152 return // An error has been reported by FindDeapexerProviderForModule. 2153 } 2154 dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName()) 2155 if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil { 2156 dexJarFile := makeDexJarPathFromPath(dexOutputPath) 2157 j.dexJarFile = dexJarFile 2158 installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName())) 2159 j.dexJarInstallFile = installPath 2160 2161 j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath) 2162 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 2163 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 2164 2165 if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil { 2166 j.dexpreopter.inputProfilePathOnHost = profilePath 2167 } 2168 2169 j.dexpreopt(ctx, dexOutputPath) 2170 2171 // Initialize the hiddenapi structure. 2172 j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex) 2173 } else { 2174 // This should never happen as a variant for a prebuilt_apex is only created if the 2175 // prebuilt_apex has been configured to export the java library dex file. 2176 ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName()) 2177 } 2178 } else if Bool(j.dexProperties.Compile_dex) { 2179 sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) 2180 if sdkDep.invalidVersion { 2181 ctx.AddMissingDependencies(sdkDep.bootclasspath) 2182 ctx.AddMissingDependencies(sdkDep.java9Classpath) 2183 } else if sdkDep.useFiles { 2184 // sdkDep.jar is actually equivalent to turbine header.jar. 2185 flags.classpath = append(flags.classpath, sdkDep.jars...) 2186 } 2187 2188 // Dex compilation 2189 2190 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 2191 ctx, android.PathForModuleInstall(ctx, "framework", jarName)) 2192 setUncompressDex(ctx, &j.dexpreopter, &j.dexer) 2193 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 2194 2195 var dexOutputFile android.OutputPath 2196 dexParams := &compileDexParams{ 2197 flags: flags, 2198 sdkVersion: j.SdkVersion(ctx), 2199 minSdkVersion: j.MinSdkVersion(ctx), 2200 classesJar: outputFile, 2201 jarName: jarName, 2202 } 2203 2204 dexOutputFile = j.dexer.compileDex(ctx, dexParams) 2205 if ctx.Failed() { 2206 return 2207 } 2208 2209 // Initialize the hiddenapi structure. 2210 j.initHiddenAPI(ctx, makeDexJarPathFromPath(dexOutputFile), outputFile, j.dexProperties.Uncompress_dex) 2211 2212 // Encode hidden API flags in dex file. 2213 dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) 2214 2215 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 2216 j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName) 2217 } 2218 } 2219 2220 ctx.SetProvider(JavaInfoProvider, JavaInfo{ 2221 HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile), 2222 TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars, 2223 TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars, 2224 ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), 2225 ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile), 2226 AidlIncludeDirs: j.exportAidlIncludeDirs, 2227 }) 2228} 2229 2230func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputFile android.Path) { 2231 if !Bool(j.properties.Installable) { 2232 return 2233 } 2234 2235 var installDir android.InstallPath 2236 if ctx.InstallInTestcases() { 2237 var archDir string 2238 if !ctx.Host() { 2239 archDir = ctx.DeviceConfig().DeviceArch() 2240 } 2241 installDir = android.PathForModuleInstall(ctx, ctx.ModuleName(), archDir) 2242 } else { 2243 installDir = android.PathForModuleInstall(ctx, "framework") 2244 } 2245 ctx.InstallFile(installDir, jarName, outputFile) 2246} 2247 2248func (j *Import) OutputFiles(tag string) (android.Paths, error) { 2249 switch tag { 2250 case "", ".jar": 2251 return android.Paths{j.combinedClasspathFile}, nil 2252 default: 2253 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 2254 } 2255} 2256 2257var _ android.OutputFileProducer = (*Import)(nil) 2258 2259func (j *Import) HeaderJars() android.Paths { 2260 if j.combinedClasspathFile == nil { 2261 return nil 2262 } 2263 return android.Paths{j.combinedClasspathFile} 2264} 2265 2266func (j *Import) ImplementationAndResourcesJars() android.Paths { 2267 if j.combinedClasspathFile == nil { 2268 return nil 2269 } 2270 return android.Paths{j.combinedClasspathFile} 2271} 2272 2273func (j *Import) DexJarBuildPath() OptionalDexJarPath { 2274 return j.dexJarFile 2275} 2276 2277func (j *Import) DexJarInstallPath() android.Path { 2278 return j.dexJarInstallFile 2279} 2280 2281func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 2282 return j.classLoaderContexts 2283} 2284 2285var _ android.ApexModule = (*Import)(nil) 2286 2287// Implements android.ApexModule 2288func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 2289 return j.depIsInSameApex(ctx, dep) 2290} 2291 2292// Implements android.ApexModule 2293func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 2294 sdkVersion android.ApiLevel) error { 2295 sdkVersionSpec := j.SdkVersion(ctx) 2296 minSdkVersion := j.MinSdkVersion(ctx) 2297 if !minSdkVersion.Specified() { 2298 return fmt.Errorf("min_sdk_version is not specified") 2299 } 2300 // If the module is compiling against core (via sdk_version), skip comparison check. 2301 if sdkVersionSpec.Kind == android.SdkCore { 2302 return nil 2303 } 2304 if minSdkVersion.GreaterThan(sdkVersion) { 2305 return fmt.Errorf("newer SDK(%v)", minSdkVersion) 2306 } 2307 return nil 2308} 2309 2310// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or 2311// java_sdk_library_import with the specified base module name requires to be exported from a 2312// prebuilt_apex/apex_set. 2313func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string { 2314 dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(name) 2315 // Add the dex implementation jar to the set of exported files. 2316 files := []string{ 2317 dexJarFileApexRootRelative, 2318 } 2319 if BoolDefault(d.importDexpreoptProperties.Dex_preopt.Profile_guided, false) { 2320 files = append(files, dexJarFileApexRootRelative+".prof") 2321 } 2322 return files 2323} 2324 2325// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for 2326// the java library with the specified name. 2327func apexRootRelativePathToJavaLib(name string) string { 2328 return filepath.Join("javalib", name+".jar") 2329} 2330 2331var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil) 2332 2333func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string { 2334 name := j.BaseModuleName() 2335 return requiredFilesFromPrebuiltApexForImport(name, &j.dexpreopter) 2336} 2337 2338// Add compile time check for interface implementation 2339var _ android.IDEInfo = (*Import)(nil) 2340var _ android.IDECustomizedModuleName = (*Import)(nil) 2341 2342// Collect information for opening IDE project files in java/jdeps.go. 2343 2344func (j *Import) IDEInfo(dpInfo *android.IdeInfo) { 2345 dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...) 2346} 2347 2348func (j *Import) IDECustomizedModuleName() string { 2349 // TODO(b/113562217): Extract the base module name from the Import name, often the Import name 2350 // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better 2351 // solution to get the Import name. 2352 return android.RemoveOptionalPrebuiltPrefix(j.Name()) 2353} 2354 2355var _ android.PrebuiltInterface = (*Import)(nil) 2356 2357func (j *Import) IsInstallable() bool { 2358 return Bool(j.properties.Installable) 2359} 2360 2361var _ DexpreopterInterface = (*Import)(nil) 2362 2363// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module. 2364// 2365// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were 2366// compiled against an Android classpath. 2367// 2368// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 2369// for host modules. 2370func ImportFactory() android.Module { 2371 module := &Import{} 2372 2373 module.AddProperties( 2374 &module.properties, 2375 &module.dexer.dexProperties, 2376 &module.importDexpreoptProperties, 2377 ) 2378 2379 module.initModuleAndImport(module) 2380 2381 module.dexProperties.Optimize.EnabledByDefault = false 2382 2383 android.InitPrebuiltModule(module, &module.properties.Jars) 2384 android.InitApexModule(module) 2385 android.InitBazelModule(module) 2386 InitJavaModule(module, android.HostAndDeviceSupported) 2387 return module 2388} 2389 2390// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host 2391// module. 2392// 2393// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were 2394// compiled against a host bootclasspath. 2395func ImportFactoryHost() android.Module { 2396 module := &Import{} 2397 2398 module.AddProperties(&module.properties) 2399 2400 android.InitPrebuiltModule(module, &module.properties.Jars) 2401 android.InitApexModule(module) 2402 android.InitBazelModule(module) 2403 InitJavaModule(module, android.HostSupported) 2404 return module 2405} 2406 2407// dex_import module 2408 2409type DexImportProperties struct { 2410 Jars []string `android:"path"` 2411 2412 // set the name of the output 2413 Stem *string 2414} 2415 2416type DexImport struct { 2417 android.ModuleBase 2418 android.DefaultableModuleBase 2419 android.ApexModuleBase 2420 prebuilt android.Prebuilt 2421 2422 properties DexImportProperties 2423 2424 dexJarFile OptionalDexJarPath 2425 2426 dexpreopter 2427 2428 hideApexVariantFromMake bool 2429} 2430 2431func (j *DexImport) Prebuilt() *android.Prebuilt { 2432 return &j.prebuilt 2433} 2434 2435func (j *DexImport) PrebuiltSrcs() []string { 2436 return j.properties.Jars 2437} 2438 2439func (j *DexImport) Name() string { 2440 return j.prebuilt.Name(j.ModuleBase.Name()) 2441} 2442 2443func (j *DexImport) Stem() string { 2444 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 2445} 2446 2447func (a *DexImport) JacocoReportClassesFile() android.Path { 2448 return nil 2449} 2450 2451func (a *DexImport) LintDepSets() LintDepSets { 2452 return LintDepSets{} 2453} 2454 2455func (j *DexImport) IsInstallable() bool { 2456 return true 2457} 2458 2459func (j *DexImport) getStrictUpdatabilityLinting() bool { 2460 return false 2461} 2462 2463func (j *DexImport) setStrictUpdatabilityLinting(bool) { 2464} 2465 2466func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 2467 if len(j.properties.Jars) != 1 { 2468 ctx.PropertyErrorf("jars", "exactly one jar must be provided") 2469 } 2470 2471 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 2472 if !apexInfo.IsForPlatform() { 2473 j.hideApexVariantFromMake = true 2474 } 2475 2476 j.dexpreopter.installPath = j.dexpreopter.getInstallPath( 2477 ctx, android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")) 2478 j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) 2479 2480 inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") 2481 dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar") 2482 2483 if j.dexpreopter.uncompressedDex { 2484 rule := android.NewRuleBuilder(pctx, ctx) 2485 2486 temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned") 2487 rule.Temporary(temporary) 2488 2489 // use zip2zip to uncompress classes*.dex files 2490 rule.Command(). 2491 BuiltTool("zip2zip"). 2492 FlagWithInput("-i ", inputJar). 2493 FlagWithOutput("-o ", temporary). 2494 FlagWithArg("-0 ", "'classes*.dex'") 2495 2496 // use zipalign to align uncompressed classes*.dex files 2497 rule.Command(). 2498 BuiltTool("zipalign"). 2499 Flag("-f"). 2500 Text("4"). 2501 Input(temporary). 2502 Output(dexOutputFile) 2503 2504 rule.DeleteTemporaryFiles() 2505 2506 rule.Build("uncompress_dex", "uncompress dex") 2507 } else { 2508 ctx.Build(pctx, android.BuildParams{ 2509 Rule: android.Cp, 2510 Input: inputJar, 2511 Output: dexOutputFile, 2512 }) 2513 } 2514 2515 j.dexJarFile = makeDexJarPathFromPath(dexOutputFile) 2516 2517 j.dexpreopt(ctx, dexOutputFile) 2518 2519 if apexInfo.IsForPlatform() { 2520 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 2521 j.Stem()+".jar", dexOutputFile) 2522 } 2523} 2524 2525func (j *DexImport) DexJarBuildPath() OptionalDexJarPath { 2526 return j.dexJarFile 2527} 2528 2529var _ android.ApexModule = (*DexImport)(nil) 2530 2531// Implements android.ApexModule 2532func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 2533 sdkVersion android.ApiLevel) error { 2534 // we don't check prebuilt modules for sdk_version 2535 return nil 2536} 2537 2538// dex_import imports a `.jar` file containing classes.dex files. 2539// 2540// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed 2541// to the device. 2542func DexImportFactory() android.Module { 2543 module := &DexImport{} 2544 2545 module.AddProperties(&module.properties) 2546 2547 android.InitPrebuiltModule(module, &module.properties.Jars) 2548 android.InitApexModule(module) 2549 InitJavaModule(module, android.DeviceSupported) 2550 return module 2551} 2552 2553// Defaults 2554type Defaults struct { 2555 android.ModuleBase 2556 android.DefaultsModuleBase 2557 android.ApexModuleBase 2558} 2559 2560// java_defaults provides a set of properties that can be inherited by other java or android modules. 2561// 2562// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`. Each 2563// property in the defaults module that exists in the depending module will be prepended to the depending module's 2564// value for that property. 2565// 2566// Example: 2567// 2568// java_defaults { 2569// name: "example_defaults", 2570// srcs: ["common/**/*.java"], 2571// javacflags: ["-Xlint:all"], 2572// aaptflags: ["--auto-add-overlay"], 2573// } 2574// 2575// java_library { 2576// name: "example", 2577// defaults: ["example_defaults"], 2578// srcs: ["example/**/*.java"], 2579// } 2580// 2581// is functionally identical to: 2582// 2583// java_library { 2584// name: "example", 2585// srcs: [ 2586// "common/**/*.java", 2587// "example/**/*.java", 2588// ], 2589// javacflags: ["-Xlint:all"], 2590// } 2591func DefaultsFactory() android.Module { 2592 module := &Defaults{} 2593 2594 module.AddProperties( 2595 &CommonProperties{}, 2596 &DeviceProperties{}, 2597 &OverridableDeviceProperties{}, 2598 &DexProperties{}, 2599 &DexpreoptProperties{}, 2600 &android.ProtoProperties{}, 2601 &aaptProperties{}, 2602 &androidLibraryProperties{}, 2603 &appProperties{}, 2604 &appTestProperties{}, 2605 &overridableAppProperties{}, 2606 &testProperties{}, 2607 &ImportProperties{}, 2608 &AARImportProperties{}, 2609 &sdkLibraryProperties{}, 2610 &commonToSdkLibraryAndImportProperties{}, 2611 &DexImportProperties{}, 2612 &android.ApexProperties{}, 2613 &RuntimeResourceOverlayProperties{}, 2614 &LintProperties{}, 2615 &appTestHelperAppProperties{}, 2616 &JavaApiLibraryProperties{}, 2617 ) 2618 2619 android.InitDefaultsModule(module) 2620 return module 2621} 2622 2623func kytheExtractJavaFactory() android.Singleton { 2624 return &kytheExtractJavaSingleton{} 2625} 2626 2627type kytheExtractJavaSingleton struct { 2628} 2629 2630func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) { 2631 var xrefTargets android.Paths 2632 ctx.VisitAllModules(func(module android.Module) { 2633 if javaModule, ok := module.(xref); ok { 2634 xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...) 2635 } 2636 }) 2637 // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets 2638 if len(xrefTargets) > 0 { 2639 ctx.Phony("xref_java", xrefTargets...) 2640 } 2641} 2642 2643var Bool = proptools.Bool 2644var BoolDefault = proptools.BoolDefault 2645var String = proptools.String 2646var inList = android.InList 2647 2648// Add class loader context (CLC) of a given dependency to the current CLC. 2649func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, 2650 clcMap dexpreopt.ClassLoaderContextMap) { 2651 2652 dep, ok := depModule.(UsesLibraryDependency) 2653 if !ok { 2654 return 2655 } 2656 2657 depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule)) 2658 2659 var sdkLib *string 2660 if lib, ok := depModule.(SdkLibraryDependency); ok && lib.sharedLibrary() { 2661 // A shared SDK library. This should be added as a top-level CLC element. 2662 sdkLib = &depName 2663 } else if ulib, ok := depModule.(ProvidesUsesLib); ok { 2664 // A non-SDK library disguised as an SDK library by the means of `provides_uses_lib` 2665 // property. This should be handled in the same way as a shared SDK library. 2666 sdkLib = ulib.ProvidesUsesLib() 2667 } 2668 2669 depTag := ctx.OtherModuleDependencyTag(depModule) 2670 if IsLibDepTag(depTag) { 2671 // Ok, propagate <uses-library> through non-static library dependencies. 2672 } else if tag, ok := depTag.(usesLibraryDependencyTag); ok && tag.sdkVersion == dexpreopt.AnySdkVersion { 2673 // Ok, propagate <uses-library> through non-compatibility <uses-library> dependencies. 2674 } else if depTag == staticLibTag { 2675 // Propagate <uses-library> through static library dependencies, unless it is a component 2676 // library (such as stubs). Component libraries have a dependency on their SDK library, 2677 // which should not be pulled just because of a static component library. 2678 if sdkLib != nil { 2679 return 2680 } 2681 } else { 2682 // Don't propagate <uses-library> for other dependency tags. 2683 return 2684 } 2685 2686 // If this is an SDK (or SDK-like) library, then it should be added as a node in the CLC tree, 2687 // and its CLC should be added as subtree of that node. Otherwise the library is not a 2688 // <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies 2689 // from its CLC should be added to the current CLC. 2690 if sdkLib != nil { 2691 clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, 2692 dep.DexJarBuildPath().PathOrNil(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) 2693 } else { 2694 clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) 2695 } 2696} 2697 2698type javaResourcesAttributes struct { 2699 Resources bazel.LabelListAttribute 2700 Resource_strip_prefix *string 2701} 2702 2703func (m *Library) convertJavaResourcesAttributes(ctx android.TopDownMutatorContext) *javaResourcesAttributes { 2704 var resources bazel.LabelList 2705 var resourceStripPrefix *string 2706 2707 if m.properties.Java_resources != nil { 2708 resources.Append(android.BazelLabelForModuleSrc(ctx, m.properties.Java_resources)) 2709 } 2710 2711 //TODO(b/179889880) handle case where glob includes files outside package 2712 resDeps := ResourceDirsToFiles( 2713 ctx, 2714 m.properties.Java_resource_dirs, 2715 m.properties.Exclude_java_resource_dirs, 2716 m.properties.Exclude_java_resources, 2717 ) 2718 2719 for i, resDep := range resDeps { 2720 dir, files := resDep.dir, resDep.files 2721 2722 resources.Append(bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, files))) 2723 2724 // Bazel includes the relative path from the WORKSPACE root when placing the resource 2725 // inside the JAR file, so we need to remove that prefix 2726 resourceStripPrefix = proptools.StringPtr(dir.String()) 2727 if i > 0 { 2728 // TODO(b/226423379) allow multiple resource prefixes 2729 ctx.ModuleErrorf("bp2build does not support more than one directory in java_resource_dirs (b/226423379)") 2730 } 2731 } 2732 2733 return &javaResourcesAttributes{ 2734 Resources: bazel.MakeLabelListAttribute(resources), 2735 Resource_strip_prefix: resourceStripPrefix, 2736 } 2737} 2738 2739type javaCommonAttributes struct { 2740 *javaResourcesAttributes 2741 *kotlinAttributes 2742 Srcs bazel.LabelListAttribute 2743 Plugins bazel.LabelListAttribute 2744 Javacopts bazel.StringListAttribute 2745 Sdk_version bazel.StringAttribute 2746 Java_version bazel.StringAttribute 2747} 2748 2749type javaDependencyLabels struct { 2750 // Dependencies which DO NOT contribute to the API visible to upstream dependencies. 2751 Deps bazel.LabelListAttribute 2752 // Dependencies which DO contribute to the API visible to upstream dependencies. 2753 StaticDeps bazel.LabelListAttribute 2754} 2755 2756type eventLogTagsAttributes struct { 2757 Srcs bazel.LabelListAttribute 2758} 2759 2760type aidlLibraryAttributes struct { 2761 Srcs bazel.LabelListAttribute 2762 Tags bazel.StringListAttribute 2763} 2764 2765type javaAidlLibraryAttributes struct { 2766 Deps bazel.LabelListAttribute 2767 Tags bazel.StringListAttribute 2768} 2769 2770// bp2BuildJavaInfo has information needed for the conversion of java*_modules 2771// that is needed bor Bp2Build conversion but that requires different handling 2772// depending on the module type. 2773type bp2BuildJavaInfo struct { 2774 // separates dependencies into dynamic dependencies and static dependencies. 2775 DepLabels *javaDependencyLabels 2776 hasKotlin bool 2777} 2778 2779// convertLibraryAttrsBp2Build returns a javaCommonAttributes struct with 2780// converted attributes shared across java_* modules and a bp2BuildJavaInfo struct 2781// which has other non-attribute information needed for bp2build conversion 2782// that needs different handling depending on the module types, and thus needs 2783// to be returned to the calling function. 2784func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *bp2BuildJavaInfo) { 2785 var srcs bazel.LabelListAttribute 2786 var deps bazel.LabelListAttribute 2787 var staticDeps bazel.LabelList 2788 2789 archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{}) 2790 for axis, configToProps := range archVariantProps { 2791 for config, _props := range configToProps { 2792 if archProps, ok := _props.(*CommonProperties); ok { 2793 archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs) 2794 srcs.SetSelectValue(axis, config, archSrcs) 2795 } 2796 } 2797 } 2798 srcs.ResolveExcludes() 2799 2800 javaSrcPartition := "java" 2801 protoSrcPartition := "proto" 2802 logtagSrcPartition := "logtag" 2803 aidlSrcPartition := "aidl" 2804 kotlinPartition := "kotlin" 2805 srcPartitions := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{ 2806 javaSrcPartition: bazel.LabelPartition{Extensions: []string{".java"}, Keep_remainder: true}, 2807 logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}}, 2808 protoSrcPartition: android.ProtoSrcLabelPartition, 2809 aidlSrcPartition: android.AidlSrcLabelPartition, 2810 kotlinPartition: bazel.LabelPartition{Extensions: []string{".kt"}}, 2811 }) 2812 2813 javaSrcs := srcPartitions[javaSrcPartition] 2814 kotlinSrcs := srcPartitions[kotlinPartition] 2815 javaSrcs.Append(kotlinSrcs) 2816 2817 if !srcPartitions[logtagSrcPartition].IsEmpty() { 2818 logtagsLibName := m.Name() + "_logtags" 2819 ctx.CreateBazelTargetModule( 2820 bazel.BazelTargetModuleProperties{ 2821 Rule_class: "event_log_tags", 2822 Bzl_load_location: "//build/bazel/rules/java:event_log_tags.bzl", 2823 }, 2824 android.CommonAttributes{Name: logtagsLibName}, 2825 &eventLogTagsAttributes{ 2826 Srcs: srcPartitions[logtagSrcPartition], 2827 }, 2828 ) 2829 2830 logtagsSrcs := bazel.MakeLabelList([]bazel.Label{{Label: ":" + logtagsLibName}}) 2831 javaSrcs.Append(bazel.MakeLabelListAttribute(logtagsSrcs)) 2832 } 2833 2834 if !srcPartitions[aidlSrcPartition].IsEmpty() { 2835 aidlLibs, aidlSrcs := srcPartitions[aidlSrcPartition].Partition(func(src bazel.Label) bool { 2836 return android.IsConvertedToAidlLibrary(ctx, src.OriginalModuleName) 2837 }) 2838 2839 apexAvailableTags := android.ApexAvailableTags(ctx.Module()) 2840 2841 if !aidlSrcs.IsEmpty() { 2842 aidlLibName := m.Name() + "_aidl_library" 2843 ctx.CreateBazelTargetModule( 2844 bazel.BazelTargetModuleProperties{ 2845 Rule_class: "aidl_library", 2846 Bzl_load_location: "//build/bazel/rules/aidl:aidl_library.bzl", 2847 }, 2848 android.CommonAttributes{Name: aidlLibName}, 2849 &aidlLibraryAttributes{ 2850 Srcs: aidlSrcs, 2851 Tags: apexAvailableTags, 2852 }, 2853 ) 2854 aidlLibs.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + aidlLibName}}) 2855 } 2856 2857 javaAidlLibName := m.Name() + "_java_aidl_library" 2858 ctx.CreateBazelTargetModule( 2859 bazel.BazelTargetModuleProperties{ 2860 Rule_class: "java_aidl_library", 2861 Bzl_load_location: "//build/bazel/rules/java:java_aidl_library.bzl", 2862 }, 2863 android.CommonAttributes{Name: javaAidlLibName}, 2864 &javaAidlLibraryAttributes{ 2865 Deps: aidlLibs, 2866 Tags: apexAvailableTags, 2867 }, 2868 ) 2869 2870 staticDeps.Add(&bazel.Label{Label: ":" + javaAidlLibName}) 2871 } 2872 2873 var javacopts []string 2874 if m.properties.Javacflags != nil { 2875 javacopts = append(javacopts, m.properties.Javacflags...) 2876 } 2877 2878 epEnabled := m.properties.Errorprone.Enabled 2879 //TODO(b/227504307) add configuration that depends on RUN_ERROR_PRONE environment variable 2880 if Bool(epEnabled) { 2881 javacopts = append(javacopts, m.properties.Errorprone.Javacflags...) 2882 } 2883 2884 commonAttrs := &javaCommonAttributes{ 2885 Srcs: javaSrcs, 2886 javaResourcesAttributes: m.convertJavaResourcesAttributes(ctx), 2887 Plugins: bazel.MakeLabelListAttribute( 2888 android.BazelLabelForModuleDeps(ctx, m.properties.Plugins), 2889 ), 2890 Javacopts: bazel.MakeStringListAttribute(javacopts), 2891 Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, 2892 Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, 2893 } 2894 2895 for axis, configToProps := range archVariantProps { 2896 for config, _props := range configToProps { 2897 if archProps, ok := _props.(*CommonProperties); ok { 2898 var libLabels []bazel.Label 2899 for _, d := range archProps.Libs { 2900 neverlinkLabel := android.BazelLabelForModuleDepSingle(ctx, d) 2901 neverlinkLabel.Label = neverlinkLabel.Label + "-neverlink" 2902 libLabels = append(libLabels, neverlinkLabel) 2903 } 2904 deps.SetSelectValue(axis, config, bazel.MakeLabelList(libLabels)) 2905 } 2906 } 2907 } 2908 2909 protoDepLabel := bp2buildProto(ctx, &m.Module, srcPartitions[protoSrcPartition]) 2910 // Soong does not differentiate between a java_library and the Bazel equivalent of 2911 // a java_proto_library + proto_library pair. Instead, in Soong proto sources are 2912 // listed directly in the srcs of a java_library, and the classes produced 2913 // by protoc are included directly in the resulting JAR. Thus upstream dependencies 2914 // that depend on a java_library with proto sources can link directly to the protobuf API, 2915 // and so this should be a static dependency. 2916 staticDeps.Add(protoDepLabel) 2917 2918 depLabels := &javaDependencyLabels{} 2919 depLabels.Deps = deps 2920 2921 for axis, configToProps := range archVariantProps { 2922 for config, _props := range configToProps { 2923 if archProps, ok := _props.(*CommonProperties); ok { 2924 archStaticLibs := android.BazelLabelForModuleDeps( 2925 ctx, 2926 android.LastUniqueStrings(android.CopyOf(archProps.Static_libs))) 2927 depLabels.StaticDeps.SetSelectValue(axis, config, archStaticLibs) 2928 } 2929 } 2930 } 2931 depLabels.StaticDeps.Value.Append(staticDeps) 2932 2933 hasKotlin := !kotlinSrcs.IsEmpty() 2934 commonAttrs.kotlinAttributes = &kotlinAttributes{ 2935 Kotlincflags: &m.properties.Kotlincflags, 2936 } 2937 if len(m.properties.Common_srcs) != 0 { 2938 hasKotlin = true 2939 commonAttrs.kotlinAttributes.Common_srcs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Common_srcs)) 2940 } 2941 2942 bp2BuildInfo := &bp2BuildJavaInfo{ 2943 DepLabels: depLabels, 2944 hasKotlin: hasKotlin, 2945 } 2946 2947 return commonAttrs, bp2BuildInfo 2948} 2949 2950type javaLibraryAttributes struct { 2951 *javaCommonAttributes 2952 Deps bazel.LabelListAttribute 2953 Exports bazel.LabelListAttribute 2954 Neverlink bazel.BoolAttribute 2955} 2956 2957type kotlinAttributes struct { 2958 Common_srcs bazel.LabelListAttribute 2959 Kotlincflags *[]string 2960} 2961 2962func ktJvmLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties { 2963 return bazel.BazelTargetModuleProperties{ 2964 Rule_class: "kt_jvm_library", 2965 Bzl_load_location: "//build/bazel/rules/kotlin:rules.bzl", 2966 } 2967} 2968 2969func javaLibraryBazelTargetModuleProperties() bazel.BazelTargetModuleProperties { 2970 return bazel.BazelTargetModuleProperties{ 2971 Rule_class: "java_library", 2972 Bzl_load_location: "//build/bazel/rules/java:rules.bzl", 2973 } 2974} 2975 2976func javaLibraryBp2Build(ctx android.TopDownMutatorContext, m *Library) { 2977 commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx) 2978 depLabels := bp2BuildInfo.DepLabels 2979 2980 deps := depLabels.Deps 2981 if !commonAttrs.Srcs.IsEmpty() { 2982 deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them 2983 } else if !deps.IsEmpty() { 2984 ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") 2985 } 2986 var props bazel.BazelTargetModuleProperties 2987 attrs := &javaLibraryAttributes{ 2988 javaCommonAttributes: commonAttrs, 2989 Deps: deps, 2990 Exports: depLabels.StaticDeps, 2991 } 2992 name := m.Name() 2993 2994 if !bp2BuildInfo.hasKotlin { 2995 props = javaLibraryBazelTargetModuleProperties() 2996 } else { 2997 props = ktJvmLibraryBazelTargetModuleProperties() 2998 } 2999 3000 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs) 3001 neverlinkProp := true 3002 neverLinkAttrs := &javaLibraryAttributes{ 3003 Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), 3004 Neverlink: bazel.BoolAttribute{Value: &neverlinkProp}, 3005 javaCommonAttributes: &javaCommonAttributes{ 3006 Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version}, 3007 Java_version: bazel.StringAttribute{Value: m.properties.Java_version}, 3008 }, 3009 } 3010 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name + "-neverlink"}, neverLinkAttrs) 3011 3012} 3013 3014type javaBinaryHostAttributes struct { 3015 *javaCommonAttributes 3016 Deps bazel.LabelListAttribute 3017 Runtime_deps bazel.LabelListAttribute 3018 Main_class string 3019 Jvm_flags bazel.StringListAttribute 3020} 3021 3022// JavaBinaryHostBp2Build is for java_binary_host bp2build. 3023func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { 3024 commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx) 3025 depLabels := bp2BuildInfo.DepLabels 3026 3027 deps := depLabels.Deps 3028 deps.Append(depLabels.StaticDeps) 3029 if m.binaryProperties.Jni_libs != nil { 3030 deps.Append(bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs))) 3031 } 3032 3033 var runtimeDeps bazel.LabelListAttribute 3034 if commonAttrs.Srcs.IsEmpty() { 3035 // if there are no sources, then the dependencies can only be used at runtime 3036 runtimeDeps = deps 3037 deps = bazel.LabelListAttribute{} 3038 } 3039 3040 mainClass := "" 3041 if m.binaryProperties.Main_class != nil { 3042 mainClass = *m.binaryProperties.Main_class 3043 } 3044 if m.properties.Manifest != nil { 3045 mainClassInManifest, err := android.GetMainClassInManifest(ctx.Config(), android.PathForModuleSrc(ctx, *m.properties.Manifest).String()) 3046 if err != nil { 3047 return 3048 } 3049 mainClass = mainClassInManifest 3050 } 3051 3052 // Attribute jvm_flags 3053 var jvmFlags bazel.StringListAttribute 3054 if m.binaryProperties.Jni_libs != nil { 3055 jniLibPackages := map[string]bool{} 3056 for _, jniLibLabel := range android.BazelLabelForModuleDeps(ctx, m.binaryProperties.Jni_libs).Includes { 3057 jniLibPackage := jniLibLabel.Label 3058 indexOfColon := strings.Index(jniLibLabel.Label, ":") 3059 if indexOfColon > 0 { 3060 // JNI lib from other package 3061 jniLibPackage = jniLibLabel.Label[2:indexOfColon] 3062 } else if indexOfColon == 0 { 3063 // JNI lib in the same package of java_binary 3064 packageOfCurrentModule := m.GetBazelLabel(ctx, m) 3065 jniLibPackage = packageOfCurrentModule[2:strings.Index(packageOfCurrentModule, ":")] 3066 } 3067 if _, inMap := jniLibPackages[jniLibPackage]; !inMap { 3068 jniLibPackages[jniLibPackage] = true 3069 } 3070 } 3071 jniLibPaths := []string{} 3072 for jniLibPackage, _ := range jniLibPackages { 3073 // See cs/f:.*/third_party/bazel/.*java_stub_template.txt for the use of RUNPATH 3074 jniLibPaths = append(jniLibPaths, "$${RUNPATH}"+jniLibPackage) 3075 } 3076 jvmFlags = bazel.MakeStringListAttribute([]string{"-Djava.library.path=" + strings.Join(jniLibPaths, ":")}) 3077 } 3078 3079 props := bazel.BazelTargetModuleProperties{ 3080 Rule_class: "java_binary", 3081 Bzl_load_location: "//build/bazel/rules/java:rules.bzl", 3082 } 3083 binAttrs := &javaBinaryHostAttributes{ 3084 Runtime_deps: runtimeDeps, 3085 Main_class: mainClass, 3086 Jvm_flags: jvmFlags, 3087 } 3088 3089 if commonAttrs.Srcs.IsEmpty() { 3090 binAttrs.javaCommonAttributes = commonAttrs 3091 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs) 3092 return 3093 } 3094 3095 libName := m.Name() + "_lib" 3096 var libProps bazel.BazelTargetModuleProperties 3097 if bp2BuildInfo.hasKotlin { 3098 libProps = ktJvmLibraryBazelTargetModuleProperties() 3099 } else { 3100 libProps = javaLibraryBazelTargetModuleProperties() 3101 } 3102 libAttrs := &javaLibraryAttributes{ 3103 Deps: deps, 3104 javaCommonAttributes: commonAttrs, 3105 } 3106 3107 ctx.CreateBazelTargetModule(libProps, android.CommonAttributes{Name: libName}, libAttrs) 3108 binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) 3109 3110 // Create the BazelTargetModule. 3111 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs) 3112} 3113 3114type bazelJavaImportAttributes struct { 3115 Jars bazel.LabelListAttribute 3116 Exports bazel.LabelListAttribute 3117} 3118 3119// java_import bp2Build converter. 3120func (i *Import) ConvertWithBp2build(ctx android.TopDownMutatorContext) { 3121 var jars bazel.LabelListAttribute 3122 archVariantProps := i.GetArchVariantProperties(ctx, &ImportProperties{}) 3123 for axis, configToProps := range archVariantProps { 3124 for config, _props := range configToProps { 3125 if archProps, ok := _props.(*ImportProperties); ok { 3126 archJars := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Jars, []string(nil)) 3127 jars.SetSelectValue(axis, config, archJars) 3128 } 3129 } 3130 } 3131 3132 attrs := &bazelJavaImportAttributes{ 3133 Jars: jars, 3134 } 3135 props := bazel.BazelTargetModuleProperties{ 3136 Rule_class: "java_import", 3137 Bzl_load_location: "//build/bazel/rules/java:rules.bzl", 3138 } 3139 3140 name := android.RemoveOptionalPrebuiltPrefix(i.Name()) 3141 3142 ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs) 3143 3144 neverlink := true 3145 neverlinkAttrs := &javaLibraryAttributes{ 3146 Neverlink: bazel.BoolAttribute{Value: &neverlink}, 3147 Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}), 3148 javaCommonAttributes: &javaCommonAttributes{ 3149 Sdk_version: bazel.StringAttribute{Value: proptools.StringPtr("none")}, 3150 }, 3151 } 3152 ctx.CreateBazelTargetModule( 3153 javaLibraryBazelTargetModuleProperties(), 3154 android.CommonAttributes{Name: name + "-neverlink"}, 3155 neverlinkAttrs) 3156 3157} 3158 3159var _ android.MixedBuildBuildable = (*Import)(nil) 3160 3161func (i *Import) getBazelModuleLabel(ctx android.BaseModuleContext) string { 3162 return android.RemoveOptionalPrebuiltPrefixFromBazelLabel(i.GetBazelLabel(ctx, i)) 3163} 3164 3165func (i *Import) ProcessBazelQueryResponse(ctx android.ModuleContext) { 3166 i.commonBuildActions(ctx) 3167 3168 bazelCtx := ctx.Config().BazelContext 3169 filePaths, err := bazelCtx.GetOutputFiles(i.getBazelModuleLabel(ctx), android.GetConfigKey(ctx)) 3170 if err != nil { 3171 ctx.ModuleErrorf(err.Error()) 3172 return 3173 } 3174 3175 bazelJars := android.Paths{} 3176 for _, bazelOutputFile := range filePaths { 3177 bazelJars = append(bazelJars, android.PathForBazelOut(ctx, bazelOutputFile)) 3178 } 3179 3180 jarName := android.RemoveOptionalPrebuiltPrefix(i.Name()) + ".jar" 3181 outputFile := android.PathForModuleOut(ctx, "bazelCombined", jarName) 3182 TransformJarsToJar(ctx, outputFile, "combine prebuilt jars", bazelJars, 3183 android.OptionalPath{}, // manifest 3184 false, // stripDirEntries 3185 []string{}, // filesToStrip 3186 []string{}, // dirsToStrip 3187 ) 3188 i.combinedClasspathFile = outputFile 3189 3190 ctx.SetProvider(JavaInfoProvider, JavaInfo{ 3191 HeaderJars: android.PathsIfNonNil(i.combinedClasspathFile), 3192 ImplementationAndResourcesJars: android.PathsIfNonNil(i.combinedClasspathFile), 3193 ImplementationJars: android.PathsIfNonNil(i.combinedClasspathFile), 3194 //TODO(b/240308299) include AIDL information from Bazel 3195 }) 3196 3197 i.maybeInstall(ctx, jarName, outputFile) 3198} 3199 3200func (i *Import) QueueBazelCall(ctx android.BaseModuleContext) { 3201 bazelCtx := ctx.Config().BazelContext 3202 bazelCtx.QueueBazelRequest(i.getBazelModuleLabel(ctx), cquery.GetOutputFiles, android.GetConfigKey(ctx)) 3203} 3204 3205func (i *Import) IsMixedBuildSupported(ctx android.BaseModuleContext) bool { 3206 return true 3207} 3208