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 "github.com/google/blueprint" 27 "github.com/google/blueprint/proptools" 28 29 "android/soong/android" 30 "android/soong/cc" 31 "android/soong/dexpreopt" 32 "android/soong/java/config" 33 "android/soong/tradefed" 34) 35 36func init() { 37 registerJavaBuildComponents(android.InitRegistrationContext) 38 39 RegisterJavaSdkMemberTypes() 40} 41 42func registerJavaBuildComponents(ctx android.RegistrationContext) { 43 ctx.RegisterModuleType("java_defaults", DefaultsFactory) 44 45 ctx.RegisterModuleType("java_library", LibraryFactory) 46 ctx.RegisterModuleType("java_library_static", LibraryStaticFactory) 47 ctx.RegisterModuleType("java_library_host", LibraryHostFactory) 48 ctx.RegisterModuleType("java_binary", BinaryFactory) 49 ctx.RegisterModuleType("java_binary_host", BinaryHostFactory) 50 ctx.RegisterModuleType("java_test", TestFactory) 51 ctx.RegisterModuleType("java_test_helper_library", TestHelperLibraryFactory) 52 ctx.RegisterModuleType("java_test_host", TestHostFactory) 53 ctx.RegisterModuleType("java_test_import", JavaTestImportFactory) 54 ctx.RegisterModuleType("java_import", ImportFactory) 55 ctx.RegisterModuleType("java_import_host", ImportFactoryHost) 56 ctx.RegisterModuleType("java_device_for_host", DeviceForHostFactory) 57 ctx.RegisterModuleType("java_host_for_device", HostForDeviceFactory) 58 ctx.RegisterModuleType("dex_import", DexImportFactory) 59 60 // This mutator registers dependencies on dex2oat for modules that should be 61 // dexpreopted. This is done late when the final variants have been 62 // established, to not get the dependencies split into the wrong variants and 63 // to support the checks in dexpreoptDisabled(). 64 ctx.FinalDepsMutators(func(ctx android.RegisterMutatorsContext) { 65 ctx.BottomUp("dexpreopt_tool_deps", dexpreoptToolDepsMutator).Parallel() 66 }) 67 68 ctx.RegisterSingletonType("logtags", LogtagsSingleton) 69 ctx.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) 70} 71 72func RegisterJavaSdkMemberTypes() { 73 // Register sdk member types. 74 android.RegisterSdkMemberType(javaHeaderLibsSdkMemberType) 75 android.RegisterSdkMemberType(javaLibsSdkMemberType) 76 android.RegisterSdkMemberType(javaBootLibsSdkMemberType) 77 android.RegisterSdkMemberType(javaTestSdkMemberType) 78} 79 80var ( 81 // Supports adding java header libraries to module_exports and sdk. 82 javaHeaderLibsSdkMemberType = &librarySdkMemberType{ 83 android.SdkMemberTypeBase{ 84 PropertyName: "java_header_libs", 85 SupportsSdk: true, 86 }, 87 func(_ android.SdkMemberContext, j *Library) android.Path { 88 headerJars := j.HeaderJars() 89 if len(headerJars) != 1 { 90 panic(fmt.Errorf("there must be only one header jar from %q", j.Name())) 91 } 92 93 return headerJars[0] 94 }, 95 sdkSnapshotFilePathForJar, 96 copyEverythingToSnapshot, 97 } 98 99 // Export implementation classes jar as part of the sdk. 100 exportImplementationClassesJar = func(_ android.SdkMemberContext, j *Library) android.Path { 101 implementationJars := j.ImplementationAndResourcesJars() 102 if len(implementationJars) != 1 { 103 panic(fmt.Errorf("there must be only one implementation jar from %q", j.Name())) 104 } 105 return implementationJars[0] 106 } 107 108 // Supports adding java implementation libraries to module_exports but not sdk. 109 javaLibsSdkMemberType = &librarySdkMemberType{ 110 android.SdkMemberTypeBase{ 111 PropertyName: "java_libs", 112 }, 113 exportImplementationClassesJar, 114 sdkSnapshotFilePathForJar, 115 copyEverythingToSnapshot, 116 } 117 118 // Supports adding java boot libraries to module_exports and sdk. 119 // 120 // The build has some implicit dependencies (via the boot jars configuration) on a number of 121 // modules, e.g. core-oj, apache-xml, that are part of the java boot class path and which are 122 // provided by mainline modules (e.g. art, conscrypt, runtime-i18n) but which are not otherwise 123 // used outside those mainline modules. 124 // 125 // As they are not needed outside the mainline modules adding them to the sdk/module-exports as 126 // either java_libs, or java_header_libs would end up exporting more information than was strictly 127 // necessary. The java_boot_libs property to allow those modules to be exported as part of the 128 // sdk/module_exports without exposing any unnecessary information. 129 javaBootLibsSdkMemberType = &librarySdkMemberType{ 130 android.SdkMemberTypeBase{ 131 PropertyName: "java_boot_libs", 132 SupportsSdk: true, 133 }, 134 // Temporarily export implementation classes jar for java_boot_libs as it is required for the 135 // hiddenapi processing. 136 // TODO(b/179354495): Revert once hiddenapi processing has been modularized. 137 exportImplementationClassesJar, 138 sdkSnapshotFilePathForJar, 139 onlyCopyJarToSnapshot, 140 } 141 142 // Supports adding java test libraries to module_exports but not sdk. 143 javaTestSdkMemberType = &testSdkMemberType{ 144 SdkMemberTypeBase: android.SdkMemberTypeBase{ 145 PropertyName: "java_tests", 146 }, 147 } 148) 149 150// JavaInfo contains information about a java module for use by modules that depend on it. 151type JavaInfo struct { 152 // HeaderJars is a list of jars that can be passed as the javac classpath in order to link 153 // against this module. If empty, ImplementationJars should be used instead. 154 HeaderJars android.Paths 155 156 // ImplementationAndResourceJars is a list of jars that contain the implementations of classes 157 // in the module as well as any resources included in the module. 158 ImplementationAndResourcesJars android.Paths 159 160 // ImplementationJars is a list of jars that contain the implementations of classes in the 161 //module. 162 ImplementationJars android.Paths 163 164 // ResourceJars is a list of jars that contain the resources included in the module. 165 ResourceJars android.Paths 166 167 // AidlIncludeDirs is a list of directories that should be passed to the aidl tool when 168 // depending on this module. 169 AidlIncludeDirs android.Paths 170 171 // SrcJarArgs is a list of arguments to pass to soong_zip to package the sources of this 172 // module. 173 SrcJarArgs []string 174 175 // SrcJarDeps is a list of paths to depend on when packaging the sources of this module. 176 SrcJarDeps android.Paths 177 178 // ExportedPlugins is a list of paths that should be used as annotation processors for any 179 // module that depends on this module. 180 ExportedPlugins android.Paths 181 182 // ExportedPluginClasses is a list of classes that should be run as annotation processors for 183 // any module that depends on this module. 184 ExportedPluginClasses []string 185 186 // ExportedPluginDisableTurbine is true if this module's annotation processors generate APIs, 187 // requiring disbling turbine for any modules that depend on it. 188 ExportedPluginDisableTurbine bool 189 190 // JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be 191 // instrumented by jacoco. 192 JacocoReportClassesFile android.Path 193} 194 195var JavaInfoProvider = blueprint.NewProvider(JavaInfo{}) 196 197// SyspropPublicStubInfo contains info about the sysprop public stub library that corresponds to 198// the sysprop implementation library. 199type SyspropPublicStubInfo struct { 200 // JavaInfo is the JavaInfoProvider of the sysprop public stub library that corresponds to 201 // the sysprop implementation library. 202 JavaInfo JavaInfo 203} 204 205var SyspropPublicStubInfoProvider = blueprint.NewProvider(SyspropPublicStubInfo{}) 206 207// Methods that need to be implemented for a module that is added to apex java_libs property. 208type ApexDependency interface { 209 HeaderJars() android.Paths 210 ImplementationAndResourcesJars() android.Paths 211} 212 213// Provides build path and install path to DEX jars. 214type UsesLibraryDependency interface { 215 DexJarBuildPath() android.Path 216 DexJarInstallPath() android.Path 217 ClassLoaderContexts() dexpreopt.ClassLoaderContextMap 218} 219 220// TODO(jungjw): Move this to kythe.go once it's created. 221type xref interface { 222 XrefJavaFiles() android.Paths 223} 224 225func (j *Module) XrefJavaFiles() android.Paths { 226 return j.kytheFiles 227} 228 229type dependencyTag struct { 230 blueprint.BaseDependencyTag 231 name string 232} 233 234// installDependencyTag is a dependency tag that is annotated to cause the installed files of the 235// dependency to be installed when the parent module is installed. 236type installDependencyTag struct { 237 blueprint.BaseDependencyTag 238 android.InstallAlwaysNeededDependencyTag 239 name string 240} 241 242type usesLibraryDependencyTag struct { 243 dependencyTag 244 sdkVersion int // SDK version in which the library appared as a standalone library. 245} 246 247func makeUsesLibraryDependencyTag(sdkVersion int) usesLibraryDependencyTag { 248 return usesLibraryDependencyTag{ 249 dependencyTag: dependencyTag{name: fmt.Sprintf("uses-library-%d", sdkVersion)}, 250 sdkVersion: sdkVersion, 251 } 252} 253 254func IsJniDepTag(depTag blueprint.DependencyTag) bool { 255 return depTag == jniLibTag 256} 257 258var ( 259 dataNativeBinsTag = dependencyTag{name: "dataNativeBins"} 260 staticLibTag = dependencyTag{name: "staticlib"} 261 libTag = dependencyTag{name: "javalib"} 262 java9LibTag = dependencyTag{name: "java9lib"} 263 pluginTag = dependencyTag{name: "plugin"} 264 errorpronePluginTag = dependencyTag{name: "errorprone-plugin"} 265 exportedPluginTag = dependencyTag{name: "exported-plugin"} 266 bootClasspathTag = dependencyTag{name: "bootclasspath"} 267 systemModulesTag = dependencyTag{name: "system modules"} 268 frameworkResTag = dependencyTag{name: "framework-res"} 269 kotlinStdlibTag = dependencyTag{name: "kotlin-stdlib"} 270 kotlinAnnotationsTag = dependencyTag{name: "kotlin-annotations"} 271 proguardRaiseTag = dependencyTag{name: "proguard-raise"} 272 certificateTag = dependencyTag{name: "certificate"} 273 instrumentationForTag = dependencyTag{name: "instrumentation_for"} 274 extraLintCheckTag = dependencyTag{name: "extra-lint-check"} 275 jniLibTag = dependencyTag{name: "jnilib"} 276 syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} 277 jniInstallTag = installDependencyTag{name: "jni install"} 278 binaryInstallTag = installDependencyTag{name: "binary install"} 279 usesLibTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion) 280 usesLibCompat28Tag = makeUsesLibraryDependencyTag(28) 281 usesLibCompat29Tag = makeUsesLibraryDependencyTag(29) 282 usesLibCompat30Tag = makeUsesLibraryDependencyTag(30) 283) 284 285func IsLibDepTag(depTag blueprint.DependencyTag) bool { 286 return depTag == libTag 287} 288 289func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool { 290 return depTag == staticLibTag 291} 292 293type sdkDep struct { 294 useModule, useFiles, invalidVersion bool 295 296 // The modules that will be added to the bootclasspath when targeting 1.8 or lower 297 bootclasspath []string 298 299 // The default system modules to use. Will be an empty string if no system 300 // modules are to be used. 301 systemModules string 302 303 // The modules that will be added to the classpath regardless of the Java language level targeted 304 classpath []string 305 306 // The modules that will be added ot the classpath when targeting 1.9 or higher 307 // (normally these will be on the bootclasspath when targeting 1.8 or lower) 308 java9Classpath []string 309 310 frameworkResModule string 311 312 jars android.Paths 313 aidl android.OptionalPath 314 315 noStandardLibs, noFrameworksLibs bool 316} 317 318func (s sdkDep) hasStandardLibs() bool { 319 return !s.noStandardLibs 320} 321 322func (s sdkDep) hasFrameworkLibs() bool { 323 return !s.noStandardLibs && !s.noFrameworksLibs 324} 325 326type jniLib struct { 327 name string 328 path android.Path 329 target android.Target 330 coverageFile android.OptionalPath 331 unstrippedFile android.Path 332} 333 334func sdkDeps(ctx android.BottomUpMutatorContext, sdkContext android.SdkContext, d dexer) { 335 sdkDep := decodeSdkDep(ctx, sdkContext) 336 if sdkDep.useModule { 337 ctx.AddVariationDependencies(nil, bootClasspathTag, sdkDep.bootclasspath...) 338 ctx.AddVariationDependencies(nil, java9LibTag, sdkDep.java9Classpath...) 339 ctx.AddVariationDependencies(nil, libTag, sdkDep.classpath...) 340 if d.effectiveOptimizeEnabled() && sdkDep.hasStandardLibs() { 341 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.LegacyCorePlatformBootclasspathLibraries...) 342 } 343 if d.effectiveOptimizeEnabled() && sdkDep.hasFrameworkLibs() { 344 ctx.AddVariationDependencies(nil, proguardRaiseTag, config.FrameworkLibraries...) 345 } 346 } 347 if sdkDep.systemModules != "" { 348 ctx.AddVariationDependencies(nil, systemModulesTag, sdkDep.systemModules) 349 } 350} 351 352type deps struct { 353 classpath classpath 354 java9Classpath classpath 355 bootClasspath classpath 356 processorPath classpath 357 errorProneProcessorPath classpath 358 processorClasses []string 359 staticJars android.Paths 360 staticHeaderJars android.Paths 361 staticResourceJars android.Paths 362 aidlIncludeDirs android.Paths 363 srcs android.Paths 364 srcJars android.Paths 365 systemModules *systemModules 366 aidlPreprocess android.OptionalPath 367 kotlinStdlib android.Paths 368 kotlinAnnotations android.Paths 369 370 disableTurbine bool 371} 372 373func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) { 374 for _, f := range dep.Srcs() { 375 if f.Ext() != ".jar" { 376 ctx.ModuleErrorf("genrule %q must generate files ending with .jar to be used as a libs or static_libs dependency", 377 ctx.OtherModuleName(dep.(blueprint.Module))) 378 } 379 } 380} 381 382func getJavaVersion(ctx android.ModuleContext, javaVersion string, sdkContext android.SdkContext) javaVersion { 383 if javaVersion != "" { 384 return normalizeJavaVersion(ctx, javaVersion) 385 } else if ctx.Device() { 386 return defaultJavaLanguageVersion(ctx, sdkContext.SdkVersion(ctx)) 387 } else { 388 return JAVA_VERSION_9 389 } 390} 391 392type javaVersion int 393 394const ( 395 JAVA_VERSION_UNSUPPORTED = 0 396 JAVA_VERSION_6 = 6 397 JAVA_VERSION_7 = 7 398 JAVA_VERSION_8 = 8 399 JAVA_VERSION_9 = 9 400) 401 402func (v javaVersion) String() string { 403 switch v { 404 case JAVA_VERSION_6: 405 return "1.6" 406 case JAVA_VERSION_7: 407 return "1.7" 408 case JAVA_VERSION_8: 409 return "1.8" 410 case JAVA_VERSION_9: 411 return "1.9" 412 default: 413 return "unsupported" 414 } 415} 416 417// Returns true if javac targeting this version uses system modules instead of a bootclasspath. 418func (v javaVersion) usesJavaModules() bool { 419 return v >= 9 420} 421 422func normalizeJavaVersion(ctx android.BaseModuleContext, javaVersion string) javaVersion { 423 switch javaVersion { 424 case "1.6", "6": 425 return JAVA_VERSION_6 426 case "1.7", "7": 427 return JAVA_VERSION_7 428 case "1.8", "8": 429 return JAVA_VERSION_8 430 case "1.9", "9": 431 return JAVA_VERSION_9 432 case "10", "11": 433 ctx.PropertyErrorf("java_version", "Java language levels above 9 are not supported") 434 return JAVA_VERSION_UNSUPPORTED 435 default: 436 ctx.PropertyErrorf("java_version", "Unrecognized Java language level") 437 return JAVA_VERSION_UNSUPPORTED 438 } 439} 440 441// 442// Java libraries (.jar file) 443// 444 445type Library struct { 446 Module 447 448 InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) 449} 450 451var _ android.ApexModule = (*Library)(nil) 452 453// Provides access to the list of permitted packages from updatable boot jars. 454type PermittedPackagesForUpdatableBootJars interface { 455 PermittedPackagesForUpdatableBootJars() []string 456} 457 458var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil) 459 460func (j *Library) PermittedPackagesForUpdatableBootJars() []string { 461 return j.properties.Permitted_packages 462} 463 464func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { 465 // Store uncompressed (and aligned) any dex files from jars in APEXes. 466 if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { 467 return true 468 } 469 470 // Store uncompressed (and do not strip) dex files from boot class path jars. 471 if inList(ctx.ModuleName(), ctx.Config().BootJars()) { 472 return true 473 } 474 475 // Store uncompressed dex files that are preopted on /system. 476 if !dexpreopter.dexpreoptDisabled(ctx) && (ctx.Host() || !odexOnSystemOther(ctx, dexpreopter.installPath)) { 477 return true 478 } 479 if ctx.Config().UncompressPrivAppDex() && 480 inList(ctx.ModuleName(), ctx.Config().ModulesLoadedByPrivilegedModules()) { 481 return true 482 } 483 484 return false 485} 486 487func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { 488 j.sdkVersion = j.SdkVersion(ctx) 489 j.minSdkVersion = j.MinSdkVersion(ctx) 490 491 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 492 if !apexInfo.IsForPlatform() { 493 j.hideApexVariantFromMake = true 494 } 495 496 j.checkSdkVersions(ctx) 497 j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") 498 j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary 499 if j.dexProperties.Uncompress_dex == nil { 500 // If the value was not force-set by the user, use reasonable default based on the module. 501 j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter)) 502 } 503 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 504 j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) 505 j.compile(ctx, nil) 506 507 // Collect the module directory for IDE info in java/jdeps.go. 508 j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) 509 510 exclusivelyForApex := !apexInfo.IsForPlatform() 511 if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex { 512 var extraInstallDeps android.Paths 513 if j.InstallMixin != nil { 514 extraInstallDeps = j.InstallMixin(ctx, j.outputFile) 515 } 516 j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 517 j.Stem()+".jar", j.outputFile, extraInstallDeps...) 518 } 519} 520 521func (j *Library) DepsMutator(ctx android.BottomUpMutatorContext) { 522 j.deps(ctx) 523} 524 525const ( 526 aidlIncludeDir = "aidl" 527 javaDir = "java" 528 jarFileSuffix = ".jar" 529 testConfigSuffix = "-AndroidTest.xml" 530) 531 532// path to the jar file of a java library. Relative to <sdk_root>/<api_dir> 533func sdkSnapshotFilePathForJar(osPrefix, name string) string { 534 return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix) 535} 536 537func sdkSnapshotFilePathForMember(osPrefix, name string, suffix string) string { 538 return filepath.Join(javaDir, osPrefix, name+suffix) 539} 540 541type librarySdkMemberType struct { 542 android.SdkMemberTypeBase 543 544 // Function to retrieve the appropriate output jar (implementation or header) from 545 // the library. 546 jarToExportGetter func(ctx android.SdkMemberContext, j *Library) android.Path 547 548 // Function to compute the snapshot relative path to which the named library's 549 // jar should be copied. 550 snapshotPathGetter func(osPrefix, name string) string 551 552 // True if only the jar should be copied to the snapshot, false if the jar plus any additional 553 // files like aidl files should also be copied. 554 onlyCopyJarToSnapshot bool 555} 556 557const ( 558 onlyCopyJarToSnapshot = true 559 copyEverythingToSnapshot = false 560) 561 562func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { 563 mctx.AddVariationDependencies(nil, dependencyTag, names...) 564} 565 566func (mt *librarySdkMemberType) IsInstance(module android.Module) bool { 567 _, ok := module.(*Library) 568 return ok 569} 570 571func (mt *librarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 572 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_import") 573} 574 575func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 576 return &librarySdkMemberProperties{} 577} 578 579type librarySdkMemberProperties struct { 580 android.SdkMemberPropertiesBase 581 582 JarToExport android.Path `android:"arch_variant"` 583 AidlIncludeDirs android.Paths 584 585 // The list of permitted packages that need to be passed to the prebuilts as they are used to 586 // create the updatable-bcp-packages.txt file. 587 PermittedPackages []string 588} 589 590func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 591 j := variant.(*Library) 592 593 p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) 594 595 p.AidlIncludeDirs = j.AidlIncludeDirs() 596 597 p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars() 598} 599 600func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 601 builder := ctx.SnapshotBuilder() 602 603 memberType := ctx.MemberType().(*librarySdkMemberType) 604 605 exportedJar := p.JarToExport 606 if exportedJar != nil { 607 // Delegate the creation of the snapshot relative path to the member type. 608 snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(p.OsPrefix(), ctx.Name()) 609 610 // Copy the exported jar to the snapshot. 611 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 612 613 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 614 } 615 616 if len(p.PermittedPackages) > 0 { 617 propertySet.AddProperty("permitted_packages", p.PermittedPackages) 618 } 619 620 // Do not copy anything else to the snapshot. 621 if memberType.onlyCopyJarToSnapshot { 622 return 623 } 624 625 aidlIncludeDirs := p.AidlIncludeDirs 626 if len(aidlIncludeDirs) != 0 { 627 sdkModuleContext := ctx.SdkModuleContext() 628 for _, dir := range aidlIncludeDirs { 629 // TODO(jiyong): copy parcelable declarations only 630 aidlFiles, _ := sdkModuleContext.GlobWithDeps(dir.String()+"/**/*.aidl", nil) 631 for _, file := range aidlFiles { 632 builder.CopyToSnapshot(android.PathForSource(sdkModuleContext, file), filepath.Join(aidlIncludeDir, file)) 633 } 634 } 635 636 // TODO(b/151933053) - add aidl include dirs property 637 } 638} 639 640// java_library builds and links sources into a `.jar` file for the device, and possibly for the host as well. 641// 642// By default, a java_library has a single variant that produces a `.jar` file containing `.class` files that were 643// compiled against the device bootclasspath. This jar is not suitable for installing on a device, but can be used 644// as a `static_libs` dependency of another module. 645// 646// Specifying `installable: true` will product a `.jar` file containing `classes.dex` files, suitable for installing on 647// a device. 648// 649// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 650// compiled against the host bootclasspath. 651func LibraryFactory() android.Module { 652 module := &Library{} 653 654 module.addHostAndDeviceProperties() 655 656 module.initModuleAndImport(module) 657 658 android.InitApexModule(module) 659 android.InitSdkAwareModule(module) 660 InitJavaModule(module, android.HostAndDeviceSupported) 661 return module 662} 663 664// java_library_static is an obsolete alias for java_library. 665func LibraryStaticFactory() android.Module { 666 return LibraryFactory() 667} 668 669// java_library_host builds and links sources into a `.jar` file for the host. 670// 671// A java_library_host has a single variant that produces a `.jar` file containing `.class` files that were 672// compiled against the host bootclasspath. 673func LibraryHostFactory() android.Module { 674 module := &Library{} 675 676 module.addHostProperties() 677 678 module.Module.properties.Installable = proptools.BoolPtr(true) 679 680 android.InitApexModule(module) 681 android.InitSdkAwareModule(module) 682 InitJavaModule(module, android.HostSupported) 683 return module 684} 685 686// 687// Java Tests 688// 689 690// Test option struct. 691type TestOptions struct { 692 // a list of extra test configuration files that should be installed with the module. 693 Extra_test_configs []string `android:"path,arch_variant"` 694 695 // If the test is a hostside(no device required) unittest that shall be run during presubmit check. 696 Unit_test *bool 697} 698 699type testProperties struct { 700 // list of compatibility suites (for example "cts", "vts") that the module should be 701 // installed into. 702 Test_suites []string `android:"arch_variant"` 703 704 // the name of the test configuration (for example "AndroidTest.xml") that should be 705 // installed with the module. 706 Test_config *string `android:"path,arch_variant"` 707 708 // the name of the test configuration template (for example "AndroidTestTemplate.xml") that 709 // should be installed with the module. 710 Test_config_template *string `android:"path,arch_variant"` 711 712 // list of files or filegroup modules that provide data that should be installed alongside 713 // the test 714 Data []string `android:"path"` 715 716 // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml 717 // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true 718 // explicitly. 719 Auto_gen_config *bool 720 721 // Add parameterized mainline modules to auto generated test config. The options will be 722 // handled by TradeFed to do downloading and installing the specified modules on the device. 723 Test_mainline_modules []string 724 725 // Test options. 726 Test_options TestOptions 727 728 // Names of modules containing JNI libraries that should be installed alongside the test. 729 Jni_libs []string 730} 731 732type hostTestProperties struct { 733 // list of native binary modules that should be installed alongside the test 734 Data_native_bins []string `android:"arch_variant"` 735} 736 737type testHelperLibraryProperties struct { 738 // list of compatibility suites (for example "cts", "vts") that the module should be 739 // installed into. 740 Test_suites []string `android:"arch_variant"` 741} 742 743type prebuiltTestProperties struct { 744 // list of compatibility suites (for example "cts", "vts") that the module should be 745 // installed into. 746 Test_suites []string `android:"arch_variant"` 747 748 // the name of the test configuration (for example "AndroidTest.xml") that should be 749 // installed with the module. 750 Test_config *string `android:"path,arch_variant"` 751} 752 753type Test struct { 754 Library 755 756 testProperties testProperties 757 758 testConfig android.Path 759 extraTestConfigs android.Paths 760 data android.Paths 761} 762 763type TestHost struct { 764 Test 765 766 testHostProperties hostTestProperties 767} 768 769type TestHelperLibrary struct { 770 Library 771 772 testHelperLibraryProperties testHelperLibraryProperties 773} 774 775type JavaTestImport struct { 776 Import 777 778 prebuiltTestProperties prebuiltTestProperties 779 780 testConfig android.Path 781 dexJarFile android.Path 782} 783 784func (j *TestHost) DepsMutator(ctx android.BottomUpMutatorContext) { 785 if len(j.testHostProperties.Data_native_bins) > 0 { 786 for _, target := range ctx.MultiTargets() { 787 ctx.AddVariationDependencies(target.Variations(), dataNativeBinsTag, j.testHostProperties.Data_native_bins...) 788 } 789 } 790 791 if len(j.testProperties.Jni_libs) > 0 { 792 for _, target := range ctx.MultiTargets() { 793 sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) 794 ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...) 795 } 796 } 797 798 j.deps(ctx) 799} 800 801func (j *TestHost) AddExtraResource(p android.Path) { 802 j.extraResources = append(j.extraResources, p) 803} 804 805func (j *Test) GenerateAndroidBuildActions(ctx android.ModuleContext) { 806 if j.testProperties.Test_options.Unit_test == nil && ctx.Host() { 807 // TODO(b/): Clean temporary heuristic to avoid unexpected onboarding. 808 defaultUnitTest := !inList("tradefed", j.properties.Libs) && !inList("cts", j.testProperties.Test_suites) 809 j.testProperties.Test_options.Unit_test = proptools.BoolPtr(defaultUnitTest) 810 } 811 j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.testProperties.Test_config, j.testProperties.Test_config_template, 812 j.testProperties.Test_suites, j.testProperties.Auto_gen_config, j.testProperties.Test_options.Unit_test) 813 814 j.data = android.PathsForModuleSrc(ctx, j.testProperties.Data) 815 816 j.extraTestConfigs = android.PathsForModuleSrc(ctx, j.testProperties.Test_options.Extra_test_configs) 817 818 ctx.VisitDirectDepsWithTag(dataNativeBinsTag, func(dep android.Module) { 819 j.data = append(j.data, android.OutputFileForModule(ctx, dep, "")) 820 }) 821 822 ctx.VisitDirectDepsWithTag(jniLibTag, func(dep android.Module) { 823 sharedLibInfo := ctx.OtherModuleProvider(dep, cc.SharedLibraryInfoProvider).(cc.SharedLibraryInfo) 824 if sharedLibInfo.SharedLibrary != nil { 825 // Copy to an intermediate output directory to append "lib[64]" to the path, 826 // so that it's compatible with the default rpath values. 827 var relPath string 828 if sharedLibInfo.Target.Arch.ArchType.Multilib == "lib64" { 829 relPath = filepath.Join("lib64", sharedLibInfo.SharedLibrary.Base()) 830 } else { 831 relPath = filepath.Join("lib", sharedLibInfo.SharedLibrary.Base()) 832 } 833 relocatedLib := android.PathForModuleOut(ctx, "relocated").Join(ctx, relPath) 834 ctx.Build(pctx, android.BuildParams{ 835 Rule: android.Cp, 836 Input: sharedLibInfo.SharedLibrary, 837 Output: relocatedLib, 838 }) 839 j.data = append(j.data, relocatedLib) 840 } else { 841 ctx.PropertyErrorf("jni_libs", "%q of type %q is not supported", dep.Name(), ctx.OtherModuleType(dep)) 842 } 843 }) 844 845 j.Library.GenerateAndroidBuildActions(ctx) 846} 847 848func (j *TestHelperLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 849 j.Library.GenerateAndroidBuildActions(ctx) 850} 851 852func (j *JavaTestImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 853 j.testConfig = tradefed.AutoGenJavaTestConfig(ctx, j.prebuiltTestProperties.Test_config, nil, 854 j.prebuiltTestProperties.Test_suites, nil, nil) 855 856 j.Import.GenerateAndroidBuildActions(ctx) 857} 858 859type testSdkMemberType struct { 860 android.SdkMemberTypeBase 861} 862 863func (mt *testSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { 864 mctx.AddVariationDependencies(nil, dependencyTag, names...) 865} 866 867func (mt *testSdkMemberType) IsInstance(module android.Module) bool { 868 _, ok := module.(*Test) 869 return ok 870} 871 872func (mt *testSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { 873 return ctx.SnapshotBuilder().AddPrebuiltModule(member, "java_test_import") 874} 875 876func (mt *testSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { 877 return &testSdkMemberProperties{} 878} 879 880type testSdkMemberProperties struct { 881 android.SdkMemberPropertiesBase 882 883 JarToExport android.Path 884 TestConfig android.Path 885} 886 887func (p *testSdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { 888 test := variant.(*Test) 889 890 implementationJars := test.ImplementationJars() 891 if len(implementationJars) != 1 { 892 panic(fmt.Errorf("there must be only one implementation jar from %q", test.Name())) 893 } 894 895 p.JarToExport = implementationJars[0] 896 p.TestConfig = test.testConfig 897} 898 899func (p *testSdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { 900 builder := ctx.SnapshotBuilder() 901 902 exportedJar := p.JarToExport 903 if exportedJar != nil { 904 snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name()) 905 builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath) 906 907 propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) 908 } 909 910 testConfig := p.TestConfig 911 if testConfig != nil { 912 snapshotRelativeTestConfigPath := sdkSnapshotFilePathForMember(p.OsPrefix(), ctx.Name(), testConfigSuffix) 913 builder.CopyToSnapshot(testConfig, snapshotRelativeTestConfigPath) 914 propertySet.AddProperty("test_config", snapshotRelativeTestConfigPath) 915 } 916} 917 918// java_test builds a and links sources into a `.jar` file for the device, and possibly for the host as well, and 919// creates an `AndroidTest.xml` file to allow running the test with `atest` or a `TEST_MAPPING` file. 920// 921// By default, a java_test has a single variant that produces a `.jar` file containing `classes.dex` files that were 922// compiled against the device bootclasspath. 923// 924// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 925// compiled against the host bootclasspath. 926func TestFactory() android.Module { 927 module := &Test{} 928 929 module.addHostAndDeviceProperties() 930 module.AddProperties(&module.testProperties) 931 932 module.Module.properties.Installable = proptools.BoolPtr(true) 933 module.Module.dexpreopter.isTest = true 934 module.Module.linter.test = true 935 936 android.InitSdkAwareModule(module) 937 InitJavaModule(module, android.HostAndDeviceSupported) 938 return module 939} 940 941// java_test_helper_library creates a java library and makes sure that it is added to the appropriate test suite. 942func TestHelperLibraryFactory() android.Module { 943 module := &TestHelperLibrary{} 944 945 module.addHostAndDeviceProperties() 946 module.AddProperties(&module.testHelperLibraryProperties) 947 948 module.Module.properties.Installable = proptools.BoolPtr(true) 949 module.Module.dexpreopter.isTest = true 950 module.Module.linter.test = true 951 952 InitJavaModule(module, android.HostAndDeviceSupported) 953 return module 954} 955 956// java_test_import imports one or more `.jar` files into the build graph as if they were built by a java_test module 957// and makes sure that it is added to the appropriate test suite. 958// 959// By default, a java_test_import has a single variant that expects a `.jar` file containing `.class` files that were 960// compiled against an Android classpath. 961// 962// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 963// for host modules. 964func JavaTestImportFactory() android.Module { 965 module := &JavaTestImport{} 966 967 module.AddProperties( 968 &module.Import.properties, 969 &module.prebuiltTestProperties) 970 971 module.Import.properties.Installable = proptools.BoolPtr(true) 972 973 android.InitPrebuiltModule(module, &module.properties.Jars) 974 android.InitApexModule(module) 975 android.InitSdkAwareModule(module) 976 InitJavaModule(module, android.HostAndDeviceSupported) 977 return module 978} 979 980// java_test_host builds a and links sources into a `.jar` file for the host, and creates an `AndroidTest.xml` file to 981// allow running the test with `atest` or a `TEST_MAPPING` file. 982// 983// A java_test_host has a single variant that produces a `.jar` file containing `.class` files that were 984// compiled against the host bootclasspath. 985func TestHostFactory() android.Module { 986 module := &TestHost{} 987 988 module.addHostProperties() 989 module.AddProperties(&module.testProperties) 990 module.AddProperties(&module.testHostProperties) 991 992 InitTestHost( 993 module, 994 proptools.BoolPtr(true), 995 nil, 996 nil) 997 998 InitJavaModuleMultiTargets(module, android.HostSupported) 999 1000 return module 1001} 1002 1003func InitTestHost(th *TestHost, installable *bool, testSuites []string, autoGenConfig *bool) { 1004 th.properties.Installable = installable 1005 th.testProperties.Auto_gen_config = autoGenConfig 1006 th.testProperties.Test_suites = testSuites 1007} 1008 1009// 1010// Java Binaries (.jar file plus wrapper script) 1011// 1012 1013type binaryProperties struct { 1014 // installable script to execute the resulting jar 1015 Wrapper *string `android:"path"` 1016 1017 // Name of the class containing main to be inserted into the manifest as Main-Class. 1018 Main_class *string 1019 1020 // Names of modules containing JNI libraries that should be installed alongside the host 1021 // variant of the binary. 1022 Jni_libs []string 1023} 1024 1025type Binary struct { 1026 Library 1027 1028 binaryProperties binaryProperties 1029 1030 isWrapperVariant bool 1031 1032 wrapperFile android.Path 1033 binaryFile android.InstallPath 1034} 1035 1036func (j *Binary) HostToolPath() android.OptionalPath { 1037 return android.OptionalPathForPath(j.binaryFile) 1038} 1039 1040func (j *Binary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1041 if ctx.Arch().ArchType == android.Common { 1042 // Compile the jar 1043 if j.binaryProperties.Main_class != nil { 1044 if j.properties.Manifest != nil { 1045 ctx.PropertyErrorf("main_class", "main_class cannot be used when manifest is set") 1046 } 1047 manifestFile := android.PathForModuleOut(ctx, "manifest.txt") 1048 GenerateMainClassManifest(ctx, manifestFile, String(j.binaryProperties.Main_class)) 1049 j.overrideManifest = android.OptionalPathForPath(manifestFile) 1050 } 1051 1052 j.Library.GenerateAndroidBuildActions(ctx) 1053 } else { 1054 // Handle the binary wrapper 1055 j.isWrapperVariant = true 1056 1057 if j.binaryProperties.Wrapper != nil { 1058 j.wrapperFile = android.PathForModuleSrc(ctx, *j.binaryProperties.Wrapper) 1059 } else { 1060 j.wrapperFile = android.PathForSource(ctx, "build/soong/scripts/jar-wrapper.sh") 1061 } 1062 1063 // The host installation rules make the installed wrapper depend on all the dependencies 1064 // of the wrapper variant, which will include the common variant's jar file and any JNI 1065 // libraries. This is verified by TestBinary. 1066 j.binaryFile = ctx.InstallExecutable(android.PathForModuleInstall(ctx, "bin"), 1067 ctx.ModuleName(), j.wrapperFile) 1068 } 1069} 1070 1071func (j *Binary) DepsMutator(ctx android.BottomUpMutatorContext) { 1072 if ctx.Arch().ArchType == android.Common || ctx.BazelConversionMode() { 1073 j.deps(ctx) 1074 } 1075 if ctx.Arch().ArchType != android.Common || ctx.BazelConversionMode() { 1076 // These dependencies ensure the host installation rules will install the jar file and 1077 // the jni libraries when the wrapper is installed. 1078 ctx.AddVariationDependencies(nil, jniInstallTag, j.binaryProperties.Jni_libs...) 1079 ctx.AddVariationDependencies( 1080 []blueprint.Variation{{Mutator: "arch", Variation: android.CommonArch.String()}}, 1081 binaryInstallTag, ctx.ModuleName()) 1082 } 1083} 1084 1085// java_binary builds a `.jar` file and a shell script that executes it for the device, and possibly for the host 1086// as well. 1087// 1088// By default, a java_binary has a single variant that produces a `.jar` file containing `classes.dex` files that were 1089// compiled against the device bootclasspath. 1090// 1091// Specifying `host_supported: true` will produce two variants, one compiled against the device bootclasspath and one 1092// compiled against the host bootclasspath. 1093func BinaryFactory() android.Module { 1094 module := &Binary{} 1095 1096 module.addHostAndDeviceProperties() 1097 module.AddProperties(&module.binaryProperties) 1098 1099 module.Module.properties.Installable = proptools.BoolPtr(true) 1100 1101 android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibCommonFirst) 1102 android.InitDefaultableModule(module) 1103 return module 1104} 1105 1106// java_binary_host builds a `.jar` file and a shell script that executes it for the host. 1107// 1108// A java_binary_host has a single variant that produces a `.jar` file containing `.class` files that were 1109// compiled against the host bootclasspath. 1110func BinaryHostFactory() android.Module { 1111 module := &Binary{} 1112 1113 module.addHostProperties() 1114 module.AddProperties(&module.binaryProperties) 1115 1116 module.Module.properties.Installable = proptools.BoolPtr(true) 1117 1118 android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommonFirst) 1119 android.InitDefaultableModule(module) 1120 return module 1121} 1122 1123// 1124// Java prebuilts 1125// 1126 1127type ImportProperties struct { 1128 Jars []string `android:"path,arch_variant"` 1129 1130 // The version of the SDK that the source prebuilt file was built against. Defaults to the 1131 // current version if not specified. 1132 Sdk_version *string 1133 1134 // The minimum version of the SDK that this module supports. Defaults to sdk_version if not 1135 // specified. 1136 Min_sdk_version *string 1137 1138 Installable *bool 1139 1140 // If not empty, classes are restricted to the specified packages and their sub-packages. 1141 // This information is used to generate the updatable-bcp-packages.txt file. 1142 Permitted_packages []string 1143 1144 // List of shared java libs that this module has dependencies to 1145 Libs []string 1146 1147 // List of files to remove from the jar file(s) 1148 Exclude_files []string 1149 1150 // List of directories to remove from the jar file(s) 1151 Exclude_dirs []string 1152 1153 // if set to true, run Jetifier against .jar file. Defaults to false. 1154 Jetifier *bool 1155 1156 // set the name of the output 1157 Stem *string 1158 1159 Aidl struct { 1160 // directories that should be added as include directories for any aidl sources of modules 1161 // that depend on this module, as well as to aidl for this module. 1162 Export_include_dirs []string 1163 } 1164} 1165 1166type Import struct { 1167 android.ModuleBase 1168 android.DefaultableModuleBase 1169 android.ApexModuleBase 1170 prebuilt android.Prebuilt 1171 android.SdkBase 1172 1173 // Functionality common to Module and Import. 1174 embeddableInModuleAndImport 1175 1176 hiddenAPI 1177 dexer 1178 dexpreopter 1179 1180 properties ImportProperties 1181 1182 // output file containing classes.dex and resources 1183 dexJarFile android.Path 1184 1185 combinedClasspathFile android.Path 1186 classLoaderContexts dexpreopt.ClassLoaderContextMap 1187 exportAidlIncludeDirs android.Paths 1188 1189 hideApexVariantFromMake bool 1190 1191 sdkVersion android.SdkSpec 1192 minSdkVersion android.SdkSpec 1193} 1194 1195var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil) 1196 1197func (j *Import) PermittedPackagesForUpdatableBootJars() []string { 1198 return j.properties.Permitted_packages 1199} 1200 1201func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 1202 return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version)) 1203} 1204 1205func (j *Import) SystemModules() string { 1206 return "none" 1207} 1208 1209func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 1210 if j.properties.Min_sdk_version != nil { 1211 return android.SdkSpecFrom(ctx, *j.properties.Min_sdk_version) 1212 } 1213 return j.SdkVersion(ctx) 1214} 1215 1216func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { 1217 return j.SdkVersion(ctx) 1218} 1219 1220func (j *Import) Prebuilt() *android.Prebuilt { 1221 return &j.prebuilt 1222} 1223 1224func (j *Import) PrebuiltSrcs() []string { 1225 return j.properties.Jars 1226} 1227 1228func (j *Import) Name() string { 1229 return j.prebuilt.Name(j.ModuleBase.Name()) 1230} 1231 1232func (j *Import) Stem() string { 1233 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 1234} 1235 1236func (a *Import) JacocoReportClassesFile() android.Path { 1237 return nil 1238} 1239 1240func (j *Import) LintDepSets() LintDepSets { 1241 return LintDepSets{} 1242} 1243 1244func (j *Import) getStrictUpdatabilityLinting() bool { 1245 return false 1246} 1247 1248func (j *Import) setStrictUpdatabilityLinting(bool) { 1249} 1250 1251func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { 1252 ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) 1253 1254 if ctx.Device() && Bool(j.dexProperties.Compile_dex) { 1255 sdkDeps(ctx, android.SdkContext(j), j.dexer) 1256 } 1257} 1258 1259func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1260 j.sdkVersion = j.SdkVersion(ctx) 1261 j.minSdkVersion = j.MinSdkVersion(ctx) 1262 1263 if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() { 1264 j.hideApexVariantFromMake = true 1265 } 1266 1267 jars := android.PathsForModuleSrc(ctx, j.properties.Jars) 1268 1269 jarName := j.Stem() + ".jar" 1270 outputFile := android.PathForModuleOut(ctx, "combined", jarName) 1271 TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{}, 1272 false, j.properties.Exclude_files, j.properties.Exclude_dirs) 1273 if Bool(j.properties.Jetifier) { 1274 inputFile := outputFile 1275 outputFile = android.PathForModuleOut(ctx, "jetifier", jarName) 1276 TransformJetifier(ctx, outputFile, inputFile) 1277 } 1278 j.combinedClasspathFile = outputFile 1279 j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) 1280 1281 var flags javaBuilderFlags 1282 var deapexerModule android.Module 1283 1284 ctx.VisitDirectDeps(func(module android.Module) { 1285 tag := ctx.OtherModuleDependencyTag(module) 1286 1287 if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { 1288 dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) 1289 switch tag { 1290 case libTag, staticLibTag: 1291 flags.classpath = append(flags.classpath, dep.HeaderJars...) 1292 case bootClasspathTag: 1293 flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...) 1294 } 1295 } else if dep, ok := module.(SdkLibraryDependency); ok { 1296 switch tag { 1297 case libTag: 1298 flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...) 1299 } 1300 } 1301 1302 addCLCFromDep(ctx, module, j.classLoaderContexts) 1303 1304 // Save away the `deapexer` module on which this depends, if any. 1305 if tag == android.DeapexerTag { 1306 if deapexerModule != nil { 1307 ctx.ModuleErrorf("Ambiguous duplicate deapexer module dependencies %q and %q", 1308 deapexerModule.Name(), module.Name()) 1309 } 1310 deapexerModule = module 1311 } 1312 }) 1313 1314 if Bool(j.properties.Installable) { 1315 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 1316 jarName, outputFile) 1317 } 1318 1319 j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) 1320 1321 if ctx.Device() { 1322 // If this is a variant created for a prebuilt_apex then use the dex implementation jar 1323 // obtained from the associated deapexer module. 1324 ai := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 1325 if ai.ForPrebuiltApex { 1326 if deapexerModule == nil { 1327 // This should never happen as a variant for a prebuilt_apex is only created if the 1328 // deapexer module has been configured to export the dex implementation jar for this module. 1329 ctx.ModuleErrorf("internal error: module %q does not depend on a `deapexer` module for prebuilt_apex %q", 1330 j.Name(), ai.ApexVariationName) 1331 return 1332 } 1333 1334 // Get the path of the dex implementation jar from the `deapexer` module. 1335 di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) 1336 if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil { 1337 j.dexJarFile = dexOutputPath 1338 1339 // Initialize the hiddenapi structure. 1340 j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil) 1341 } else { 1342 // This should never happen as a variant for a prebuilt_apex is only created if the 1343 // prebuilt_apex has been configured to export the java library dex file. 1344 ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt_apex %q", deapexerModule.Name()) 1345 } 1346 } else if Bool(j.dexProperties.Compile_dex) { 1347 sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) 1348 if sdkDep.invalidVersion { 1349 ctx.AddMissingDependencies(sdkDep.bootclasspath) 1350 ctx.AddMissingDependencies(sdkDep.java9Classpath) 1351 } else if sdkDep.useFiles { 1352 // sdkDep.jar is actually equivalent to turbine header.jar. 1353 flags.classpath = append(flags.classpath, sdkDep.jars...) 1354 } 1355 1356 // Dex compilation 1357 1358 j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", jarName) 1359 if j.dexProperties.Uncompress_dex == nil { 1360 // If the value was not force-set by the user, use reasonable default based on the module. 1361 j.dexProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter)) 1362 } 1363 j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex 1364 1365 var dexOutputFile android.OutputPath 1366 dexOutputFile = j.dexer.compileDex(ctx, flags, j.MinSdkVersion(ctx), outputFile, jarName) 1367 if ctx.Failed() { 1368 return 1369 } 1370 1371 // Initialize the hiddenapi structure. 1372 j.initHiddenAPI(ctx, dexOutputFile, outputFile, j.dexProperties.Uncompress_dex) 1373 1374 // Encode hidden API flags in dex file. 1375 dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) 1376 1377 j.dexJarFile = dexOutputFile 1378 } 1379 } 1380 1381 ctx.SetProvider(JavaInfoProvider, JavaInfo{ 1382 HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile), 1383 ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), 1384 ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile), 1385 AidlIncludeDirs: j.exportAidlIncludeDirs, 1386 }) 1387} 1388 1389func (j *Import) OutputFiles(tag string) (android.Paths, error) { 1390 switch tag { 1391 case "", ".jar": 1392 return android.Paths{j.combinedClasspathFile}, nil 1393 default: 1394 return nil, fmt.Errorf("unsupported module reference tag %q", tag) 1395 } 1396} 1397 1398var _ android.OutputFileProducer = (*Import)(nil) 1399 1400func (j *Import) HeaderJars() android.Paths { 1401 if j.combinedClasspathFile == nil { 1402 return nil 1403 } 1404 return android.Paths{j.combinedClasspathFile} 1405} 1406 1407func (j *Import) ImplementationAndResourcesJars() android.Paths { 1408 if j.combinedClasspathFile == nil { 1409 return nil 1410 } 1411 return android.Paths{j.combinedClasspathFile} 1412} 1413 1414func (j *Import) DexJarBuildPath() android.Path { 1415 return j.dexJarFile 1416} 1417 1418func (j *Import) DexJarInstallPath() android.Path { 1419 return nil 1420} 1421 1422func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { 1423 return j.classLoaderContexts 1424} 1425 1426var _ android.ApexModule = (*Import)(nil) 1427 1428// Implements android.ApexModule 1429func (j *Import) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool { 1430 return j.depIsInSameApex(ctx, dep) 1431} 1432 1433// Implements android.ApexModule 1434func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 1435 sdkVersion android.ApiLevel) error { 1436 sdkSpec := j.MinSdkVersion(ctx) 1437 if !sdkSpec.Specified() { 1438 return fmt.Errorf("min_sdk_version is not specified") 1439 } 1440 if sdkSpec.Kind == android.SdkCore { 1441 return nil 1442 } 1443 ver, err := sdkSpec.EffectiveVersion(ctx) 1444 if err != nil { 1445 return err 1446 } 1447 if ver.GreaterThan(sdkVersion) { 1448 return fmt.Errorf("newer SDK(%v)", ver) 1449 } 1450 return nil 1451} 1452 1453// requiredFilesFromPrebuiltApexForImport returns information about the files that a java_import or 1454// java_sdk_library_import with the specified base module name requires to be exported from a 1455// prebuilt_apex/apex_set. 1456func requiredFilesFromPrebuiltApexForImport(name string) []string { 1457 // Add the dex implementation jar to the set of exported files. 1458 return []string{ 1459 apexRootRelativePathToJavaLib(name), 1460 } 1461} 1462 1463// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for 1464// the java library with the specified name. 1465func apexRootRelativePathToJavaLib(name string) string { 1466 return filepath.Join("javalib", name+".jar") 1467} 1468 1469var _ android.RequiredFilesFromPrebuiltApex = (*Import)(nil) 1470 1471func (j *Import) RequiredFilesFromPrebuiltApex(_ android.BaseModuleContext) []string { 1472 name := j.BaseModuleName() 1473 return requiredFilesFromPrebuiltApexForImport(name) 1474} 1475 1476// Add compile time check for interface implementation 1477var _ android.IDEInfo = (*Import)(nil) 1478var _ android.IDECustomizedModuleName = (*Import)(nil) 1479 1480// Collect information for opening IDE project files in java/jdeps.go. 1481const ( 1482 removedPrefix = "prebuilt_" 1483) 1484 1485func (j *Import) IDEInfo(dpInfo *android.IdeInfo) { 1486 dpInfo.Jars = append(dpInfo.Jars, j.PrebuiltSrcs()...) 1487} 1488 1489func (j *Import) IDECustomizedModuleName() string { 1490 // TODO(b/113562217): Extract the base module name from the Import name, often the Import name 1491 // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better 1492 // solution to get the Import name. 1493 name := j.Name() 1494 if strings.HasPrefix(name, removedPrefix) { 1495 name = strings.TrimPrefix(name, removedPrefix) 1496 } 1497 return name 1498} 1499 1500var _ android.PrebuiltInterface = (*Import)(nil) 1501 1502func (j *Import) IsInstallable() bool { 1503 return Bool(j.properties.Installable) 1504} 1505 1506var _ dexpreopterInterface = (*Import)(nil) 1507 1508// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library module. 1509// 1510// By default, a java_import has a single variant that expects a `.jar` file containing `.class` files that were 1511// compiled against an Android classpath. 1512// 1513// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one 1514// for host modules. 1515func ImportFactory() android.Module { 1516 module := &Import{} 1517 1518 module.AddProperties( 1519 &module.properties, 1520 &module.dexer.dexProperties, 1521 ) 1522 1523 module.initModuleAndImport(module) 1524 1525 module.dexProperties.Optimize.EnabledByDefault = false 1526 1527 android.InitPrebuiltModule(module, &module.properties.Jars) 1528 android.InitApexModule(module) 1529 android.InitSdkAwareModule(module) 1530 InitJavaModule(module, android.HostAndDeviceSupported) 1531 return module 1532} 1533 1534// java_import imports one or more `.jar` files into the build graph as if they were built by a java_library_host 1535// module. 1536// 1537// A java_import_host has a single variant that expects a `.jar` file containing `.class` files that were 1538// compiled against a host bootclasspath. 1539func ImportFactoryHost() android.Module { 1540 module := &Import{} 1541 1542 module.AddProperties(&module.properties) 1543 1544 android.InitPrebuiltModule(module, &module.properties.Jars) 1545 android.InitApexModule(module) 1546 InitJavaModule(module, android.HostSupported) 1547 return module 1548} 1549 1550// dex_import module 1551 1552type DexImportProperties struct { 1553 Jars []string `android:"path"` 1554 1555 // set the name of the output 1556 Stem *string 1557} 1558 1559type DexImport struct { 1560 android.ModuleBase 1561 android.DefaultableModuleBase 1562 android.ApexModuleBase 1563 prebuilt android.Prebuilt 1564 1565 properties DexImportProperties 1566 1567 dexJarFile android.Path 1568 1569 dexpreopter 1570 1571 hideApexVariantFromMake bool 1572} 1573 1574func (j *DexImport) Prebuilt() *android.Prebuilt { 1575 return &j.prebuilt 1576} 1577 1578func (j *DexImport) PrebuiltSrcs() []string { 1579 return j.properties.Jars 1580} 1581 1582func (j *DexImport) Name() string { 1583 return j.prebuilt.Name(j.ModuleBase.Name()) 1584} 1585 1586func (j *DexImport) Stem() string { 1587 return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name()) 1588} 1589 1590func (a *DexImport) JacocoReportClassesFile() android.Path { 1591 return nil 1592} 1593 1594func (a *DexImport) LintDepSets() LintDepSets { 1595 return LintDepSets{} 1596} 1597 1598func (j *DexImport) IsInstallable() bool { 1599 return true 1600} 1601 1602func (j *DexImport) getStrictUpdatabilityLinting() bool { 1603 return false 1604} 1605 1606func (j *DexImport) setStrictUpdatabilityLinting(bool) { 1607} 1608 1609func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { 1610 if len(j.properties.Jars) != 1 { 1611 ctx.PropertyErrorf("jars", "exactly one jar must be provided") 1612 } 1613 1614 apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) 1615 if !apexInfo.IsForPlatform() { 1616 j.hideApexVariantFromMake = true 1617 } 1618 1619 j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") 1620 j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) 1621 1622 inputJar := ctx.ExpandSource(j.properties.Jars[0], "jars") 1623 dexOutputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar") 1624 1625 if j.dexpreopter.uncompressedDex { 1626 rule := android.NewRuleBuilder(pctx, ctx) 1627 1628 temporary := android.PathForModuleOut(ctx, ctx.ModuleName()+".jar.unaligned") 1629 rule.Temporary(temporary) 1630 1631 // use zip2zip to uncompress classes*.dex files 1632 rule.Command(). 1633 BuiltTool("zip2zip"). 1634 FlagWithInput("-i ", inputJar). 1635 FlagWithOutput("-o ", temporary). 1636 FlagWithArg("-0 ", "'classes*.dex'") 1637 1638 // use zipalign to align uncompressed classes*.dex files 1639 rule.Command(). 1640 BuiltTool("zipalign"). 1641 Flag("-f"). 1642 Text("4"). 1643 Input(temporary). 1644 Output(dexOutputFile) 1645 1646 rule.DeleteTemporaryFiles() 1647 1648 rule.Build("uncompress_dex", "uncompress dex") 1649 } else { 1650 ctx.Build(pctx, android.BuildParams{ 1651 Rule: android.Cp, 1652 Input: inputJar, 1653 Output: dexOutputFile, 1654 }) 1655 } 1656 1657 j.dexJarFile = dexOutputFile 1658 1659 j.dexpreopt(ctx, dexOutputFile) 1660 1661 if apexInfo.IsForPlatform() { 1662 ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), 1663 j.Stem()+".jar", dexOutputFile) 1664 } 1665} 1666 1667func (j *DexImport) DexJarBuildPath() android.Path { 1668 return j.dexJarFile 1669} 1670 1671var _ android.ApexModule = (*DexImport)(nil) 1672 1673// Implements android.ApexModule 1674func (j *DexImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 1675 sdkVersion android.ApiLevel) error { 1676 // we don't check prebuilt modules for sdk_version 1677 return nil 1678} 1679 1680// dex_import imports a `.jar` file containing classes.dex files. 1681// 1682// A dex_import module cannot be used as a dependency of a java_* or android_* module, it can only be installed 1683// to the device. 1684func DexImportFactory() android.Module { 1685 module := &DexImport{} 1686 1687 module.AddProperties(&module.properties) 1688 1689 android.InitPrebuiltModule(module, &module.properties.Jars) 1690 android.InitApexModule(module) 1691 InitJavaModule(module, android.DeviceSupported) 1692 return module 1693} 1694 1695// 1696// Defaults 1697// 1698type Defaults struct { 1699 android.ModuleBase 1700 android.DefaultsModuleBase 1701 android.ApexModuleBase 1702} 1703 1704// java_defaults provides a set of properties that can be inherited by other java or android modules. 1705// 1706// A module can use the properties from a java_defaults module using `defaults: ["defaults_module_name"]`. Each 1707// property in the defaults module that exists in the depending module will be prepended to the depending module's 1708// value for that property. 1709// 1710// Example: 1711// 1712// java_defaults { 1713// name: "example_defaults", 1714// srcs: ["common/**/*.java"], 1715// javacflags: ["-Xlint:all"], 1716// aaptflags: ["--auto-add-overlay"], 1717// } 1718// 1719// java_library { 1720// name: "example", 1721// defaults: ["example_defaults"], 1722// srcs: ["example/**/*.java"], 1723// } 1724// 1725// is functionally identical to: 1726// 1727// java_library { 1728// name: "example", 1729// srcs: [ 1730// "common/**/*.java", 1731// "example/**/*.java", 1732// ], 1733// javacflags: ["-Xlint:all"], 1734// } 1735func DefaultsFactory() android.Module { 1736 module := &Defaults{} 1737 1738 module.AddProperties( 1739 &CommonProperties{}, 1740 &DeviceProperties{}, 1741 &DexProperties{}, 1742 &DexpreoptProperties{}, 1743 &android.ProtoProperties{}, 1744 &aaptProperties{}, 1745 &androidLibraryProperties{}, 1746 &appProperties{}, 1747 &appTestProperties{}, 1748 &overridableAppProperties{}, 1749 &testProperties{}, 1750 &ImportProperties{}, 1751 &AARImportProperties{}, 1752 &sdkLibraryProperties{}, 1753 &commonToSdkLibraryAndImportProperties{}, 1754 &DexImportProperties{}, 1755 &android.ApexProperties{}, 1756 &RuntimeResourceOverlayProperties{}, 1757 &LintProperties{}, 1758 &appTestHelperAppProperties{}, 1759 ) 1760 1761 android.InitDefaultsModule(module) 1762 return module 1763} 1764 1765func kytheExtractJavaFactory() android.Singleton { 1766 return &kytheExtractJavaSingleton{} 1767} 1768 1769type kytheExtractJavaSingleton struct { 1770} 1771 1772func (ks *kytheExtractJavaSingleton) GenerateBuildActions(ctx android.SingletonContext) { 1773 var xrefTargets android.Paths 1774 ctx.VisitAllModules(func(module android.Module) { 1775 if javaModule, ok := module.(xref); ok { 1776 xrefTargets = append(xrefTargets, javaModule.XrefJavaFiles()...) 1777 } 1778 }) 1779 // TODO(asmundak): perhaps emit a rule to output a warning if there were no xrefTargets 1780 if len(xrefTargets) > 0 { 1781 ctx.Phony("xref_java", xrefTargets...) 1782 } 1783} 1784 1785var Bool = proptools.Bool 1786var BoolDefault = proptools.BoolDefault 1787var String = proptools.String 1788var inList = android.InList 1789 1790// Add class loader context (CLC) of a given dependency to the current CLC. 1791func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, 1792 clcMap dexpreopt.ClassLoaderContextMap) { 1793 1794 dep, ok := depModule.(UsesLibraryDependency) 1795 if !ok { 1796 return 1797 } 1798 1799 // Find out if the dependency is either an SDK library or an ordinary library that is disguised 1800 // as an SDK library by the means of `provides_uses_lib` property. If yes, the library is itself 1801 // a <uses-library> and should be added as a node in the CLC tree, and its CLC should be added 1802 // as subtree of that node. Otherwise the library is not a <uses_library> and should not be 1803 // added to CLC, but the transitive <uses-library> dependencies from its CLC should be added to 1804 // the current CLC. 1805 var implicitSdkLib *string 1806 comp, isComp := depModule.(SdkLibraryComponentDependency) 1807 if isComp { 1808 implicitSdkLib = comp.OptionalImplicitSdkLibrary() 1809 // OptionalImplicitSdkLibrary() may be nil so need to fall through to ProvidesUsesLib(). 1810 } 1811 if implicitSdkLib == nil { 1812 if ulib, ok := depModule.(ProvidesUsesLib); ok { 1813 implicitSdkLib = ulib.ProvidesUsesLib() 1814 } 1815 } 1816 1817 depTag := ctx.OtherModuleDependencyTag(depModule) 1818 if depTag == libTag || depTag == usesLibTag { 1819 // Ok, propagate <uses-library> through non-static library dependencies. 1820 } else if depTag == staticLibTag { 1821 // Propagate <uses-library> through static library dependencies, unless it is a component 1822 // library (such as stubs). Component libraries have a dependency on their SDK library, 1823 // which should not be pulled just because of a static component library. 1824 if implicitSdkLib != nil { 1825 return 1826 } 1827 } else { 1828 // Don't propagate <uses-library> for other dependency tags. 1829 return 1830 } 1831 1832 if implicitSdkLib != nil { 1833 clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *implicitSdkLib, 1834 dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) 1835 } else { 1836 depName := ctx.OtherModuleName(depModule) 1837 clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) 1838 } 1839} 1840