diff --git a/java/aar.go b/java/aar.go index 506187959..1734da945 100644 --- a/java/aar.go +++ b/java/aar.go @@ -387,11 +387,6 @@ func (a *aapt) buildActions(ctx android.ModuleContext, opts aaptBuildActionOptio // Add additional manifest files to transitive manifests. additionalManifests := android.PathsForModuleSrc(ctx, a.aaptProperties.Additional_manifests) transitiveManifestPaths := append(android.Paths{manifestPath}, additionalManifests...) - // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import - // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies - // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of - // android_library_import modules. If this is fixed, staticManifestsDepSet can be dropped completely in favor of - // staticResourcesNodesDepSet.manifests() transitiveManifestPaths = append(transitiveManifestPaths, staticManifestsDepSet.ToList()...) if len(transitiveManifestPaths) > 1 && !Bool(a.aaptProperties.Dont_merge_manifests) { @@ -763,7 +758,8 @@ func aaptLibs(ctx android.ModuleContext, sdkContext android.SdkContext, classLoa // reverse later. // NOTE: this is legacy and probably incorrect behavior, for most other cases (e.g. conflicting classes in // dependencies) the highest priority dependency is listed first, but for resources the highest priority - // dependency has to be listed last. + // dependency has to be listed last. This is also inconsistent with the way manifests from the same + // transitive dependencies are merged. staticResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil, android.ReverseSliceInPlace(staticResourcesNodeDepSets)) sharedResourcesNodes = android.NewDepSet(android.TOPOLOGICAL, nil, @@ -978,7 +974,8 @@ type AARImport struct { properties AARImportProperties - classpathFile android.WritablePath + headerJarFile android.WritablePath + implementationJarFile android.WritablePath proguardFlags android.WritablePath exportPackage android.WritablePath transitiveAaptResourcePackagesFile android.Path @@ -999,6 +996,9 @@ type AARImport struct { sdkVersion android.SdkSpec minSdkVersion android.ApiLevel + usesLibrary + classLoaderContexts dexpreopt.ClassLoaderContextMap + // Single aconfig "cache file" merged from this module and all dependencies. mergedAconfigFiles map[string]android.Paths } @@ -1011,7 +1011,7 @@ func (a *AARImport) OutputFiles(tag string) (android.Paths, error) { case ".aar": return []android.Path{a.aarPath}, nil case "": - return []android.Path{a.classpathFile}, nil + return []android.Path{a.implementationJarFile}, nil default: return nil, fmt.Errorf("unsupported module reference tag %q", tag) } @@ -1094,6 +1094,8 @@ func (a *AARImport) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddVariationDependencies(nil, libTag, a.properties.Libs...) ctx.AddVariationDependencies(nil, staticLibTag, a.properties.Static_libs...) + + a.usesLibrary.deps(ctx, false) } type JniPackageInfo struct { @@ -1152,7 +1154,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } extractedAARDir := android.PathForModuleOut(ctx, "aar") - a.classpathFile = extractedAARDir.Join(ctx, "classes-combined.jar") + classpathFile := extractedAARDir.Join(ctx, "classes-combined.jar") a.manifest = extractedAARDir.Join(ctx, "AndroidManifest.xml") a.rTxt = extractedAARDir.Join(ctx, "R.txt") a.assetsPackage = android.PathForModuleOut(ctx, "assets.zip") @@ -1168,11 +1170,11 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.Build(pctx, android.BuildParams{ Rule: unzipAAR, Input: a.aarPath, - Outputs: android.WritablePaths{a.classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt}, + Outputs: android.WritablePaths{classpathFile, a.proguardFlags, a.manifest, a.assetsPackage, a.rTxt}, Description: "unzip AAR", Args: map[string]string{ "outDir": extractedAARDir.String(), - "combinedClassesJar": a.classpathFile.String(), + "combinedClassesJar": classpathFile.String(), "assetsPackage": a.assetsPackage.String(), }, }) @@ -1245,13 +1247,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.resourcesNodesDepSet = resourcesNodesDepSetBuilder.Build() manifestDepSetBuilder := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(a.manifest) - // TODO(b/288358614): Soong has historically not merged manifests from dependencies of android_library_import - // modules. Merging manifests from dependencies could remove the need for pom2bp to generate the "-nodeps" copies - // of androidx libraries, but doing so triggers errors due to errors introduced by existing dependencies of - // android_library_import modules. If this is fixed, AndroidLibraryDependency.ManifestsDepSet can be dropped - // completely in favor of AndroidLibraryDependency.ResourceNodesDepSet.manifest - //manifestDepSetBuilder.Transitive(transitiveStaticDeps.manifests) - _ = staticManifestsDepSet + manifestDepSetBuilder.Transitive(staticManifestsDepSet) a.manifestsDepSet = manifestDepSetBuilder.Build() transitiveAaptResourcePackages := staticDeps.resPackages().Strings() @@ -1263,12 +1259,45 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.transitiveAaptResourcePackagesFile = transitiveAaptResourcePackagesFile a.collectTransitiveHeaderJars(ctx) + + a.classLoaderContexts = a.usesLibrary.classLoaderContextForUsesLibDeps(ctx) + + var staticJars android.Paths + var staticHeaderJars android.Paths + ctx.VisitDirectDeps(func(module android.Module) { + if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { + tag := ctx.OtherModuleDependencyTag(module) + switch tag { + case staticLibTag: + staticJars = append(staticJars, dep.ImplementationJars...) + staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...) + } + } + addCLCFromDep(ctx, module, a.classLoaderContexts) + }) + + if len(staticJars) > 0 { + combineJars := append(android.Paths{classpathFile}, staticJars...) + a.implementationJarFile = android.PathForModuleOut(ctx, "combined", ctx.ModuleName()+".jar") + TransformJarsToJar(ctx, a.implementationJarFile, "combine", combineJars, android.OptionalPath{}, false, nil, nil) + } else { + a.implementationJarFile = classpathFile + } + + if len(staticHeaderJars) > 0 { + combineJars := append(android.Paths{classpathFile}, staticHeaderJars...) + a.headerJarFile = android.PathForModuleOut(ctx, "turbine-combined", ctx.ModuleName()+".jar") + TransformJarsToJar(ctx, a.headerJarFile, "combine header jars", combineJars, android.OptionalPath{}, false, nil, nil) + } else { + a.headerJarFile = classpathFile + } + android.SetProvider(ctx, JavaInfoProvider, JavaInfo{ - HeaderJars: android.PathsIfNonNil(a.classpathFile), + HeaderJars: android.PathsIfNonNil(a.headerJarFile), TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars, TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars, - ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile), - ImplementationJars: android.PathsIfNonNil(a.classpathFile), + ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationJarFile), + ImplementationJars: android.PathsIfNonNil(a.implementationJarFile), StubsLinkType: Implementation, // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts }) @@ -1301,15 +1330,15 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { } func (a *AARImport) HeaderJars() android.Paths { - return android.Paths{a.classpathFile} + return android.Paths{a.headerJarFile} } func (a *AARImport) ImplementationAndResourcesJars() android.Paths { - return android.Paths{a.classpathFile} + return android.Paths{a.implementationJarFile} } -func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) android.Path { - return nil +func (a *AARImport) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { + return OptionalDexJarPath{} } func (a *AARImport) DexJarInstallPath() android.Path { @@ -1317,9 +1346,11 @@ func (a *AARImport) DexJarInstallPath() android.Path { } func (a *AARImport) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { - return nil + return a.classLoaderContexts } +var _ UsesLibraryDependency = (*AARImport)(nil) + var _ android.ApexModule = (*AARImport)(nil) // Implements android.ApexModule @@ -1328,7 +1359,7 @@ func (a *AARImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.M } // Implements android.ApexModule -func (g *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, +func (a *AARImport) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error { return nil } @@ -1342,7 +1373,10 @@ var _ android.PrebuiltInterface = (*AARImport)(nil) func AARImportFactory() android.Module { module := &AARImport{} - module.AddProperties(&module.properties) + module.AddProperties( + &module.properties, + &module.usesLibrary.usesLibraryProperties, + ) android.InitPrebuiltModule(module, &module.properties.Aars) android.InitApexModule(module) diff --git a/java/android_manifest_test.go b/java/android_manifest_test.go index 5909b1e6a..7c9188462 100644 --- a/java/android_manifest_test.go +++ b/java/android_manifest_test.go @@ -92,10 +92,9 @@ func TestManifestMerger(t *testing.T) { "out/soong/.intermediates/transitive/android_common/manifest_fixer/AndroidManifest.xml", "transitive/AndroidManifest2.xml", "out/soong/.intermediates/transitive_import/android_common/aar/AndroidManifest.xml", + "out/soong/.intermediates/transitive_import_dep/android_common/aar/AndroidManifest.xml", "out/soong/.intermediates/direct_import/android_common/aar/AndroidManifest.xml", - // TODO(b/288358614): Soong has historically not merged manifests from dependencies of - // android_library_import modules. - + "out/soong/.intermediates/direct_import_dep/android_common/aar/AndroidManifest.xml", }, manifestMergerRule.Implicits) } diff --git a/java/androidmk.go b/java/androidmk.go index 498962f88..a52d43965 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -211,7 +211,7 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries { return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "JAVA_LIBRARIES", OverrideName: prebuilt.BaseModuleName(), - OutputFile: android.OptionalPathForPath(prebuilt.combinedClasspathFile), + OutputFile: android.OptionalPathForPath(prebuilt.combinedImplementationFile), Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { @@ -219,8 +219,8 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries { if prebuilt.dexJarFile.IsSet() { entries.SetPath("LOCAL_SOONG_DEX_JAR", prebuilt.dexJarFile.Path()) } - entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedClasspathFile) - entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedClasspathFile) + entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.combinedHeaderFile) + entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.combinedImplementationFile) entries.SetString("LOCAL_SDK_VERSION", prebuilt.sdkVersion.String()) entries.SetString("LOCAL_MODULE_STEM", prebuilt.Stem()) // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts @@ -262,13 +262,13 @@ func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries { } return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "JAVA_LIBRARIES", - OutputFile: android.OptionalPathForPath(prebuilt.classpathFile), + OutputFile: android.OptionalPathForPath(prebuilt.implementationJarFile), Include: "$(BUILD_SYSTEM)/soong_java_prebuilt.mk", ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) - entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.classpathFile) - entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.classpathFile) + entries.SetPath("LOCAL_SOONG_HEADER_JAR", prebuilt.headerJarFile) + entries.SetPath("LOCAL_SOONG_CLASSES_JAR", prebuilt.implementationJarFile) entries.SetPath("LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE", prebuilt.exportPackage) entries.SetPath("LOCAL_SOONG_TRANSITIVE_RES_PACKAGES", prebuilt.transitiveAaptResourcePackagesFile) entries.SetPath("LOCAL_SOONG_EXPORT_PROGUARD_FLAGS", prebuilt.proguardFlags) diff --git a/java/app_test.go b/java/app_test.go index b75cb1678..ca9d31704 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -829,12 +829,12 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", }, directResources: nil, @@ -849,12 +849,12 @@ func TestAndroidResourceProcessor(t *testing.T) { directClasspath: []string{ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", }, directCombined: []string{ "out/soong/.intermediates/direct/android_common/javac/direct.jar", "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", }, transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, @@ -928,13 +928,13 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/app/android_common/busybox/R.jar", "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", "out/soong/.intermediates/app/android_common/busybox/R.jar", "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", }, directResources: nil, @@ -953,12 +953,12 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar", "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar", "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", }, directCombined: []string{ "out/soong/.intermediates/direct/android_common/javac/direct.jar", "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", }, transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, @@ -1034,13 +1034,13 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/app/android_common/busybox/R.jar", "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", "out/soong/.intermediates/app/android_common/busybox/R.jar", "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", }, dontVerifyDirect: true, @@ -1075,12 +1075,12 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", }, directResources: nil, @@ -1098,12 +1098,12 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/transitive_import_dep/android_common/busybox/R.jar", "out/soong/.intermediates/transitive_import/android_common/busybox/R.jar", "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", }, directCombined: []string{ "out/soong/.intermediates/direct/android_common/javac/direct.jar", "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", }, dontVerifyTransitive: true, @@ -1137,12 +1137,12 @@ func TestAndroidResourceProcessor(t *testing.T) { "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", "out/soong/.intermediates/shared/android_common/turbine-combined/shared.jar", "out/soong/.intermediates/direct/android_common/turbine-combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/turbine-combined/direct_import.jar", }, appCombined: []string{ "out/soong/.intermediates/app/android_common/javac/app.jar", "out/soong/.intermediates/direct/android_common/combined/direct.jar", - "out/soong/.intermediates/direct_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/direct_import/android_common/combined/direct_import.jar", }, directResources: nil, @@ -1157,12 +1157,12 @@ func TestAndroidResourceProcessor(t *testing.T) { directClasspath: []string{ "out/soong/.intermediates/default/java/android_stubs_current/android_common/turbine-combined/android_stubs_current.jar", "out/soong/.intermediates/transitive/android_common/turbine-combined/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/transitive_import/android_common/turbine-combined/transitive_import.jar", }, directCombined: []string{ "out/soong/.intermediates/direct/android_common/javac/direct.jar", "out/soong/.intermediates/transitive/android_common/javac/transitive.jar", - "out/soong/.intermediates/transitive_import/android_common/aar/classes-combined.jar", + "out/soong/.intermediates/transitive_import/android_common/combined/transitive_import.jar", }, transitiveResources: []string{"out/soong/.intermediates/transitive/android_common/aapt2/transitive/res/values_strings.arsc.flat"}, diff --git a/java/java.go b/java/java.go index 97feb9bb2..72536cd6d 100644 --- a/java/java.go +++ b/java/java.go @@ -21,6 +21,7 @@ package java import ( "fmt" "path/filepath" + "slices" "sort" "strings" @@ -2337,6 +2338,9 @@ type ImportProperties struct { // List of shared java libs that this module has dependencies to Libs []string + // List of static java libs that this module has dependencies to + Static_libs []string + // List of files to remove from the jar file(s) Exclude_files []string @@ -2389,9 +2393,10 @@ type Import struct { dexJarFileErr error dexJarInstallFile android.Path - combinedClasspathFile android.Path - classLoaderContexts dexpreopt.ClassLoaderContextMap - exportAidlIncludeDirs android.Paths + combinedImplementationFile android.Path + combinedHeaderFile android.Path + classLoaderContexts dexpreopt.ClassLoaderContextMap + exportAidlIncludeDirs android.Paths hideApexVariantFromMake bool @@ -2475,6 +2480,7 @@ func (j *Import) setStrictUpdatabilityLinting(bool) { func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) + ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...) if ctx.Device() && Bool(j.dexProperties.Compile_dex) { sdkDeps(ctx, android.SdkContext(j), j.dexer) @@ -2504,23 +2510,13 @@ func (j *Import) commonBuildActions(ctx android.ModuleContext) { func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.commonBuildActions(ctx) - jars := android.PathsForModuleSrc(ctx, j.properties.Jars) - - jarName := j.Stem() + ".jar" - outputFile := android.PathForModuleOut(ctx, "combined", jarName) - TransformJarsToJar(ctx, outputFile, "for prebuilts", jars, android.OptionalPath{}, - false, j.properties.Exclude_files, j.properties.Exclude_dirs) - if Bool(j.properties.Jetifier) { - inputFile := outputFile - outputFile = android.PathForModuleOut(ctx, "jetifier", jarName) - TransformJetifier(ctx, outputFile, inputFile) - } - j.combinedClasspathFile = outputFile j.classLoaderContexts = make(dexpreopt.ClassLoaderContextMap) var flags javaBuilderFlags j.collectTransitiveHeaderJars(ctx) + var staticJars android.Paths + var staticHeaderJars android.Paths ctx.VisitDirectDeps(func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { @@ -2530,6 +2526,8 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...) case staticLibTag: flags.classpath = append(flags.classpath, dep.HeaderJars...) + staticJars = append(staticJars, dep.ImplementationAndResourcesJars...) + staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...) case bootClasspathTag: flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...) } @@ -2543,6 +2541,46 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { addCLCFromDep(ctx, module, j.classLoaderContexts) }) + jars := android.PathsForModuleSrc(ctx, j.properties.Jars) + jarName := j.Stem() + ".jar" + + // Always pass the input jars to TransformJarsToJar, even if there is only a single jar, we need the output + // file of the module to be named jarName. + outputFile := android.PathForModuleOut(ctx, "combined", jarName) + implementationJars := append(slices.Clone(jars), staticJars...) + TransformJarsToJar(ctx, outputFile, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{}, + false, j.properties.Exclude_files, j.properties.Exclude_dirs) + + // If no dependencies have separate header jars then there is no need to create a separate + // header jar for this module. + reuseImplementationJarAsHeaderJar := slices.Equal(staticJars, staticHeaderJars) + + var headerOutputFile android.WritablePath + if reuseImplementationJarAsHeaderJar { + headerOutputFile = outputFile + } else { + headerJars := append(slices.Clone(jars), staticHeaderJars...) + headerOutputFile = android.PathForModuleOut(ctx, "turbine-combined", jarName) + TransformJarsToJar(ctx, headerOutputFile, "combine prebuilt header jars", headerJars, android.OptionalPath{}, + false, j.properties.Exclude_files, j.properties.Exclude_dirs) + } + + if Bool(j.properties.Jetifier) { + inputFile := outputFile + outputFile = android.PathForModuleOut(ctx, "jetifier", jarName) + TransformJetifier(ctx, outputFile, inputFile) + + if !reuseImplementationJarAsHeaderJar { + headerInputFile := headerOutputFile + headerOutputFile = android.PathForModuleOut(ctx, "jetifier-headers", jarName) + TransformJetifier(ctx, headerOutputFile, headerInputFile) + } else { + headerOutputFile = outputFile + } + } + j.combinedHeaderFile = headerOutputFile + j.combinedImplementationFile = outputFile + j.maybeInstall(ctx, jarName, outputFile) j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs) @@ -2626,11 +2664,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } android.SetProvider(ctx, JavaInfoProvider, JavaInfo{ - HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile), + HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile), TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars, TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars, - ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), - ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile), + ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile), + ImplementationJars: android.PathsIfNonNil(j.combinedImplementationFile), AidlIncludeDirs: j.exportAidlIncludeDirs, StubsLinkType: j.stubsLinkType, // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts @@ -2658,7 +2696,7 @@ func (j *Import) maybeInstall(ctx android.ModuleContext, jarName string, outputF func (j *Import) OutputFiles(tag string) (android.Paths, error) { switch tag { case "", ".jar": - return android.Paths{j.combinedClasspathFile}, nil + return android.Paths{j.combinedImplementationFile}, nil default: return nil, fmt.Errorf("unsupported module reference tag %q", tag) } @@ -2667,17 +2705,11 @@ func (j *Import) OutputFiles(tag string) (android.Paths, error) { var _ android.OutputFileProducer = (*Import)(nil) func (j *Import) HeaderJars() android.Paths { - if j.combinedClasspathFile == nil { - return nil - } - return android.Paths{j.combinedClasspathFile} + return android.PathsIfNonNil(j.combinedHeaderFile) } func (j *Import) ImplementationAndResourcesJars() android.Paths { - if j.combinedClasspathFile == nil { - return nil - } - return android.Paths{j.combinedClasspathFile} + return android.PathsIfNonNil(j.combinedImplementationFile) } func (j *Import) DexJarBuildPath(ctx android.ModuleErrorfContext) OptionalDexJarPath { diff --git a/java/java_test.go b/java/java_test.go index 194f9d974..2676aa558 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -588,10 +588,11 @@ func TestPrebuilts(t *testing.T) { javac := fooModule.Rule("javac") combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") barModule := ctx.ModuleForTests("bar", "android_common") - barJar := barModule.Rule("combineJar").Output + barJar := barModule.Output("combined/bar.jar").Output bazModule := ctx.ModuleForTests("baz", "android_common") bazJar := bazModule.Rule("combineJar").Output - sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output + sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common"). + Output("combined/sdklib.stubs.jar").Output fooLibrary := fooModule.Module().(*Library) assertDeepEquals(t, "foo unique sources incorrect", @@ -1035,7 +1036,7 @@ func TestExcludeFileGroupInSrcs(t *testing.T) { } } -func TestJavaLibrary(t *testing.T) { +func TestJavaLibraryOutputFiles(t *testing.T) { testJavaWithFS(t, "", map[string][]byte{ "libcore/Android.bp": []byte(` java_library { @@ -1052,7 +1053,7 @@ func TestJavaLibrary(t *testing.T) { }) } -func TestJavaImport(t *testing.T) { +func TestJavaImportOutputFiles(t *testing.T) { testJavaWithFS(t, "", map[string][]byte{ "libcore/Android.bp": []byte(` java_import { @@ -1068,6 +1069,85 @@ func TestJavaImport(t *testing.T) { }) } +func TestJavaImport(t *testing.T) { + bp := ` + java_library { + name: "source_library", + srcs: ["source.java"], + } + + java_import { + name: "import_with_no_deps", + jars: ["no_deps.jar"], + } + + java_import { + name: "import_with_source_deps", + jars: ["source_deps.jar"], + static_libs: ["source_library"], + } + + java_import { + name: "import_with_import_deps", + jars: ["import_deps.jar"], + static_libs: ["import_with_no_deps"], + } + ` + ctx := android.GroupFixturePreparers( + PrepareForTestWithJavaDefaultModules, + ).RunTestWithBp(t, bp) + + source := ctx.ModuleForTests("source_library", "android_common") + sourceJar := source.Output("javac/source_library.jar") + sourceHeaderJar := source.Output("turbine-combined/source_library.jar") + sourceJavaInfo, _ := android.SingletonModuleProvider(ctx, source.Module(), JavaInfoProvider) + + // The source library produces separate implementation and header jars + android.AssertPathsRelativeToTopEquals(t, "source library implementation jar", + []string{sourceJar.Output.String()}, sourceJavaInfo.ImplementationAndResourcesJars) + android.AssertPathsRelativeToTopEquals(t, "source library header jar", + []string{sourceHeaderJar.Output.String()}, sourceJavaInfo.HeaderJars) + + importWithNoDeps := ctx.ModuleForTests("import_with_no_deps", "android_common") + importWithNoDepsJar := importWithNoDeps.Output("combined/import_with_no_deps.jar") + importWithNoDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithNoDeps.Module(), JavaInfoProvider) + + // An import with no deps produces a single jar used as both the header and implementation jar. + android.AssertPathsRelativeToTopEquals(t, "import with no deps implementation jar", + []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.ImplementationAndResourcesJars) + android.AssertPathsRelativeToTopEquals(t, "import with no deps header jar", + []string{importWithNoDepsJar.Output.String()}, importWithNoDepsJavaInfo.HeaderJars) + android.AssertPathsRelativeToTopEquals(t, "import with no deps combined inputs", + []string{"no_deps.jar"}, importWithNoDepsJar.Inputs) + + importWithSourceDeps := ctx.ModuleForTests("import_with_source_deps", "android_common") + importWithSourceDepsJar := importWithSourceDeps.Output("combined/import_with_source_deps.jar") + importWithSourceDepsHeaderJar := importWithSourceDeps.Output("turbine-combined/import_with_source_deps.jar") + importWithSourceDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithSourceDeps.Module(), JavaInfoProvider) + + // An import with source deps produces separate header and implementation jars. + android.AssertPathsRelativeToTopEquals(t, "import with source deps implementation jar", + []string{importWithSourceDepsJar.Output.String()}, importWithSourceDepsJavaInfo.ImplementationAndResourcesJars) + android.AssertPathsRelativeToTopEquals(t, "import with source deps header jar", + []string{importWithSourceDepsHeaderJar.Output.String()}, importWithSourceDepsJavaInfo.HeaderJars) + android.AssertPathsRelativeToTopEquals(t, "import with source deps combined implementation jar inputs", + []string{"source_deps.jar", sourceJar.Output.String()}, importWithSourceDepsJar.Inputs) + android.AssertPathsRelativeToTopEquals(t, "import with source deps combined header jar inputs", + []string{"source_deps.jar", sourceHeaderJar.Output.String()}, importWithSourceDepsHeaderJar.Inputs) + + importWithImportDeps := ctx.ModuleForTests("import_with_import_deps", "android_common") + importWithImportDepsJar := importWithImportDeps.Output("combined/import_with_import_deps.jar") + importWithImportDepsJavaInfo, _ := android.SingletonModuleProvider(ctx, importWithImportDeps.Module(), JavaInfoProvider) + + // An import with only import deps produces a single jar used as both the header and implementation jar. + android.AssertPathsRelativeToTopEquals(t, "import with import deps implementation jar", + []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.ImplementationAndResourcesJars) + android.AssertPathsRelativeToTopEquals(t, "import with import deps header jar", + []string{importWithImportDepsJar.Output.String()}, importWithImportDepsJavaInfo.HeaderJars) + android.AssertPathsRelativeToTopEquals(t, "import with import deps combined implementation jar inputs", + []string{"import_deps.jar", importWithNoDepsJar.Output.String()}, importWithImportDepsJar.Inputs) +} + var compilerFlagsTestCases = []struct { in string out bool