Merge "Use transitive header jars in classpaths" into main am: 399ff4019d

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/3214782

Change-Id: I034fe6ddbd7bcafb40807cd00973d7f0f36e6339
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Colin Cross
2024-09-06 16:30:58 +00:00
committed by Automerger Merge Worker
11 changed files with 737 additions and 202 deletions

View File

@@ -1962,6 +1962,10 @@ func (c *config) UseResourceProcessorByDefault() bool {
return c.productVariables.GetBuildFlagBool("RELEASE_USE_RESOURCE_PROCESSOR_BY_DEFAULT")
}
func (c *config) UseTransitiveJarsInClasspath() bool {
return c.productVariables.GetBuildFlagBool("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH")
}
var (
mainlineApexContributionBuildFlagsToApexNames = map[string]string{
"RELEASE_APEX_CONTRIBUTIONS_ADBD": "com.android.adbd",

View File

@@ -1297,6 +1297,10 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var staticJars android.Paths
var staticHeaderJars android.Paths
var staticResourceJars android.Paths
var transitiveStaticLibsHeaderJars []*android.DepSet[android.Path]
var transitiveStaticLibsImplementationJars []*android.DepSet[android.Path]
var transitiveStaticLibsResourceJars []*android.DepSet[android.Path]
ctx.VisitDirectDeps(func(module android.Module) {
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
tag := ctx.OtherModuleDependencyTag(module)
@@ -1305,66 +1309,111 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
staticJars = append(staticJars, dep.ImplementationJars...)
staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
staticResourceJars = append(staticResourceJars, dep.ResourceJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
if dep.TransitiveStaticLibsImplementationJars != nil {
transitiveStaticLibsImplementationJars = append(transitiveStaticLibsImplementationJars, dep.TransitiveStaticLibsImplementationJars)
}
if dep.TransitiveStaticLibsResourceJars != nil {
transitiveStaticLibsResourceJars = append(transitiveStaticLibsResourceJars, dep.TransitiveStaticLibsResourceJars)
}
}
}
addCLCFromDep(ctx, module, a.classLoaderContexts)
addMissingOptionalUsesLibsFromDep(ctx, module, &a.usesLibrary)
})
completeStaticLibsHeaderJars := android.NewDepSet(android.PREORDER, android.Paths{classpathFile}, transitiveStaticLibsHeaderJars)
completeStaticLibsImplementationJars := android.NewDepSet(android.PREORDER, android.Paths{classpathFile}, transitiveStaticLibsImplementationJars)
completeStaticLibsResourceJars := android.NewDepSet(android.PREORDER, nil, transitiveStaticLibsResourceJars)
var implementationJarFile android.Path
if len(staticJars) > 0 {
combineJars := append(android.Paths{classpathFile}, staticJars...)
combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName).OutputPath
TransformJarsToJar(ctx, combinedImplementationJar, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
implementationJarFile = combinedImplementationJar
var combineJars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
combineJars = completeStaticLibsImplementationJars.ToList()
} else {
combineJars = append(android.Paths{classpathFile}, staticJars...)
}
if len(combineJars) > 1 {
implementationJarOutputPath := android.PathForModuleOut(ctx, "combined", jarName)
TransformJarsToJar(ctx, implementationJarOutputPath, "combine", combineJars, android.OptionalPath{}, false, nil, nil)
implementationJarFile = implementationJarOutputPath
} else {
implementationJarFile = classpathFile
}
var resourceJarFile android.Path
if len(staticResourceJars) > 1 {
var resourceJars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
resourceJars = completeStaticLibsResourceJars.ToList()
} else {
resourceJars = staticResourceJars
}
if len(resourceJars) > 1 {
combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
TransformJarsToJar(ctx, combinedJar, "for resources", staticResourceJars, android.OptionalPath{},
TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
false, nil, nil)
resourceJarFile = combinedJar
} else if len(staticResourceJars) == 1 {
resourceJarFile = staticResourceJars[0]
} else if len(resourceJars) == 1 {
resourceJarFile = resourceJars[0]
}
// merge implementation jar with resources if necessary
implementationAndResourcesJar := implementationJarFile
if resourceJarFile != nil {
jars := android.Paths{resourceJarFile, implementationAndResourcesJar}
var implementationAndResourcesJars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
implementationAndResourcesJars = append(slices.Clone(resourceJars), combineJars...)
} else {
implementationAndResourcesJars = android.PathsIfNonNil(resourceJarFile, implementationJarFile)
}
var implementationAndResourcesJar android.Path
if len(implementationAndResourcesJars) > 1 {
combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for resources", jars, android.OptionalPath{},
TransformJarsToJar(ctx, combinedJar, "for resources", implementationAndResourcesJars, android.OptionalPath{},
false, nil, nil)
implementationAndResourcesJar = combinedJar
} else {
implementationAndResourcesJar = implementationAndResourcesJars[0]
}
a.implementationJarFile = implementationJarFile
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
a.implementationAndResourcesJarFile = implementationAndResourcesJar.WithoutRel()
if len(staticHeaderJars) > 0 {
combineJars := append(android.Paths{classpathFile}, staticHeaderJars...)
var headerJars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
headerJars = completeStaticLibsHeaderJars.ToList()
} else {
headerJars = append(android.Paths{classpathFile}, staticHeaderJars...)
}
if len(headerJars) > 1 {
headerJarFile := android.PathForModuleOut(ctx, "turbine-combined", jarName)
TransformJarsToJar(ctx, headerJarFile, "combine header jars", combineJars, android.OptionalPath{}, false, nil, nil)
TransformJarsToJar(ctx, headerJarFile, "combine header jars", headerJars, android.OptionalPath{}, false, nil, nil)
a.headerJarFile = headerJarFile
} else {
a.headerJarFile = classpathFile
a.headerJarFile = headerJars[0]
}
ctx.CheckbuildFile(a.headerJarFile)
ctx.CheckbuildFile(a.implementationJarFile)
if ctx.Config().UseTransitiveJarsInClasspath() {
ctx.CheckbuildFile(classpathFile)
} else {
ctx.CheckbuildFile(a.headerJarFile)
ctx.CheckbuildFile(a.implementationJarFile)
}
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(a.headerJarFile),
ResourceJars: android.PathsIfNonNil(resourceJarFile),
TransitiveLibsHeaderJarsForR8: a.transitiveLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJarsForR8: a.transitiveStaticLibsHeaderJarsForR8,
ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationAndResourcesJarFile),
ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
StubsLinkType: Implementation,
HeaderJars: android.PathsIfNonNil(a.headerJarFile),
LocalHeaderJars: android.PathsIfNonNil(classpathFile),
TransitiveStaticLibsHeaderJars: completeStaticLibsHeaderJars,
TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars,
ResourceJars: android.PathsIfNonNil(resourceJarFile),
TransitiveLibsHeaderJarsForR8: a.transitiveLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJarsForR8: a.transitiveStaticLibsHeaderJarsForR8,
ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationAndResourcesJarFile),
ImplementationJars: android.PathsIfNonNil(a.implementationJarFile),
StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})

View File

@@ -461,15 +461,10 @@ type Module struct {
// inserting into the bootclasspath/classpath of another compile
headerJarFile android.Path
repackagedHeaderJarFile android.Path
// jar file containing implementation classes including static library dependencies but no
// resources
implementationJarFile android.Path
// jar file containing only resources including from static library dependencies
resourceJar android.Path
// args and dependencies to package source files into a srcjar
srcJarArgs []string
srcJarDeps android.Paths
@@ -1251,7 +1246,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
// Collect .java and .kt files for AIDEGen
j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
var kotlinJars android.Paths
var kotlinHeaderJars android.Paths
// Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before
@@ -1261,6 +1255,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...)
var localImplementationJars android.Paths
// If compiling headers then compile them and skip the rest
if proptools.Bool(j.properties.Headers_only) {
if srcFiles.HasExt(".kt") {
@@ -1270,20 +1266,41 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ctx.ModuleErrorf("headers_only is enabled but Turbine is disabled.")
}
_, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars
localHeaderJars, combinedHeaderJarFile := j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName,
extraCombinedJars)
combinedHeaderJarFile = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
combinedHeaderJarFile = j.repackageFlagsIfNecessary(ctx, combinedHeaderJarFile, jarName, "repackage-turbine")
combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
if jarjared {
localHeaderJars = android.Paths{combinedHeaderJarFile}
transitiveStaticLibsHeaderJars = nil
}
combinedHeaderJarFile, repackaged := j.repackageFlagsIfNecessary(ctx, combinedHeaderJarFile, jarName, "repackage-turbine")
if repackaged {
localHeaderJars = android.Paths{combinedHeaderJarFile}
transitiveStaticLibsHeaderJars = nil
}
if ctx.Failed() {
return
}
j.headerJarFile = combinedHeaderJarFile
ctx.CheckbuildFile(j.headerJarFile)
if ctx.Config().UseTransitiveJarsInClasspath() {
if len(localHeaderJars) > 0 {
ctx.CheckbuildFile(localHeaderJars...)
} else {
// There are no local sources or resources in this module, so there is nothing to checkbuild.
ctx.UncheckedModule()
}
} else {
ctx.CheckbuildFile(j.headerJarFile)
}
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
LocalHeaderJars: localHeaderJars,
TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
AidlIncludeDirs: j.exportAidlIncludeDirs,
@@ -1342,7 +1359,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
srcJars = append(srcJars, kaptSrcJar)
kotlinJars = append(kotlinJars, kaptResJar)
localImplementationJars = append(localImplementationJars, kaptResJar)
// Disable annotation processing in javac, it's already been handled by kapt
flags.processorPath = nil
flags.processors = nil
@@ -1355,21 +1372,24 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
return
}
kotlinJarPath := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")
kotlinJarPath, _ := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")
// Make javac rule depend on the kotlinc rule
flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...)
kotlinJars = append(kotlinJars, kotlinJarPath)
localImplementationJars = append(localImplementationJars, kotlinJarPath)
kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
}
jars := slices.Clone(kotlinJars)
j.compiledSrcJars = srcJars
transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars
enableSharding := false
var headerJarFileWithoutDepsOrJarjar android.Path
var localHeaderJars android.Paths
var shardingHeaderJars android.Paths
var repackagedHeaderJarFile android.Path
if ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine {
if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
enableSharding = true
@@ -1382,11 +1402,26 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
extraJars := slices.Clone(kotlinHeaderJars)
extraJars = append(extraJars, extraCombinedJars...)
var combinedHeaderJarFile android.Path
headerJarFileWithoutDepsOrJarjar, combinedHeaderJarFile =
j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
localHeaderJars, combinedHeaderJarFile = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
shardingHeaderJars = localHeaderJars
j.headerJarFile = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
j.repackagedHeaderJarFile = j.repackageFlagsIfNecessary(ctx, j.headerJarFile, jarName, "turbine")
var jarjared bool
j.headerJarFile, jarjared = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
if jarjared {
// jarjar modifies transitive static dependencies, use the combined header jar and drop the transitive
// static libs header jars.
localHeaderJars = android.Paths{j.headerJarFile}
transitiveStaticLibsHeaderJars = nil
}
var repackaged bool
repackagedHeaderJarFile, repackaged = j.repackageFlagsIfNecessary(ctx, j.headerJarFile, jarName, "turbine")
if repackaged {
// repackage modifies transitive static dependencies, use the combined header jar and drop the transitive
// static libs header jars.
// TODO(b/356688296): this shouldn't export both the unmodified and repackaged header jars
localHeaderJars = android.Paths{j.headerJarFile, repackagedHeaderJarFile}
transitiveStaticLibsHeaderJars = nil
}
}
if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 {
hasErrorproneableFiles := false
@@ -1421,8 +1456,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
}
if enableSharding {
if headerJarFileWithoutDepsOrJarjar != nil {
flags.classpath = append(classpath{headerJarFileWithoutDepsOrJarjar}, flags.classpath...)
if len(shardingHeaderJars) > 0 {
flags.classpath = append(classpath(slices.Clone(shardingHeaderJars)), flags.classpath...)
}
shardSize := int(*(j.properties.Javac_shard_size))
var shardSrcs []android.Paths
@@ -1431,8 +1466,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
for idx, shardSrc := range shardSrcs {
classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
nil, flags, extraJarDeps)
classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
jars = append(jars, classes)
classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
localImplementationJars = append(localImplementationJars, classes)
}
}
// Assume approximately 5 sources per srcjar.
@@ -1444,21 +1479,21 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
for idx, shardSrcJars := range shardSrcJarsList {
classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
nil, shardSrcJars, flags, extraJarDeps)
classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
jars = append(jars, classes)
classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
localImplementationJars = append(localImplementationJars, classes)
}
}
} else {
classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
jars = append(jars, classes)
classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
localImplementationJars = append(localImplementationJars, classes)
}
if ctx.Failed() {
return
}
}
jars = append(jars, extraCombinedJars...)
localImplementationJars = append(localImplementationJars, extraCombinedJars...)
j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles
@@ -1485,42 +1520,18 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
resArgs = append(resArgs, extraArgs...)
resDeps = append(resDeps, extraDeps...)
var localResourceJars android.Paths
if len(resArgs) > 0 {
resourceJar := android.PathForModuleOut(ctx, "res", jarName)
TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
j.resourceJar = resourceJar
if ctx.Failed() {
return
}
localResourceJars = append(localResourceJars, resourceJar)
}
var resourceJars android.Paths
if j.resourceJar != nil {
resourceJars = append(resourceJars, j.resourceJar)
}
if Bool(j.properties.Include_srcs) {
resourceJars = append(resourceJars, includeSrcJar)
}
resourceJars = append(resourceJars, deps.staticResourceJars...)
if len(resourceJars) > 1 {
combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
false, nil, nil)
j.resourceJar = combinedJar
} else if len(resourceJars) == 1 {
j.resourceJar = resourceJars[0]
}
if len(deps.staticJars) > 0 {
jars = append(jars, deps.staticJars...)
}
jars = append(jars, extraDepCombinedJars...)
manifest := j.overrideManifest
if !manifest.Valid() && j.properties.Manifest != nil {
manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
localResourceJars = append(localResourceJars, includeSrcJar)
}
services := android.PathsForModuleSrc(ctx, j.properties.Services)
@@ -1545,35 +1556,68 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
Implicits: services,
Args: args,
})
jars = append(jars, servicesJar)
localResourceJars = append(localResourceJars, servicesJar)
}
completeStaticLibsResourceJars := android.NewDepSet(android.PREORDER, localResourceJars, deps.transitiveStaticLibsResourceJars)
var combinedResourceJar android.Path
var resourceJars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
resourceJars = completeStaticLibsResourceJars.ToList()
} else {
resourceJars = append(slices.Clone(localResourceJars), deps.staticResourceJars...)
}
if len(resourceJars) == 1 {
combinedResourceJar = resourceJars[0]
} else if len(resourceJars) > 0 {
combinedJar := android.PathForModuleOut(ctx, "res-combined", jarName)
TransformJarsToJar(ctx, combinedJar, "for resources", resourceJars, android.OptionalPath{},
false, nil, nil)
combinedResourceJar = combinedJar
}
manifest := j.overrideManifest
if !manifest.Valid() && j.properties.Manifest != nil {
manifest = android.OptionalPathForPath(android.PathForModuleSrc(ctx, *j.properties.Manifest))
}
// Combine the classes built from sources, any manifests, and any static libraries into
// classes.jar. If there is only one input jar this step will be skipped.
var outputFile android.Path
completeStaticLibsImplementationJars := android.NewDepSet(android.PREORDER, localImplementationJars, deps.transitiveStaticLibsImplementationJars)
var jars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
jars = completeStaticLibsImplementationJars.ToList()
} else {
jars = append(slices.Clone(localImplementationJars), deps.staticJars...)
}
jars = append(jars, extraDepCombinedJars...)
if len(jars) == 1 && !manifest.Valid() {
// Optimization: skip the combine step as there is nothing to do
// TODO(ccross): this leaves any module-info.class files, but those should only come from
// prebuilt dependencies until we support modules in the platform build, so there shouldn't be
// any if len(jars) == 1.
// any if len(extraJars) == 0.
// moduleStubLinkType determines if the module is the TopLevelStubLibrary generated
// from sdk_library. The TopLevelStubLibrary contains only one static lib,
// either with .from-source or .from-text suffix.
// outputFile should be agnostic to the build configuration,
// thus "combine" the single static lib in order to prevent the static lib from being exposed
// thus copy the single input static lib in order to prevent the static lib from being exposed
// to the copy rules.
stub, _ := moduleStubLinkType(j)
if stub {
combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
if stub, _ := moduleStubLinkType(j); stub {
copiedJar := android.PathForModuleOut(ctx, "combined", jarName)
ctx.Build(pctx, android.BuildParams{
Rule: android.Cp,
Input: jars[0],
Output: combinedJar,
Output: copiedJar,
})
outputFile = combinedJar
completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, android.Paths{copiedJar}, nil)
outputFile = copiedJar
} else {
outputFile = jars[0]
}
@@ -1585,13 +1629,21 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
}
// jarjar implementation jar if necessary
jarjarFile := j.jarjarIfNecessary(ctx, outputFile, jarName, "")
jarjarFile, jarjarred := j.jarjarIfNecessary(ctx, outputFile, jarName, "")
if jarjarred {
localImplementationJars = android.Paths{jarjarFile}
completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, localImplementationJars, nil)
}
outputFile = jarjarFile
// jarjar resource jar if necessary
if j.resourceJar != nil {
resourceJarJarFile := j.jarjarIfNecessary(ctx, j.resourceJar, jarName, "resource")
j.resourceJar = resourceJarJarFile
if combinedResourceJar != nil {
resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource")
combinedResourceJar = resourceJarJarFile
if jarjarred {
localResourceJars = android.Paths{resourceJarJarFile}
completeStaticLibsResourceJars = android.NewDepSet(android.PREORDER, localResourceJars, nil)
}
}
if ctx.Failed() {
@@ -1659,6 +1711,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName)
convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile)
j.headerJarFile = headerJarFile
if len(localImplementationJars) == 1 && ctx.Config().UseTransitiveJarsInClasspath() {
localHeaderJarFile := android.PathForModuleOut(ctx, "local-javac-header", jarName)
convertImplementationJarToHeaderJar(ctx, localImplementationJars[0], localHeaderJarFile)
localHeaderJars = append(localHeaderJars, localHeaderJarFile)
} else {
localHeaderJars = append(localHeaderJars, headerJarFile)
}
}
// enforce syntax check to jacoco filters for any build (http://b/183622051)
@@ -1672,16 +1731,27 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
}
// merge implementation jar with resources if necessary
implementationAndResourcesJar := outputFile
if j.resourceJar != nil {
jars := android.Paths{j.resourceJar, implementationAndResourcesJar}
combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest,
false, nil, nil)
implementationAndResourcesJar = combinedJar
var implementationAndResourcesJarsToCombine android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
resourceJars := completeStaticLibsResourceJars.ToList()
if len(resourceJars) > 0 {
implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJars.ToList()...)
implementationAndResourcesJarsToCombine = append(implementationAndResourcesJarsToCombine, extraDepCombinedJars...)
}
} else {
if combinedResourceJar != nil {
implementationAndResourcesJarsToCombine = android.Paths{combinedResourceJar, outputFile}
}
}
j.implementationAndResourcesJar = implementationAndResourcesJar
if len(implementationAndResourcesJarsToCombine) > 0 {
combinedJar := android.PathForModuleOut(ctx, "withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for resources", implementationAndResourcesJarsToCombine, manifest,
false, nil, nil)
outputFile = combinedJar
}
j.implementationAndResourcesJar = outputFile
// Enable dex compilation for the APEX variants, unless it is disabled explicitly
compileDex := j.dexProperties.Compile_dex
@@ -1707,7 +1777,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
flags: flags,
sdkVersion: j.SdkVersion(ctx),
minSdkVersion: j.MinSdkVersion(ctx),
classesJar: implementationAndResourcesJar,
classesJar: outputFile,
jarName: jarName,
}
if j.GetProfileGuided() && j.optimizeOrObfuscateEnabled() && !j.EnableProfileRewriting() {
@@ -1733,10 +1803,20 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
}
// merge dex jar with resources if necessary
if j.resourceJar != nil {
jars := android.Paths{dexOutputFile, j.resourceJar}
var dexAndResourceJarsToCombine android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
resourceJars := completeStaticLibsResourceJars.ToList()
if len(resourceJars) > 0 {
dexAndResourceJarsToCombine = append(android.Paths{dexOutputFile}, resourceJars...)
}
} else {
if combinedResourceJar != nil {
dexAndResourceJarsToCombine = android.Paths{dexOutputFile, combinedResourceJar}
}
}
if len(dexAndResourceJarsToCombine) > 0 {
combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
TransformJarsToJar(ctx, combinedJar, "for dex resources", dexAndResourceJarsToCombine, android.OptionalPath{},
false, nil, nil)
if *j.dexProperties.Uncompress_dex {
combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
@@ -1769,15 +1849,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
} else {
// There is no code to compile into a dex jar, make sure the resources are propagated
// to the APK if this is an app.
outputFile = implementationAndResourcesJar
j.dexJarFile = makeDexJarPathFromPath(j.resourceJar)
j.dexJarFile = makeDexJarPathFromPath(combinedResourceJar)
}
if ctx.Failed() {
return
}
} else {
outputFile = implementationAndResourcesJar
}
if ctx.Device() {
@@ -1809,17 +1886,34 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
j.collectTransitiveSrcFiles(ctx, srcFiles)
ctx.CheckbuildFile(j.implementationJarFile)
ctx.CheckbuildFile(j.headerJarFile)
if ctx.Config().UseTransitiveJarsInClasspath() {
if len(localImplementationJars) > 0 || len(localResourceJars) > 0 || len(localHeaderJars) > 0 {
ctx.CheckbuildFile(localImplementationJars...)
ctx.CheckbuildFile(localResourceJars...)
ctx.CheckbuildFile(localHeaderJars...)
} else {
// There are no local sources or resources in this module, so there is nothing to checkbuild.
ctx.UncheckedModule()
}
} else {
ctx.CheckbuildFile(j.implementationJarFile)
ctx.CheckbuildFile(j.headerJarFile)
}
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
RepackagedHeaderJars: android.PathsIfNonNil(j.repackagedHeaderJarFile),
HeaderJars: android.PathsIfNonNil(j.headerJarFile),
RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),
LocalHeaderJars: localHeaderJars,
TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars,
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
ResourceJars: android.PathsIfNonNil(j.resourceJar),
ResourceJars: android.PathsIfNonNil(combinedResourceJar),
AidlIncludeDirs: j.exportAidlIncludeDirs,
SrcJarArgs: j.srcJarArgs,
SrcJarDeps: j.srcJarDeps,
@@ -1955,22 +2049,26 @@ func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
deps deps, flags javaBuilderFlags, jarName string,
extraJars android.Paths) (headerJar android.Path, combinedHeaderJar android.Path) {
extraJars android.Paths) (localHeaderJars android.Paths, combinedHeaderJar android.Path) {
var jars android.Paths
if len(srcFiles) > 0 || len(srcJars) > 0 {
// Compile java sources into turbine.jar.
turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
jars = append(jars, turbineJar)
headerJar = turbineJar
localHeaderJars = append(localHeaderJars, turbineJar)
}
jars = append(jars, extraJars...)
localHeaderJars = append(localHeaderJars, extraJars...)
// Combine any static header libraries into classes-header.jar. If there is only
// one input jar this step will be skipped.
jars = append(jars, deps.staticHeaderJars...)
var jars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
depSet := android.NewDepSet(android.PREORDER, localHeaderJars, deps.transitiveStaticLibsHeaderJars)
jars = depSet.ToList()
} else {
jars = append(slices.Clone(localHeaderJars), deps.staticHeaderJars...)
}
// we cannot skip the combine step for now if there is only one jar
// since we have to strip META-INF/TRANSITIVE dir from turbine.jar
@@ -1978,9 +2076,7 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{},
false, nil, []string{"META-INF/TRANSITIVE"})
ctx.CheckbuildFile(combinedHeaderJarOutputPath)
return headerJar, combinedHeaderJarOutputPath
return localHeaderJars, combinedHeaderJarOutputPath
}
func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
@@ -2036,6 +2132,7 @@ func (j *providesTransitiveHeaderJarsForR8) collectTransitiveHeaderJarsForR8(ctx
if dep.TransitiveStaticLibsHeaderJarsForR8 != nil {
transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJarsForR8)
}
}
})
j.transitiveLibsHeaderJarsForR8 = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs)
@@ -2283,29 +2380,17 @@ func (j *Module) checkSdkLinkType(
func (j *Module) collectDeps(ctx android.ModuleContext) deps {
var deps deps
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
if sdkDep.invalidVersion {
ctx.AddMissingDependencies(sdkDep.bootclasspath)
ctx.AddMissingDependencies(sdkDep.java9Classpath)
} else if sdkDep.useFiles {
// sdkDep.jar is actually equivalent to turbine header.jar.
deps.classpath = append(deps.classpath, sdkDep.jars...)
deps.dexClasspath = append(deps.dexClasspath, sdkDep.jars...)
deps.aidlPreprocess = sdkDep.aidl
// Add the sdk module dependency to `compileDepNames`.
// This ensures that the dependency is reported in `module_bp_java_deps.json`
// TODO (b/358608607): Move this to decodeSdkDep
sdkSpec := android.SdkContext(j).SdkVersion(ctx)
j.compileDepNames = append(j.compileDepNames, fmt.Sprintf("sdk_%s_%s_android", sdkSpec.Kind.String(), sdkSpec.ApiLevel.String()))
} else {
deps.aidlPreprocess = sdkDep.aidl
}
}
sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName())
j.collectTransitiveHeaderJarsForR8(ctx)
var transitiveBootClasspathHeaderJars []*android.DepSet[android.Path]
var transitiveClasspathHeaderJars []*android.DepSet[android.Path]
var transitiveJava9ClasspathHeaderJars []*android.DepSet[android.Path]
var transitiveStaticJarsHeaderLibs []*android.DepSet[android.Path]
var transitiveStaticJarsImplementationLibs []*android.DepSet[android.Path]
var transitiveStaticJarsResourceLibs []*android.DepSet[android.Path]
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@@ -2325,6 +2410,10 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))
deps.classpath = append(deps.classpath, depHeaderJars...)
deps.dexClasspath = append(deps.dexClasspath, depHeaderJars...)
// TODO: SDK libraries should export a provider with TransitiveClasspathHeaderJars
depHeaderJarsSet := android.NewDepSet(android.PREORDER, depHeaderJars, nil)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, depHeaderJarsSet)
case staticLibTag:
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
}
@@ -2340,6 +2429,9 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
switch tag {
case bootClasspathTag:
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
case sdkLibTag, libTag, instrumentationForTag:
if _, ok := module.(*Plugin); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName)
@@ -2353,8 +2445,15 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
case java9LibTag:
deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
case staticLibTag:
if _, ok := module.(*Plugin); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName)
@@ -2370,6 +2469,17 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// optimization.
deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, dep.TransitiveStaticLibsHeaderJars)
}
if dep.TransitiveStaticLibsImplementationJars != nil {
transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, dep.TransitiveStaticLibsImplementationJars)
}
if dep.TransitiveStaticLibsResourceJars != nil {
transitiveStaticJarsResourceLibs = append(transitiveStaticJarsResourceLibs, dep.TransitiveStaticLibsResourceJars)
}
case pluginTag:
if plugin, ok := module.(*Plugin); ok {
if plugin.pluginProperties.Processor_class != nil {
@@ -2418,11 +2528,18 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
checkProducesJars(ctx, dep)
deps.classpath = append(deps.classpath, dep.Srcs()...)
deps.dexClasspath = append(deps.classpath, dep.Srcs()...)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars,
android.NewDepSet(android.PREORDER, dep.Srcs(), nil))
case staticLibTag:
checkProducesJars(ctx, dep)
deps.classpath = append(deps.classpath, dep.Srcs()...)
deps.staticJars = append(deps.staticJars, dep.Srcs()...)
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.Srcs()...)
depHeaderJars := android.NewDepSet(android.PREORDER, dep.Srcs(), nil)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, depHeaderJars)
transitiveStaticJarsHeaderLibs = append(transitiveStaticJarsHeaderLibs, depHeaderJars)
transitiveStaticJarsImplementationLibs = append(transitiveStaticJarsImplementationLibs, depHeaderJars)
}
} else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
switch tag {
@@ -2435,8 +2552,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// If a system modules dependency has been added to the bootclasspath
// then add its libs to the bootclasspath.
if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
depHeaderJars := sm.HeaderJars
deps.bootClasspath = append(deps.bootClasspath, depHeaderJars...)
deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars...)
if sm.TransitiveStaticLibsHeaderJars != nil {
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars,
sm.TransitiveStaticLibsHeaderJars)
}
} else {
ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider",
ctx.OtherModuleName(module))
@@ -2467,6 +2587,39 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary)
})
deps.transitiveStaticLibsHeaderJars = transitiveStaticJarsHeaderLibs
deps.transitiveStaticLibsImplementationJars = transitiveStaticJarsImplementationLibs
deps.transitiveStaticLibsResourceJars = transitiveStaticJarsResourceLibs
if ctx.Config().UseTransitiveJarsInClasspath() {
depSet := android.NewDepSet(android.PREORDER, nil, transitiveClasspathHeaderJars)
deps.classpath = depSet.ToList()
depSet = android.NewDepSet(android.PREORDER, nil, transitiveBootClasspathHeaderJars)
deps.bootClasspath = depSet.ToList()
depSet = android.NewDepSet(android.PREORDER, nil, transitiveJava9ClasspathHeaderJars)
deps.java9Classpath = depSet.ToList()
}
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, android.SdkContext(j))
if sdkDep.invalidVersion {
ctx.AddMissingDependencies(sdkDep.bootclasspath)
ctx.AddMissingDependencies(sdkDep.java9Classpath)
} else if sdkDep.useFiles {
// sdkDep.jar is actually equivalent to turbine header.jar.
deps.classpath = append(slices.Clone(classpath(sdkDep.jars)), deps.classpath...)
deps.dexClasspath = append(slices.Clone(classpath(sdkDep.jars)), deps.dexClasspath...)
deps.aidlPreprocess = sdkDep.aidl
// Add the sdk module dependency to `compileDepNames`.
// This ensures that the dependency is reported in `module_bp_java_deps.json`
// TODO (b/358608607): Move this to decodeSdkDep
sdkSpec := android.SdkContext(j).SdkVersion(ctx)
j.compileDepNames = append(j.compileDepNames, fmt.Sprintf("sdk_%s_%s_android", sdkSpec.Kind.String(), sdkSpec.ApiLevel.String()))
} else {
deps.aidlPreprocess = sdkDep.aidl
}
}
return deps
}
@@ -2778,22 +2931,22 @@ func getJarJarRuleText(provider *JarJarProviderData) string {
}
// Repackage the flags if the jarjar rule txt for the flags is generated
func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) android.Path {
func (j *Module) repackageFlagsIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) (android.Path, bool) {
if j.repackageJarjarRules == nil {
return infile
return infile, false
}
repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info, jarName)
TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules)
return repackagedJarjarFile
return repackagedJarjarFile, true
}
func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) android.Path {
func (j *Module) jarjarIfNecessary(ctx android.ModuleContext, infile android.Path, jarName, info string) (android.Path, bool) {
if j.expandJarjarRules == nil {
return infile
return infile, false
}
jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName)
TransformJarJar(ctx, jarjarFile, infile, j.expandJarjarRules)
return jarjarFile
return jarjarFile, true
}

View File

@@ -96,6 +96,10 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont
ctx.PropertyErrorf("libs", "at least one dependency is required")
}
var transitiveHeaderJars []*android.DepSet[android.Path]
var transitiveImplementationJars []*android.DepSet[android.Path]
var transitiveResourceJars []*android.DepSet[android.Path]
ctx.VisitDirectDepsWithTag(deviceHostConverterDepTag, func(m android.Module) {
if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
d.headerJars = append(d.headerJars, dep.HeaderJars...)
@@ -105,6 +109,16 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont
d.srcJarArgs = append(d.srcJarArgs, dep.SrcJarArgs...)
d.srcJarDeps = append(d.srcJarDeps, dep.SrcJarDeps...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveHeaderJars = append(transitiveHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
if dep.TransitiveStaticLibsImplementationJars != nil {
transitiveImplementationJars = append(transitiveImplementationJars, dep.TransitiveStaticLibsImplementationJars)
}
if dep.TransitiveStaticLibsResourceJars != nil {
transitiveResourceJars = append(transitiveResourceJars, dep.TransitiveStaticLibsResourceJars)
}
} else {
ctx.PropertyErrorf("libs", "module %q cannot be used as a dependency", ctx.OtherModuleName(m))
}
@@ -131,13 +145,17 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont
}
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: d.headerJars,
ImplementationAndResourcesJars: d.implementationAndResourceJars,
ImplementationJars: d.implementationJars,
ResourceJars: d.resourceJars,
SrcJarArgs: d.srcJarArgs,
SrcJarDeps: d.srcJarDeps,
StubsLinkType: Implementation,
HeaderJars: d.headerJars,
LocalHeaderJars: d.headerJars,
TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, nil, transitiveHeaderJars),
TransitiveStaticLibsImplementationJars: android.NewDepSet(android.PREORDER, nil, transitiveImplementationJars),
TransitiveStaticLibsResourceJars: android.NewDepSet(android.PREORDER, nil, transitiveResourceJars),
ImplementationAndResourcesJars: d.implementationAndResourceJars,
ImplementationJars: d.implementationJars,
ResourceJars: d.resourceJars,
SrcJarArgs: d.srcJarArgs,
SrcJarDeps: d.srcJarDeps,
StubsLinkType: Implementation,
// TODO: Not sure if aconfig flags that have been moved between device and host variants
// make sense.
})

View File

@@ -254,6 +254,7 @@ var ProguardSpecInfoProvider = blueprint.NewProvider[ProguardSpecInfo]()
type JavaInfo struct {
// HeaderJars is a list of jars that can be passed as the javac classpath in order to link
// against this module. If empty, ImplementationJars should be used instead.
// Unlike LocalHeaderJars, HeaderJars includes classes from static dependencies.
HeaderJars android.Paths
RepackagedHeaderJars android.Paths
@@ -264,6 +265,15 @@ type JavaInfo struct {
// set of header jars for all transitive static libs deps
TransitiveStaticLibsHeaderJarsForR8 *android.DepSet[android.Path]
// depset of header jars for this module and all transitive static dependencies
TransitiveStaticLibsHeaderJars *android.DepSet[android.Path]
// depset of implementation jars for this module and all transitive static dependencies
TransitiveStaticLibsImplementationJars *android.DepSet[android.Path]
// depset of resource jars for this module and all transitive static dependencies
TransitiveStaticLibsResourceJars *android.DepSet[android.Path]
// ImplementationAndResourceJars is a list of jars that contain the implementations of classes
// in the module as well as any resources included in the module.
ImplementationAndResourcesJars android.Paths
@@ -275,6 +285,9 @@ type JavaInfo struct {
// ResourceJars is a list of jars that contain the resources included in the module.
ResourceJars android.Paths
// LocalHeaderJars is a list of jars that contain classes from this module, but not from any static dependencies.
LocalHeaderJars android.Paths
// AidlIncludeDirs is a list of directories that should be passed to the aidl tool when
// depending on this module.
AidlIncludeDirs android.Paths
@@ -568,6 +581,10 @@ type deps struct {
aconfigProtoFiles android.Paths
disableTurbine bool
transitiveStaticLibsHeaderJars []*android.DepSet[android.Path]
transitiveStaticLibsImplementationJars []*android.DepSet[android.Path]
transitiveStaticLibsResourceJars []*android.DepSet[android.Path]
}
func checkProducesJars(ctx android.ModuleContext, dep android.SourceFileProducer) {
@@ -1008,7 +1025,7 @@ func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName s
}
hostDexNeeded := Bool(j.deviceProperties.Hostdex) && !ctx.Host()
if hostDexNeeded {
j.hostdexInstallFile = ctx.InstallFile(
j.hostdexInstallFile = ctx.InstallFileWithoutCheckbuild(
android.PathForHostDexInstall(ctx, "framework"),
j.Stem()+"-hostdex.jar", j.outputFile)
}
@@ -1022,7 +1039,7 @@ func (j *Library) setInstallRules(ctx android.ModuleContext, installModuleName s
} else {
installDir = android.PathForModuleInstall(ctx, "framework")
}
j.installFile = ctx.InstallFile(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...)
j.installFile = ctx.InstallFileWithoutCheckbuild(installDir, j.Stem()+".jar", j.outputFile, extraInstallDeps...)
}
}
@@ -2359,11 +2376,14 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.Phony(ctx.ModuleName(), al.stubsJar)
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(al.stubsJar),
ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar),
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
AidlIncludeDirs: android.Paths{},
StubsLinkType: Stubs,
HeaderJars: android.PathsIfNonNil(al.stubsJar),
LocalHeaderJars: android.PathsIfNonNil(al.stubsJar),
TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
TransitiveStaticLibsImplementationJars: android.NewDepSet(android.PREORDER, android.PathsIfNonNil(al.stubsJar), nil),
ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar),
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
AidlIncludeDirs: android.Paths{},
StubsLinkType: Stubs,
// No aconfig libraries on api libraries
})
}
@@ -2634,6 +2654,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var flags javaBuilderFlags
var transitiveClasspathHeaderJars []*android.DepSet[android.Path]
var transitiveBootClasspathHeaderJars []*android.DepSet[android.Path]
var transitiveStaticLibsHeaderJars []*android.DepSet[android.Path]
var transitiveStaticLibsImplementationJars []*android.DepSet[android.Path]
var transitiveStaticLibsResourceJars []*android.DepSet[android.Path]
j.collectTransitiveHeaderJarsForR8(ctx)
var staticJars android.Paths
var staticResourceJars android.Paths
@@ -2645,32 +2671,67 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
case libTag, sdkLibTag:
flags.classpath = append(flags.classpath, dep.HeaderJars...)
flags.dexClasspath = append(flags.dexClasspath, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
case staticLibTag:
flags.classpath = append(flags.classpath, dep.HeaderJars...)
staticJars = append(staticJars, dep.ImplementationJars...)
staticResourceJars = append(staticResourceJars, dep.ResourceJars...)
staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
if dep.TransitiveStaticLibsImplementationJars != nil {
transitiveStaticLibsImplementationJars = append(transitiveStaticLibsImplementationJars, dep.TransitiveStaticLibsImplementationJars)
}
if dep.TransitiveStaticLibsResourceJars != nil {
transitiveStaticLibsResourceJars = append(transitiveStaticLibsResourceJars, dep.TransitiveStaticLibsResourceJars)
}
case bootClasspathTag:
flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
}
} else if dep, ok := module.(SdkLibraryDependency); ok {
switch tag {
case libTag, sdkLibTag:
flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))...)
depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))
flags.classpath = append(flags.classpath, depHeaderJars...)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars,
android.NewDepSet(android.PREORDER, depHeaderJars, nil))
}
}
addCLCFromDep(ctx, module, j.classLoaderContexts)
})
jars := android.PathsForModuleSrc(ctx, j.properties.Jars)
localJars := android.PathsForModuleSrc(ctx, j.properties.Jars)
jarName := j.Stem() + ".jar"
// Combine only the local jars together for use in transitive classpaths.
// Always pass input jar through TransformJarsToJar to strip module-info.class from prebuilts.
localCombinedHeaderJar := android.PathForModuleOut(ctx, "local-combined", jarName)
TransformJarsToJar(ctx, localCombinedHeaderJar, "combine local prebuilt implementation jars", localJars, android.OptionalPath{},
false, j.properties.Exclude_files, j.properties.Exclude_dirs)
localStrippedJars := android.Paths{localCombinedHeaderJar}
completeStaticLibsHeaderJars := android.NewDepSet(android.PREORDER, localStrippedJars, transitiveStaticLibsHeaderJars)
completeStaticLibsImplementationJars := android.NewDepSet(android.PREORDER, localStrippedJars, transitiveStaticLibsImplementationJars)
completeStaticLibsResourceJars := android.NewDepSet(android.PREORDER, nil, transitiveStaticLibsResourceJars)
// 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.
var outputFile android.Path
combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName)
implementationJars := append(slices.Clone(jars), staticJars...)
var implementationJars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
implementationJars = completeStaticLibsImplementationJars.ToList()
} else {
implementationJars = append(slices.Clone(localJars), staticJars...)
}
TransformJarsToJar(ctx, combinedImplementationJar, "combine prebuilt implementation jars", implementationJars, android.OptionalPath{},
false, j.properties.Exclude_files, j.properties.Exclude_dirs)
outputFile = combinedImplementationJar
@@ -2693,7 +2754,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
if reuseImplementationJarAsHeaderJar {
headerJar = outputFile
} else {
headerJars := append(slices.Clone(jars), staticHeaderJars...)
var headerJars android.Paths
if ctx.Config().UseTransitiveJarsInClasspath() {
headerJars = completeStaticLibsHeaderJars.ToList()
} else {
headerJars = append(slices.Clone(localJars), 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)
@@ -2712,6 +2778,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
} else {
headerJar = outputFile
}
// Enabling jetifier requires modifying classes from transitive dependencies, disable transitive
// classpath and use the combined header jar instead.
completeStaticLibsHeaderJars = android.NewDepSet(android.PREORDER, android.Paths{headerJar}, nil)
completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, android.Paths{outputFile}, nil)
}
implementationJarFile := outputFile
@@ -2735,7 +2806,11 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.exportAidlIncludeDirs = android.PathsForModuleSrc(ctx, j.properties.Aidl.Export_include_dirs)
ctx.CheckbuildFile(outputFile)
if ctx.Config().UseTransitiveJarsInClasspath() {
ctx.CheckbuildFile(localJars...)
} else {
ctx.CheckbuildFile(outputFile)
}
if ctx.Device() {
// If this is a variant created for a prebuilt_apex then use the dex implementation jar
@@ -2817,14 +2892,18 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile),
ImplementationJars: android.PathsIfNonNil(implementationJarFile.WithoutRel()),
ResourceJars: android.PathsIfNonNil(resourceJarFile),
AidlIncludeDirs: j.exportAidlIncludeDirs,
StubsLinkType: j.stubsLinkType,
HeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
LocalHeaderJars: android.PathsIfNonNil(j.combinedHeaderFile),
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJars: completeStaticLibsHeaderJars,
TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars,
ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedImplementationFile),
ImplementationJars: android.PathsIfNonNil(implementationJarFile.WithoutRel()),
ResourceJars: android.PathsIfNonNil(resourceJarFile),
AidlIncludeDirs: j.exportAidlIncludeDirs,
StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})

View File

@@ -20,6 +20,7 @@ import (
"path/filepath"
"reflect"
"runtime"
"slices"
"strconv"
"strings"
"testing"
@@ -211,7 +212,7 @@ func TestJavaLinkType(t *testing.T) {
}
func TestSimple(t *testing.T) {
ctx, _ := testJava(t, `
bp := `
java_library {
name: "foo",
srcs: ["a.java"],
@@ -222,31 +223,157 @@ func TestSimple(t *testing.T) {
java_library {
name: "bar",
srcs: ["b.java"],
static_libs: ["quz"],
}
java_library {
name: "baz",
srcs: ["c.java"],
static_libs: ["quz"],
}
`)
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac")
java_library {
name: "quz",
srcs: ["d.java"],
}`
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
frameworkTurbineCombinedJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar",
}
baz := ctx.ModuleForTests("baz", "android_common").Rule("javac").Output.String()
barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar")
bazTurbine := filepath.Join("out", "soong", ".intermediates", "baz", "android_common", "turbine-combined", "baz.jar")
frameworkTurbineJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
}
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], barTurbine)
testCases := []struct {
name string
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], bazTurbine)
preparer android.FixturePreparer
if len(combineJar.Inputs) != 2 || combineJar.Inputs[1].String() != baz {
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz)
fooJavacInputs []string
fooJavacClasspath []string
fooCombinedInputs []string
fooHeaderCombinedInputs []string
barJavacInputs []string
barJavacClasspath []string
barCombinedInputs []string
barHeaderCombinedInputs []string
}{
{
name: "normal",
preparer: android.NullFixturePreparer,
fooJavacInputs: []string{"a.java"},
fooJavacClasspath: slices.Concat(
frameworkTurbineCombinedJars,
[]string{
"out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar",
"out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
},
),
fooCombinedInputs: []string{
"out/soong/.intermediates/foo/android_common/javac/foo.jar",
"out/soong/.intermediates/baz/android_common/combined/baz.jar",
},
fooHeaderCombinedInputs: []string{
"out/soong/.intermediates/foo/android_common/turbine/foo.jar",
"out/soong/.intermediates/baz/android_common/turbine-combined/baz.jar",
},
barJavacInputs: []string{"b.java"},
barJavacClasspath: slices.Concat(
frameworkTurbineCombinedJars,
[]string{
"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
},
),
barCombinedInputs: []string{
"out/soong/.intermediates/bar/android_common/javac/bar.jar",
"out/soong/.intermediates/quz/android_common/javac/quz.jar",
},
barHeaderCombinedInputs: []string{
"out/soong/.intermediates/bar/android_common/turbine/bar.jar",
"out/soong/.intermediates/quz/android_common/turbine-combined/quz.jar",
},
},
{
name: "transitive classpath",
preparer: PrepareForTestWithTransitiveClasspathEnabled,
fooJavacInputs: []string{"a.java"},
fooJavacClasspath: slices.Concat(
frameworkTurbineJars,
[]string{
"out/soong/.intermediates/bar/android_common/turbine/bar.jar",
"out/soong/.intermediates/quz/android_common/turbine/quz.jar",
"out/soong/.intermediates/baz/android_common/turbine/baz.jar",
},
),
fooCombinedInputs: []string{
"out/soong/.intermediates/foo/android_common/javac/foo.jar",
"out/soong/.intermediates/baz/android_common/javac/baz.jar",
"out/soong/.intermediates/quz/android_common/javac/quz.jar",
},
fooHeaderCombinedInputs: []string{
"out/soong/.intermediates/foo/android_common/turbine/foo.jar",
"out/soong/.intermediates/baz/android_common/turbine/baz.jar",
"out/soong/.intermediates/quz/android_common/turbine/quz.jar",
},
barJavacInputs: []string{"b.java"},
barJavacClasspath: slices.Concat(
frameworkTurbineJars,
[]string{"out/soong/.intermediates/quz/android_common/turbine/quz.jar"},
),
barCombinedInputs: []string{
"out/soong/.intermediates/bar/android_common/javac/bar.jar",
"out/soong/.intermediates/quz/android_common/javac/quz.jar",
},
barHeaderCombinedInputs: []string{
"out/soong/.intermediates/bar/android_common/turbine/bar.jar",
"out/soong/.intermediates/quz/android_common/turbine/quz.jar",
},
},
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
result := android.GroupFixturePreparers(
PrepareForTestWithJavaDefaultModules,
tt.preparer,
).RunTestWithBp(t, bp)
foo := result.ModuleForTests("foo", "android_common")
fooJavac := foo.Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "foo javac inputs", tt.fooJavacInputs, fooJavac.Inputs)
fooJavacClasspath := fooJavac.Args["classpath"]
android.AssertStringPathsRelativeToTopEquals(t, "foo javac classpath", result.Config, tt.fooJavacClasspath,
strings.Split(strings.TrimPrefix(fooJavacClasspath, "-classpath "), ":"))
fooCombinedJar := foo.Output("combined/foo.jar")
android.AssertPathsRelativeToTopEquals(t, "foo combined inputs", tt.fooCombinedInputs, fooCombinedJar.Inputs)
fooCombinedHeaderJar := foo.Output("turbine-combined/foo.jar")
android.AssertPathsRelativeToTopEquals(t, "foo header combined inputs", tt.fooHeaderCombinedInputs, fooCombinedHeaderJar.Inputs)
bar := result.ModuleForTests("bar", "android_common")
barJavac := bar.Rule("javac")
android.AssertPathsRelativeToTopEquals(t, "bar javac inputs", tt.barJavacInputs, barJavac.Inputs)
barJavacClasspath := barJavac.Args["classpath"]
android.AssertStringPathsRelativeToTopEquals(t, "bar javac classpath", result.Config, tt.barJavacClasspath,
strings.Split(strings.TrimPrefix(barJavacClasspath, "-classpath "), ":"))
barCombinedJar := bar.Output("combined/bar.jar")
android.AssertPathsRelativeToTopEquals(t, "bar combined inputs", tt.barCombinedInputs, barCombinedJar.Inputs)
barCombinedHeaderJar := bar.Output("turbine-combined/bar.jar")
android.AssertPathsRelativeToTopEquals(t, "bar header combined inputs", tt.barHeaderCombinedInputs, barCombinedHeaderJar.Inputs)
})
}
}
@@ -590,7 +717,7 @@ func TestPrebuilts(t *testing.T) {
barModule := ctx.ModuleForTests("bar", "android_common")
barJar := barModule.Output("combined/bar.jar").Output
bazModule := ctx.ModuleForTests("baz", "android_common")
bazJar := bazModule.Rule("combineJar").Output
bazJar := bazModule.Output("combined/baz.jar").Output
sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").
Output("combined/sdklib.stubs.jar").Output

View File

@@ -56,6 +56,13 @@ func TestKotlin(t *testing.T) {
"out/soong/.intermediates/default/java/kotlin-annotations/android_common/turbine-combined/kotlin-annotations.jar",
}
kotlinStdlibTurbineJars := []string{
"out/soong/.intermediates/default/java/kotlin-stdlib/android_common/turbine/kotlin-stdlib.jar",
"out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/turbine/kotlin-stdlib-jdk7.jar",
"out/soong/.intermediates/default/java/kotlin-stdlib-jdk8/android_common/turbine/kotlin-stdlib-jdk8.jar",
"out/soong/.intermediates/default/java/kotlin-annotations/android_common/turbine/kotlin-annotations.jar",
}
kotlinStdlibJavacJars := []string{
"out/soong/.intermediates/default/java/kotlin-stdlib/android_common/javac/kotlin-stdlib.jar",
"out/soong/.intermediates/default/java/kotlin-stdlib-jdk7/android_common/javac/kotlin-stdlib-jdk7.jar",
@@ -68,11 +75,21 @@ func TestKotlin(t *testing.T) {
"out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine-combined/core-lambda-stubs.jar",
}
bootclasspathTurbineJars := []string{
"out/soong/.intermediates/default/java/stable.core.platform.api.stubs/android_common/turbine/stable.core.platform.api.stubs.jar",
"out/soong/.intermediates/default/java/core-lambda-stubs/android_common/turbine/core-lambda-stubs.jar",
}
frameworkTurbineCombinedJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.jar",
}
frameworkTurbineJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine/framework.jar",
}
testCases := []struct {
name string
@@ -150,6 +167,69 @@ func TestKotlin(t *testing.T) {
kotlinStdlibTurbineCombinedJars,
),
},
{
name: "transitive classpath",
preparer: PrepareForTestWithTransitiveClasspathEnabled,
fooKotlincInputs: []string{"a.java", "b.kt"},
fooJavacInputs: []string{"a.java"},
fooKotlincClasspath: slices.Concat(
bootclasspathTurbineJars,
frameworkTurbineJars,
[]string{"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar"},
kotlinStdlibTurbineJars,
),
fooJavacClasspath: slices.Concat(
[]string{"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar"},
frameworkTurbineJars,
[]string{"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar"},
kotlinStdlibTurbineJars,
),
fooCombinedInputs: slices.Concat(
[]string{
"out/soong/.intermediates/foo/android_common/kotlin/foo.jar",
"out/soong/.intermediates/foo/android_common/javac/foo.jar",
"out/soong/.intermediates/quz/android_common/kotlin/quz.jar",
},
kotlinStdlibJavacJars,
),
fooHeaderCombinedInputs: slices.Concat(
[]string{
"out/soong/.intermediates/foo/android_common/turbine/foo.jar",
"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar",
"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
},
kotlinStdlibTurbineJars,
),
barKotlincInputs: []string{"b.kt"},
barKotlincClasspath: slices.Concat(
bootclasspathTurbineJars,
frameworkTurbineJars,
[]string{
"out/soong/.intermediates/foo/android_common/turbine/foo.jar",
"out/soong/.intermediates/foo/android_common/kotlin_headers/foo.jar",
"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
},
kotlinStdlibTurbineJars,
[]string{"out/soong/.intermediates/baz/android_common/turbine/baz.jar"},
),
barCombinedInputs: slices.Concat(
[]string{
"out/soong/.intermediates/bar/android_common/kotlin/bar.jar",
"out/soong/.intermediates/baz/android_common/javac/baz.jar",
"out/soong/.intermediates/quz/android_common/kotlin/quz.jar",
},
kotlinStdlibJavacJars,
),
barHeaderCombinedInputs: slices.Concat(
[]string{
"out/soong/.intermediates/bar/android_common/kotlin_headers/bar.jar",
"out/soong/.intermediates/baz/android_common/turbine/baz.jar",
"out/soong/.intermediates/quz/android_common/kotlin_headers/quz.jar",
},
kotlinStdlibTurbineJars,
),
},
}
for _, tt := range testCases {

View File

@@ -907,7 +907,7 @@ func TestJavaSdkLibraryImport(t *testing.T) {
fooModule := result.ModuleForTests("foo"+scope, "android_common")
javac := fooModule.Rule("javac")
sdklibStubsJar := result.ModuleForTests("sdklib.stubs"+scope, "android_common").Rule("combineJar").Output
sdklibStubsJar := result.ModuleForTests("sdklib.stubs"+scope, "android_common").Output("combined/sdklib.stubs" + scope + ".jar").Output
android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String())
}

View File

@@ -391,15 +391,19 @@ func TestClasspath(t *testing.T) {
t.Parallel()
t.Run("basic", func(t *testing.T) {
t.Parallel()
testClasspathTestCases(t, classpathTestcases, false)
testClasspathTestCases(t, classpathTestcases, false, false)
})
t.Run("Always_use_prebuilt_sdks=true", func(t *testing.T) {
testClasspathTestCases(t, classpathTestcases, true)
testClasspathTestCases(t, classpathTestcases, true, false)
})
t.Run("UseTransitiveJarsInClasspath", func(t *testing.T) {
testClasspathTestCases(t, classpathTestcases, false, true)
})
}
func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks bool) {
func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase, alwaysUsePrebuiltSdks, useTransitiveJarsInClasspath bool) {
for _, testcase := range classpathTestcases {
if testcase.forAlwaysUsePrebuiltSdks != nil && *testcase.forAlwaysUsePrebuiltSdks != alwaysUsePrebuiltSdks {
continue
@@ -437,7 +441,14 @@ func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase
convertModulesToPaths := func(cp []string) []string {
ret := make([]string, len(cp))
for i, e := range cp {
ret[i] = defaultModuleToPath(e)
switch {
case e == `""`, strings.HasSuffix(e, ".jar"):
ret[i] = e
case useTransitiveJarsInClasspath:
ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine", e+".jar")
default:
ret[i] = filepath.Join("out", "soong", ".intermediates", defaultJavaDir, e, "android_common", "turbine-combined", e+".jar")
}
}
return ret
}
@@ -531,6 +542,9 @@ func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
})
}
if useTransitiveJarsInClasspath {
preparer = PrepareForTestWithTransitiveClasspathEnabled
}
fixtureFactory := android.GroupFixturePreparers(
prepareForJavaTest,

View File

@@ -127,6 +127,9 @@ type SystemModulesProviderInfo struct {
OutputDir android.Path
OutputDirDeps android.Paths
// depset of header jars for this module and all transitive static dependencies
TransitiveStaticLibsHeaderJars *android.DepSet[android.Path]
}
var SystemModulesProvider = blueprint.NewProvider[*SystemModulesProviderInfo]()
@@ -149,18 +152,23 @@ type SystemModulesProperties struct {
func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var jars android.Paths
var transitiveStaticLibsHeaderJars []*android.DepSet[android.Path]
ctx.VisitDirectDepsWithTag(systemModulesLibsTag, func(module android.Module) {
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
jars = append(jars, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
}
})
system.outputDir, system.outputDeps = TransformJarsToSystemModules(ctx, jars)
android.SetProvider(ctx, SystemModulesProvider, &SystemModulesProviderInfo{
HeaderJars: jars,
OutputDir: system.outputDir,
OutputDirDeps: system.outputDeps,
HeaderJars: jars,
OutputDir: system.outputDir,
OutputDirDeps: system.outputDeps,
TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, nil, transitiveStaticLibsHeaderJars),
})
}

View File

@@ -581,6 +581,7 @@ func gatherRequiredDepsForTest() string {
name: "%[1]s-lib",
sdk_version: "none",
system_modules: "none",
srcs: ["a.java"],
}
`, extra)
}
@@ -780,3 +781,5 @@ func FixtureSetBootImageInstallDirOnDevice(name string, installDir string) andro
config.installDir = installDir
})
}
var PrepareForTestWithTransitiveClasspathEnabled = android.PrepareForTestWithBuildFlag("RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH", "true")