Use transitive header jars in classpaths

Skip combining jars into turbine-combined, combined, and withres jars
and instead collect transitive jars to use in the classpath and to
produce the final dexed jar.

This reduces the size of a `m checkbuild` in git_main by 11%, from
1300 KiB to 1154 KiB.  It may also improve caching and reduce uplink
network bandwidth when building with RBE, as now the classpath inputs
to rules are themselves outputs of previous rules and so already in
the RBE CAS.

The downside is that the classpath inputs to each rule are now much
longer, increasing the Soong ninja file size 11%, from 4.6 GiB to
5.1 GiB.  This could be mitigated in the future by supporting something
like depsets in the generated ninja file to reduce duplication.

Bug: 308016794
Test: TestSimple, TestKotlin, TestClasspath
Flag: build.RELEASE_USE_TRANSITIVE_JARS_IN_CLASSPATH
Change-Id: I2b7b4261375494370da70f98597c8719f1d561cf
This commit is contained in:
Colin Cross
2024-07-26 15:25:46 -07:00
parent fdaa672ad1
commit c9b4f6b502
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") 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 ( var (
mainlineApexContributionBuildFlagsToApexNames = map[string]string{ mainlineApexContributionBuildFlagsToApexNames = map[string]string{
"RELEASE_APEX_CONTRIBUTIONS_ADBD": "com.android.adbd", "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 staticJars android.Paths
var staticHeaderJars android.Paths var staticHeaderJars android.Paths
var staticResourceJars 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) { ctx.VisitDirectDeps(func(module android.Module) {
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
tag := ctx.OtherModuleDependencyTag(module) tag := ctx.OtherModuleDependencyTag(module)
@@ -1305,66 +1309,111 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
staticJars = append(staticJars, dep.ImplementationJars...) staticJars = append(staticJars, dep.ImplementationJars...)
staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...) staticHeaderJars = append(staticHeaderJars, dep.HeaderJars...)
staticResourceJars = append(staticResourceJars, dep.ResourceJars...) 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) addCLCFromDep(ctx, module, a.classLoaderContexts)
addMissingOptionalUsesLibsFromDep(ctx, module, &a.usesLibrary) 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 var implementationJarFile android.Path
if len(staticJars) > 0 { var combineJars android.Paths
combineJars := append(android.Paths{classpathFile}, staticJars...) if ctx.Config().UseTransitiveJarsInClasspath() {
combinedImplementationJar := android.PathForModuleOut(ctx, "combined", jarName).OutputPath combineJars = completeStaticLibsImplementationJars.ToList()
TransformJarsToJar(ctx, combinedImplementationJar, "combine", combineJars, android.OptionalPath{}, false, nil, nil) } else {
implementationJarFile = combinedImplementationJar 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 { } else {
implementationJarFile = classpathFile implementationJarFile = classpathFile
} }
var resourceJarFile android.Path 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) 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) false, nil, nil)
resourceJarFile = combinedJar resourceJarFile = combinedJar
} else if len(staticResourceJars) == 1 { } else if len(resourceJars) == 1 {
resourceJarFile = staticResourceJars[0] resourceJarFile = resourceJars[0]
} }
// merge implementation jar with resources if necessary // merge implementation jar with resources if necessary
implementationAndResourcesJar := implementationJarFile var implementationAndResourcesJars android.Paths
if resourceJarFile != nil { if ctx.Config().UseTransitiveJarsInClasspath() {
jars := android.Paths{resourceJarFile, implementationAndResourcesJar} 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) 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) false, nil, nil)
implementationAndResourcesJar = combinedJar implementationAndResourcesJar = combinedJar
} else {
implementationAndResourcesJar = implementationAndResourcesJars[0]
} }
a.implementationJarFile = implementationJarFile 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 // 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() a.implementationAndResourcesJarFile = implementationAndResourcesJar.WithoutRel()
if len(staticHeaderJars) > 0 { var headerJars android.Paths
combineJars := append(android.Paths{classpathFile}, staticHeaderJars...) 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) 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 a.headerJarFile = headerJarFile
} else { } else {
a.headerJarFile = classpathFile a.headerJarFile = headerJars[0]
} }
ctx.CheckbuildFile(a.headerJarFile) if ctx.Config().UseTransitiveJarsInClasspath() {
ctx.CheckbuildFile(a.implementationJarFile) ctx.CheckbuildFile(classpathFile)
} else {
ctx.CheckbuildFile(a.headerJarFile)
ctx.CheckbuildFile(a.implementationJarFile)
}
android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{ android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(a.headerJarFile), HeaderJars: android.PathsIfNonNil(a.headerJarFile),
ResourceJars: android.PathsIfNonNil(resourceJarFile), LocalHeaderJars: android.PathsIfNonNil(classpathFile),
TransitiveLibsHeaderJarsForR8: a.transitiveLibsHeaderJarsForR8, TransitiveStaticLibsHeaderJars: completeStaticLibsHeaderJars,
TransitiveStaticLibsHeaderJarsForR8: a.transitiveStaticLibsHeaderJarsForR8, TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
ImplementationAndResourcesJars: android.PathsIfNonNil(a.implementationAndResourcesJarFile), TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars,
ImplementationJars: android.PathsIfNonNil(a.implementationJarFile), ResourceJars: android.PathsIfNonNil(resourceJarFile),
StubsLinkType: Implementation, 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 // TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
}) })

View File

@@ -464,15 +464,10 @@ type Module struct {
// inserting into the bootclasspath/classpath of another compile // inserting into the bootclasspath/classpath of another compile
headerJarFile android.Path headerJarFile android.Path
repackagedHeaderJarFile android.Path
// jar file containing implementation classes including static library dependencies but no // jar file containing implementation classes including static library dependencies but no
// resources // resources
implementationJarFile android.Path 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 // args and dependencies to package source files into a srcjar
srcJarArgs []string srcJarArgs []string
srcJarDeps android.Paths srcJarDeps android.Paths
@@ -1256,7 +1251,6 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
// Collect .java and .kt files for AIDEGen // Collect .java and .kt files for AIDEGen
j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...) j.expandIDEInfoCompiledSrcs = append(j.expandIDEInfoCompiledSrcs, uniqueSrcFiles.Strings()...)
var kotlinJars android.Paths
var kotlinHeaderJars android.Paths var kotlinHeaderJars android.Paths
// Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before // Prepend extraClasspathJars to classpath so that the resource processor R.jar comes before
@@ -1266,6 +1260,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
j.aconfigCacheFiles = append(deps.aconfigProtoFiles, j.properties.Aconfig_Cache_files...) 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 compiling headers then compile them and skip the rest
if proptools.Bool(j.properties.Headers_only) { if proptools.Bool(j.properties.Headers_only) {
if srcFiles.HasExt(".kt") { if srcFiles.HasExt(".kt") {
@@ -1275,20 +1271,41 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ctx.ModuleErrorf("headers_only is enabled but Turbine is disabled.") 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) extraCombinedJars)
combinedHeaderJarFile = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine") combinedHeaderJarFile, jarjared := j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine")
combinedHeaderJarFile = j.repackageFlagsIfNecessary(ctx, combinedHeaderJarFile, jarName, "repackage-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() { if ctx.Failed() {
return return
} }
j.headerJarFile = combinedHeaderJarFile 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{ android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile), HeaderJars: android.PathsIfNonNil(j.headerJarFile),
LocalHeaderJars: localHeaderJars,
TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8, TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8, TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
AidlIncludeDirs: j.exportAidlIncludeDirs, AidlIncludeDirs: j.exportAidlIncludeDirs,
@@ -1347,7 +1364,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar") kaptResJar := android.PathForModuleOut(ctx, "kapt", "kapt-res.jar")
kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags) kotlinKapt(ctx, kaptSrcJar, kaptResJar, uniqueSrcFiles, kotlinCommonSrcFiles, srcJars, flags)
srcJars = append(srcJars, kaptSrcJar) srcJars = append(srcJars, kaptSrcJar)
kotlinJars = append(kotlinJars, kaptResJar) localImplementationJars = append(localImplementationJars, kaptResJar)
// Disable annotation processing in javac, it's already been handled by kapt // Disable annotation processing in javac, it's already been handled by kapt
flags.processorPath = nil flags.processorPath = nil
flags.processors = nil flags.processors = nil
@@ -1360,21 +1377,24 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
return return
} }
kotlinJarPath := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc") kotlinJarPath, _ := j.repackageFlagsIfNecessary(ctx, kotlinJar, jarName, "kotlinc")
// Make javac rule depend on the kotlinc rule // Make javac rule depend on the kotlinc rule
flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...) flags.classpath = append(classpath{kotlinHeaderJar}, flags.classpath...)
kotlinJars = append(kotlinJars, kotlinJarPath) localImplementationJars = append(localImplementationJars, kotlinJarPath)
kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar) kotlinHeaderJars = append(kotlinHeaderJars, kotlinHeaderJar)
} }
jars := slices.Clone(kotlinJars)
j.compiledSrcJars = srcJars j.compiledSrcJars = srcJars
transitiveStaticLibsHeaderJars := deps.transitiveStaticLibsHeaderJars
enableSharding := false 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 ctx.Device() && !ctx.Config().IsEnvFalse("TURBINE_ENABLED") && !disableTurbine {
if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 { if j.properties.Javac_shard_size != nil && *(j.properties.Javac_shard_size) > 0 {
enableSharding = true enableSharding = true
@@ -1387,11 +1407,26 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
extraJars := slices.Clone(kotlinHeaderJars) extraJars := slices.Clone(kotlinHeaderJars)
extraJars = append(extraJars, extraCombinedJars...) extraJars = append(extraJars, extraCombinedJars...)
var combinedHeaderJarFile android.Path var combinedHeaderJarFile android.Path
headerJarFileWithoutDepsOrJarjar, combinedHeaderJarFile = localHeaderJars, combinedHeaderJarFile = j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars)
j.compileJavaHeader(ctx, uniqueJavaFiles, srcJars, deps, flags, jarName, extraJars) shardingHeaderJars = localHeaderJars
j.headerJarFile = j.jarjarIfNecessary(ctx, combinedHeaderJarFile, jarName, "turbine") var jarjared bool
j.repackagedHeaderJarFile = j.repackageFlagsIfNecessary(ctx, j.headerJarFile, jarName, "turbine") 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 { if len(uniqueJavaFiles) > 0 || len(srcJars) > 0 {
hasErrorproneableFiles := false hasErrorproneableFiles := false
@@ -1426,8 +1461,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
} }
if enableSharding { if enableSharding {
if headerJarFileWithoutDepsOrJarjar != nil { if len(shardingHeaderJars) > 0 {
flags.classpath = append(classpath{headerJarFileWithoutDepsOrJarjar}, flags.classpath...) flags.classpath = append(classpath(slices.Clone(shardingHeaderJars)), flags.classpath...)
} }
shardSize := int(*(j.properties.Javac_shard_size)) shardSize := int(*(j.properties.Javac_shard_size))
var shardSrcs []android.Paths var shardSrcs []android.Paths
@@ -1436,8 +1471,8 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
for idx, shardSrc := range shardSrcs { for idx, shardSrc := range shardSrcs {
classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc, classes := j.compileJavaClasses(ctx, jarName, idx, shardSrc,
nil, flags, extraJarDeps) nil, flags, extraJarDeps)
classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx)) classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(idx))
jars = append(jars, classes) localImplementationJars = append(localImplementationJars, classes)
} }
} }
// Assume approximately 5 sources per srcjar. // Assume approximately 5 sources per srcjar.
@@ -1449,21 +1484,21 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
for idx, shardSrcJars := range shardSrcJarsList { for idx, shardSrcJars := range shardSrcJarsList {
classes := j.compileJavaClasses(ctx, jarName, startIdx+idx, classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
nil, shardSrcJars, flags, extraJarDeps) nil, shardSrcJars, flags, extraJarDeps)
classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx)) classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac-"+strconv.Itoa(startIdx+idx))
jars = append(jars, classes) localImplementationJars = append(localImplementationJars, classes)
} }
} }
} else { } else {
classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps) classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
classes = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac") classes, _ = j.repackageFlagsIfNecessary(ctx, classes, jarName, "javac")
jars = append(jars, classes) localImplementationJars = append(localImplementationJars, classes)
} }
if ctx.Failed() { if ctx.Failed() {
return return
} }
} }
jars = append(jars, extraCombinedJars...) localImplementationJars = append(localImplementationJars, extraCombinedJars...)
j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles j.srcJarArgs, j.srcJarDeps = resourcePathsToJarArgs(srcFiles), srcFiles
@@ -1490,42 +1525,18 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
resArgs = append(resArgs, extraArgs...) resArgs = append(resArgs, extraArgs...)
resDeps = append(resDeps, extraDeps...) resDeps = append(resDeps, extraDeps...)
var localResourceJars android.Paths
if len(resArgs) > 0 { if len(resArgs) > 0 {
resourceJar := android.PathForModuleOut(ctx, "res", jarName) resourceJar := android.PathForModuleOut(ctx, "res", jarName)
TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps) TransformResourcesToJar(ctx, resourceJar, resArgs, resDeps)
j.resourceJar = resourceJar
if ctx.Failed() { if ctx.Failed() {
return return
} }
localResourceJars = append(localResourceJars, resourceJar)
} }
var resourceJars android.Paths
if j.resourceJar != nil {
resourceJars = append(resourceJars, j.resourceJar)
}
if Bool(j.properties.Include_srcs) { if Bool(j.properties.Include_srcs) {
resourceJars = append(resourceJars, includeSrcJar) localResourceJars = append(localResourceJars, 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))
} }
services := android.PathsForModuleSrc(ctx, j.properties.Services) services := android.PathsForModuleSrc(ctx, j.properties.Services)
@@ -1550,35 +1561,68 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
Implicits: services, Implicits: services,
Args: args, 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 // 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. // classes.jar. If there is only one input jar this step will be skipped.
var outputFile android.Path 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() { if len(jars) == 1 && !manifest.Valid() {
// Optimization: skip the combine step as there is nothing to do // 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 // 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 // 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 // moduleStubLinkType determines if the module is the TopLevelStubLibrary generated
// from sdk_library. The TopLevelStubLibrary contains only one static lib, // from sdk_library. The TopLevelStubLibrary contains only one static lib,
// either with .from-source or .from-text suffix. // either with .from-source or .from-text suffix.
// outputFile should be agnostic to the build configuration, // 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. // to the copy rules.
stub, _ := moduleStubLinkType(j) if stub, _ := moduleStubLinkType(j); stub {
copiedJar := android.PathForModuleOut(ctx, "combined", jarName)
if stub {
combinedJar := android.PathForModuleOut(ctx, "combined", jarName)
ctx.Build(pctx, android.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: android.Cp, Rule: android.Cp,
Input: jars[0], Input: jars[0],
Output: combinedJar, Output: copiedJar,
}) })
outputFile = combinedJar completeStaticLibsImplementationJars = android.NewDepSet(android.PREORDER, android.Paths{copiedJar}, nil)
outputFile = copiedJar
} else { } else {
outputFile = jars[0] outputFile = jars[0]
} }
@@ -1590,13 +1634,21 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
} }
// jarjar implementation jar if necessary // 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 outputFile = jarjarFile
// jarjar resource jar if necessary // jarjar resource jar if necessary
if j.resourceJar != nil { if combinedResourceJar != nil {
resourceJarJarFile := j.jarjarIfNecessary(ctx, j.resourceJar, jarName, "resource") resourceJarJarFile, jarjarred := j.jarjarIfNecessary(ctx, combinedResourceJar, jarName, "resource")
j.resourceJar = resourceJarJarFile combinedResourceJar = resourceJarJarFile
if jarjarred {
localResourceJars = android.Paths{resourceJarJarFile}
completeStaticLibsResourceJars = android.NewDepSet(android.PREORDER, localResourceJars, nil)
}
} }
if ctx.Failed() { if ctx.Failed() {
@@ -1664,6 +1716,13 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName) headerJarFile := android.PathForModuleOut(ctx, "javac-header", jarName)
convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile) convertImplementationJarToHeaderJar(ctx, j.implementationJarFile, headerJarFile)
j.headerJarFile = 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) // enforce syntax check to jacoco filters for any build (http://b/183622051)
@@ -1677,16 +1736,27 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
} }
// merge implementation jar with resources if necessary // merge implementation jar with resources if necessary
implementationAndResourcesJar := outputFile var implementationAndResourcesJarsToCombine android.Paths
if j.resourceJar != nil { if ctx.Config().UseTransitiveJarsInClasspath() {
jars := android.Paths{j.resourceJar, implementationAndResourcesJar} resourceJars := completeStaticLibsResourceJars.ToList()
combinedJar := android.PathForModuleOut(ctx, "withres", jarName) if len(resourceJars) > 0 {
TransformJarsToJar(ctx, combinedJar, "for resources", jars, manifest, implementationAndResourcesJarsToCombine = append(resourceJars, completeStaticLibsImplementationJars.ToList()...)
false, nil, nil) implementationAndResourcesJarsToCombine = append(implementationAndResourcesJarsToCombine, extraDepCombinedJars...)
implementationAndResourcesJar = combinedJar }
} 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 // Enable dex compilation for the APEX variants, unless it is disabled explicitly
compileDex := j.dexProperties.Compile_dex compileDex := j.dexProperties.Compile_dex
@@ -1712,7 +1782,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
flags: flags, flags: flags,
sdkVersion: j.SdkVersion(ctx), sdkVersion: j.SdkVersion(ctx),
minSdkVersion: j.MinSdkVersion(ctx), minSdkVersion: j.MinSdkVersion(ctx),
classesJar: implementationAndResourcesJar, classesJar: outputFile,
jarName: jarName, jarName: jarName,
} }
if j.GetProfileGuided() && j.optimizeOrObfuscateEnabled() && !j.EnableProfileRewriting() { if j.GetProfileGuided() && j.optimizeOrObfuscateEnabled() && !j.EnableProfileRewriting() {
@@ -1738,10 +1808,20 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
} }
// merge dex jar with resources if necessary // merge dex jar with resources if necessary
if j.resourceJar != nil { var dexAndResourceJarsToCombine android.Paths
jars := android.Paths{dexOutputFile, j.resourceJar} 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) 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) false, nil, nil)
if *j.dexProperties.Uncompress_dex { if *j.dexProperties.Uncompress_dex {
combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName) combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
@@ -1774,15 +1854,12 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
} else { } else {
// There is no code to compile into a dex jar, make sure the resources are propagated // There is no code to compile into a dex jar, make sure the resources are propagated
// to the APK if this is an app. // to the APK if this is an app.
outputFile = implementationAndResourcesJar j.dexJarFile = makeDexJarPathFromPath(combinedResourceJar)
j.dexJarFile = makeDexJarPathFromPath(j.resourceJar)
} }
if ctx.Failed() { if ctx.Failed() {
return return
} }
} else {
outputFile = implementationAndResourcesJar
} }
if ctx.Device() { if ctx.Device() {
@@ -1814,17 +1891,34 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
j.collectTransitiveSrcFiles(ctx, srcFiles) j.collectTransitiveSrcFiles(ctx, srcFiles)
ctx.CheckbuildFile(j.implementationJarFile) if ctx.Config().UseTransitiveJarsInClasspath() {
ctx.CheckbuildFile(j.headerJarFile) 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{ android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: android.PathsIfNonNil(j.headerJarFile), HeaderJars: android.PathsIfNonNil(j.headerJarFile),
RepackagedHeaderJars: android.PathsIfNonNil(j.repackagedHeaderJarFile), RepackagedHeaderJars: android.PathsIfNonNil(repackagedHeaderJarFile),
LocalHeaderJars: localHeaderJars,
TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, localHeaderJars, transitiveStaticLibsHeaderJars),
TransitiveStaticLibsImplementationJars: completeStaticLibsImplementationJars,
TransitiveStaticLibsResourceJars: completeStaticLibsResourceJars,
TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8, TransitiveLibsHeaderJarsForR8: j.transitiveLibsHeaderJarsForR8,
TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8, TransitiveStaticLibsHeaderJarsForR8: j.transitiveStaticLibsHeaderJarsForR8,
ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar), ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar),
ImplementationJars: android.PathsIfNonNil(j.implementationJarFile), ImplementationJars: android.PathsIfNonNil(j.implementationJarFile),
ResourceJars: android.PathsIfNonNil(j.resourceJar), ResourceJars: android.PathsIfNonNil(combinedResourceJar),
AidlIncludeDirs: j.exportAidlIncludeDirs, AidlIncludeDirs: j.exportAidlIncludeDirs,
SrcJarArgs: j.srcJarArgs, SrcJarArgs: j.srcJarArgs,
SrcJarDeps: j.srcJarDeps, SrcJarDeps: j.srcJarDeps,
@@ -1960,22 +2054,26 @@ func CheckKotlincFlags(ctx android.ModuleContext, flags []string) {
func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths, func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars android.Paths,
deps deps, flags javaBuilderFlags, jarName string, 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 { if len(srcFiles) > 0 || len(srcJars) > 0 {
// Compile java sources into turbine.jar. // Compile java sources into turbine.jar.
turbineJar := android.PathForModuleOut(ctx, "turbine", jarName) turbineJar := android.PathForModuleOut(ctx, "turbine", jarName)
TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags) TransformJavaToHeaderClasses(ctx, turbineJar, srcFiles, srcJars, flags)
jars = append(jars, turbineJar) localHeaderJars = append(localHeaderJars, turbineJar)
headerJar = turbineJar
} }
jars = append(jars, extraJars...) localHeaderJars = append(localHeaderJars, extraJars...)
// Combine any static header libraries into classes-header.jar. If there is only // Combine any static header libraries into classes-header.jar. If there is only
// one input jar this step will be skipped. // 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 // 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 // since we have to strip META-INF/TRANSITIVE dir from turbine.jar
@@ -1983,9 +2081,7 @@ func (j *Module) compileJavaHeader(ctx android.ModuleContext, srcFiles, srcJars
TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{}, TransformJarsToJar(ctx, combinedHeaderJarOutputPath, "for turbine", jars, android.OptionalPath{},
false, nil, []string{"META-INF/TRANSITIVE"}) false, nil, []string{"META-INF/TRANSITIVE"})
ctx.CheckbuildFile(combinedHeaderJarOutputPath) return localHeaderJars, combinedHeaderJarOutputPath
return headerJar, combinedHeaderJarOutputPath
} }
func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags, func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags,
@@ -2041,6 +2137,7 @@ func (j *providesTransitiveHeaderJarsForR8) collectTransitiveHeaderJarsForR8(ctx
if dep.TransitiveStaticLibsHeaderJarsForR8 != nil { if dep.TransitiveStaticLibsHeaderJarsForR8 != nil {
transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJarsForR8) transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJarsForR8)
} }
} }
}) })
j.transitiveLibsHeaderJarsForR8 = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs) j.transitiveLibsHeaderJarsForR8 = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs)
@@ -2288,29 +2385,17 @@ func (j *Module) checkSdkLinkType(
func (j *Module) collectDeps(ctx android.ModuleContext) deps { func (j *Module) collectDeps(ctx android.ModuleContext) deps {
var deps 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()) sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName())
j.collectTransitiveHeaderJarsForR8(ctx) 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) { ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module) otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module) tag := ctx.OtherModuleDependencyTag(module)
@@ -2330,6 +2415,10 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx)) depHeaderJars := dep.SdkHeaderJars(ctx, j.SdkVersion(ctx))
deps.classpath = append(deps.classpath, depHeaderJars...) deps.classpath = append(deps.classpath, depHeaderJars...)
deps.dexClasspath = append(deps.dexClasspath, 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: case staticLibTag:
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName) ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
} }
@@ -2345,6 +2434,9 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
switch tag { switch tag {
case bootClasspathTag: case bootClasspathTag:
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...) deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
case sdkLibTag, libTag, instrumentationForTag: case sdkLibTag, libTag, instrumentationForTag:
if _, ok := module.(*Plugin); ok { if _, ok := module.(*Plugin); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName) ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a libs dependency", otherName)
@@ -2358,8 +2450,15 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...) deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs...)
addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...) addPlugins(&deps, dep.ExportedPlugins, dep.ExportedPluginClasses...)
deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
case java9LibTag: case java9LibTag:
deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...) deps.java9Classpath = append(deps.java9Classpath, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveJava9ClasspathHeaderJars = append(transitiveJava9ClasspathHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
case staticLibTag: case staticLibTag:
if _, ok := module.(*Plugin); ok { if _, ok := module.(*Plugin); ok {
ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName) ctx.ModuleErrorf("a java_plugin (%s) cannot be used as a static_libs dependency", otherName)
@@ -2375,6 +2474,17 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// optimization. // optimization.
deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine deps.disableTurbine = deps.disableTurbine || dep.ExportedPluginDisableTurbine
deps.aconfigProtoFiles = append(deps.aconfigProtoFiles, dep.AconfigIntermediateCacheOutputPaths...) 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: case pluginTag:
if plugin, ok := module.(*Plugin); ok { if plugin, ok := module.(*Plugin); ok {
if plugin.pluginProperties.Processor_class != nil { if plugin.pluginProperties.Processor_class != nil {
@@ -2423,11 +2533,18 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
checkProducesJars(ctx, dep) checkProducesJars(ctx, dep)
deps.classpath = append(deps.classpath, dep.Srcs()...) deps.classpath = append(deps.classpath, dep.Srcs()...)
deps.dexClasspath = append(deps.classpath, dep.Srcs()...) deps.dexClasspath = append(deps.classpath, dep.Srcs()...)
transitiveClasspathHeaderJars = append(transitiveClasspathHeaderJars,
android.NewDepSet(android.PREORDER, dep.Srcs(), nil))
case staticLibTag: case staticLibTag:
checkProducesJars(ctx, dep) checkProducesJars(ctx, dep)
deps.classpath = append(deps.classpath, dep.Srcs()...) deps.classpath = append(deps.classpath, dep.Srcs()...)
deps.staticJars = append(deps.staticJars, dep.Srcs()...) deps.staticJars = append(deps.staticJars, dep.Srcs()...)
deps.staticHeaderJars = append(deps.staticHeaderJars, 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 { } else if dep, ok := android.OtherModuleProvider(ctx, module, android.CodegenInfoProvider); ok {
switch tag { switch tag {
@@ -2440,8 +2557,11 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// If a system modules dependency has been added to the bootclasspath // If a system modules dependency has been added to the bootclasspath
// then add its libs to the bootclasspath. // then add its libs to the bootclasspath.
if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok { if sm, ok := android.OtherModuleProvider(ctx, module, SystemModulesProvider); ok {
depHeaderJars := sm.HeaderJars deps.bootClasspath = append(deps.bootClasspath, sm.HeaderJars...)
deps.bootClasspath = append(deps.bootClasspath, depHeaderJars...) if sm.TransitiveStaticLibsHeaderJars != nil {
transitiveBootClasspathHeaderJars = append(transitiveBootClasspathHeaderJars,
sm.TransitiveStaticLibsHeaderJars)
}
} else { } else {
ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider", ctx.PropertyErrorf("boot classpath dependency %q does not provide SystemModulesProvider",
ctx.OtherModuleName(module)) ctx.OtherModuleName(module))
@@ -2472,6 +2592,39 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
addMissingOptionalUsesLibsFromDep(ctx, module, &j.usesLibrary) 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 return deps
} }
@@ -2783,22 +2936,22 @@ func getJarJarRuleText(provider *JarJarProviderData) string {
} }
// Repackage the flags if the jarjar rule txt for the flags is generated // 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 { if j.repackageJarjarRules == nil {
return infile return infile, false
} }
repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info, jarName) repackagedJarjarFile := android.PathForModuleOut(ctx, "repackaged-jarjar", info, jarName)
TransformJarJar(ctx, repackagedJarjarFile, infile, j.repackageJarjarRules) 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 { if j.expandJarjarRules == nil {
return infile return infile, false
} }
jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName) jarjarFile := android.PathForModuleOut(ctx, "jarjar", info, jarName)
TransformJarJar(ctx, jarjarFile, infile, j.expandJarjarRules) 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") 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) { ctx.VisitDirectDepsWithTag(deviceHostConverterDepTag, func(m android.Module) {
if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok { if dep, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
d.headerJars = append(d.headerJars, dep.HeaderJars...) 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.srcJarArgs = append(d.srcJarArgs, dep.SrcJarArgs...)
d.srcJarDeps = append(d.srcJarDeps, dep.SrcJarDeps...) 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 { } else {
ctx.PropertyErrorf("libs", "module %q cannot be used as a dependency", ctx.OtherModuleName(m)) 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{ android.SetProvider(ctx, JavaInfoProvider, &JavaInfo{
HeaderJars: d.headerJars, HeaderJars: d.headerJars,
ImplementationAndResourcesJars: d.implementationAndResourceJars, LocalHeaderJars: d.headerJars,
ImplementationJars: d.implementationJars, TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, nil, transitiveHeaderJars),
ResourceJars: d.resourceJars, TransitiveStaticLibsImplementationJars: android.NewDepSet(android.PREORDER, nil, transitiveImplementationJars),
SrcJarArgs: d.srcJarArgs, TransitiveStaticLibsResourceJars: android.NewDepSet(android.PREORDER, nil, transitiveResourceJars),
SrcJarDeps: d.srcJarDeps, ImplementationAndResourcesJars: d.implementationAndResourceJars,
StubsLinkType: Implementation, 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 // TODO: Not sure if aconfig flags that have been moved between device and host variants
// make sense. // make sense.
}) })

View File

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

View File

@@ -20,6 +20,7 @@ import (
"path/filepath" "path/filepath"
"reflect" "reflect"
"runtime" "runtime"
"slices"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@@ -211,7 +212,7 @@ func TestJavaLinkType(t *testing.T) {
} }
func TestSimple(t *testing.T) { func TestSimple(t *testing.T) {
ctx, _ := testJava(t, ` bp := `
java_library { java_library {
name: "foo", name: "foo",
srcs: ["a.java"], srcs: ["a.java"],
@@ -222,31 +223,157 @@ func TestSimple(t *testing.T) {
java_library { java_library {
name: "bar", name: "bar",
srcs: ["b.java"], srcs: ["b.java"],
static_libs: ["quz"],
} }
java_library { java_library {
name: "baz", name: "baz",
srcs: ["c.java"], srcs: ["c.java"],
static_libs: ["quz"],
} }
`)
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac") java_library {
combineJar := ctx.ModuleForTests("foo", "android_common").Description("for javac") name: "quz",
srcs: ["d.java"],
}`
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" { frameworkTurbineCombinedJars := []string{
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs) "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() frameworkTurbineJars := []string{
barTurbine := filepath.Join("out", "soong", ".intermediates", "bar", "android_common", "turbine-combined", "bar.jar") "out/soong/.intermediates/default/java/ext/android_common/turbine/ext.jar",
bazTurbine := filepath.Join("out", "soong", ".intermediates", "baz", "android_common", "turbine-combined", "baz.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 { fooJavacInputs []string
t.Errorf("foo combineJar inputs %v does not contain %q", combineJar.Inputs, baz) 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") barModule := ctx.ModuleForTests("bar", "android_common")
barJar := barModule.Output("combined/bar.jar").Output barJar := barModule.Output("combined/bar.jar").Output
bazModule := ctx.ModuleForTests("baz", "android_common") 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"). sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").
Output("combined/sdklib.stubs.jar").Output 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", "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{ kotlinStdlibJavacJars := []string{
"out/soong/.intermediates/default/java/kotlin-stdlib/android_common/javac/kotlin-stdlib.jar", "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", "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", "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{ frameworkTurbineCombinedJars := []string{
"out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar", "out/soong/.intermediates/default/java/ext/android_common/turbine-combined/ext.jar",
"out/soong/.intermediates/default/java/framework/android_common/turbine-combined/framework.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 { testCases := []struct {
name string name string
@@ -150,6 +167,69 @@ func TestKotlin(t *testing.T) {
kotlinStdlibTurbineCombinedJars, 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 { for _, tt := range testCases {

View File

@@ -907,7 +907,7 @@ func TestJavaSdkLibraryImport(t *testing.T) {
fooModule := result.ModuleForTests("foo"+scope, "android_common") fooModule := result.ModuleForTests("foo"+scope, "android_common")
javac := fooModule.Rule("javac") 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()) android.AssertStringDoesContain(t, "foo classpath", javac.Args["classpath"], sdklibStubsJar.String())
} }

View File

@@ -391,15 +391,19 @@ func TestClasspath(t *testing.T) {
t.Parallel() t.Parallel()
t.Run("basic", func(t *testing.T) { t.Run("basic", func(t *testing.T) {
t.Parallel() t.Parallel()
testClasspathTestCases(t, classpathTestcases, false) testClasspathTestCases(t, classpathTestcases, false, false)
}) })
t.Run("Always_use_prebuilt_sdks=true", func(t *testing.T) { 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 { for _, testcase := range classpathTestcases {
if testcase.forAlwaysUsePrebuiltSdks != nil && *testcase.forAlwaysUsePrebuiltSdks != alwaysUsePrebuiltSdks { if testcase.forAlwaysUsePrebuiltSdks != nil && *testcase.forAlwaysUsePrebuiltSdks != alwaysUsePrebuiltSdks {
continue continue
@@ -437,7 +441,14 @@ func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase
convertModulesToPaths := func(cp []string) []string { convertModulesToPaths := func(cp []string) []string {
ret := make([]string, len(cp)) ret := make([]string, len(cp))
for i, e := range 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 return ret
} }
@@ -531,6 +542,9 @@ func testClasspathTestCases(t *testing.T, classpathTestcases []classpathTestCase
variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true) variables.Always_use_prebuilt_sdks = proptools.BoolPtr(true)
}) })
} }
if useTransitiveJarsInClasspath {
preparer = PrepareForTestWithTransitiveClasspathEnabled
}
fixtureFactory := android.GroupFixturePreparers( fixtureFactory := android.GroupFixturePreparers(
prepareForJavaTest, prepareForJavaTest,

View File

@@ -127,6 +127,9 @@ type SystemModulesProviderInfo struct {
OutputDir android.Path OutputDir android.Path
OutputDirDeps android.Paths 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]() var SystemModulesProvider = blueprint.NewProvider[*SystemModulesProviderInfo]()
@@ -149,18 +152,23 @@ type SystemModulesProperties struct {
func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (system *SystemModules) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var jars android.Paths var jars android.Paths
var transitiveStaticLibsHeaderJars []*android.DepSet[android.Path]
ctx.VisitDirectDepsWithTag(systemModulesLibsTag, func(module android.Module) { ctx.VisitDirectDepsWithTag(systemModulesLibsTag, func(module android.Module) {
if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok { if dep, ok := android.OtherModuleProvider(ctx, module, JavaInfoProvider); ok {
jars = append(jars, dep.HeaderJars...) jars = append(jars, dep.HeaderJars...)
if dep.TransitiveStaticLibsHeaderJars != nil {
transitiveStaticLibsHeaderJars = append(transitiveStaticLibsHeaderJars, dep.TransitiveStaticLibsHeaderJars)
}
} }
}) })
system.outputDir, system.outputDeps = TransformJarsToSystemModules(ctx, jars) system.outputDir, system.outputDeps = TransformJarsToSystemModules(ctx, jars)
android.SetProvider(ctx, SystemModulesProvider, &SystemModulesProviderInfo{ android.SetProvider(ctx, SystemModulesProvider, &SystemModulesProviderInfo{
HeaderJars: jars, HeaderJars: jars,
OutputDir: system.outputDir, OutputDir: system.outputDir,
OutputDirDeps: system.outputDeps, OutputDirDeps: system.outputDeps,
TransitiveStaticLibsHeaderJars: android.NewDepSet(android.PREORDER, nil, transitiveStaticLibsHeaderJars),
}) })
} }

View File

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