Do not propagate <uses-library> deps through static SDK component libs.

If some Java library/app depends on an SDK component library (e.g. stubs
library), then it transitively depends on the SDK library itself
(because the component library has a dependency on its SDK library).

Previously having this transitive dependency resulted in adding the SDK
library to the <uses-library> dependencies of the library/app. However,
this doesn't make sense if the app has a *static* dependency on the
component library. This patch stops adding <uses-library> dependency in
that case.

Bug: 132357300
Test: m nothing
Test: added new Soong test that would previously fail with an error:
   invalid build path for <uses-library> "fred"
Change-Id: I697a65e461037c95ec56b6c321afa4ec52ccbbec
This commit is contained in:
Ulya Trafimovich
2020-12-03 16:50:22 +00:00
parent 78210f6c9b
commit 65b031910b
3 changed files with 51 additions and 15 deletions

View File

@@ -407,6 +407,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte
ctx.VisitDirectDeps(func(module android.Module) {
depName := ctx.OtherModuleName(module)
depTag := ctx.OtherModuleDependencyTag(module)
var exportPackage android.Path
aarDep, _ := module.(AndroidLibraryDependency)
@@ -414,7 +415,7 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte
exportPackage = aarDep.ExportPackage()
}
switch ctx.OtherModuleDependencyTag(module) {
switch depTag {
case instrumentationForTag:
// Nothing, instrumentationForTag is treated as libTag for javac but not for aapt2.
case libTag:
@@ -439,7 +440,6 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte
transitiveStaticLibs = append(transitiveStaticLibs, aarDep.ExportedStaticPackages()...)
transitiveStaticLibs = append(transitiveStaticLibs, exportPackage)
transitiveStaticLibManifests = append(transitiveStaticLibManifests, aarDep.ExportedManifests()...)
classLoaderContexts.AddContextMap(aarDep.ClassLoaderContexts(), depName)
if aarDep.ExportedAssets().Valid() {
assets = append(assets, aarDep.ExportedAssets().Path())
}
@@ -458,11 +458,8 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext, classLoaderConte
}
}
// Add nested dependencies after processing the direct dependency: if it is a <uses-library>,
// nested context is added as its subcontext, and should not be re-added at the top-level.
if dep, ok := module.(Dependency); ok {
classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), depName)
}
// Merge dep's CLC after processing the dep itself (which may add its own <uses-library>).
maybeAddCLCFromDep(module, depTag, depName, classLoaderContexts)
})
deps = append(deps, sharedLibs...)

View File

@@ -2729,6 +2729,13 @@ func TestUsesLibraries(t *testing.T) {
sdk_version: "current",
}
java_sdk_library {
name: "fred",
srcs: ["a.java"],
api_packages: ["fred"],
sdk_version: "current",
}
java_sdk_library {
name: "bar",
srcs: ["a.java"],
@@ -2753,7 +2760,12 @@ func TestUsesLibraries(t *testing.T) {
name: "app",
srcs: ["a.java"],
libs: ["qux", "quuz.stubs"],
static_libs: ["static-runtime-helper"],
static_libs: [
"static-runtime-helper",
// statically linked component libraries should not pull their SDK libraries,
// so "fred" should not be added to class loader context
"fred.stubs",
],
uses_libs: ["foo"],
sdk_version: "current",
optional_uses_libs: [

View File

@@ -1050,7 +1050,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
switch tag {
case libTag:
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
// names of sdk libs that are directly depended are exported
j.classLoaderContexts.MaybeAddContext(ctx, dep.OptionalImplicitSdkLibrary(),
dep.DexJarBuildPath(), dep.DexJarInstallPath())
case staticLibTag:
@@ -1062,7 +1061,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.bootClasspath = append(deps.bootClasspath, dep.HeaderJars()...)
case libTag, instrumentationForTag:
deps.classpath = append(deps.classpath, dep.HeaderJars()...)
// sdk lib names from dependencies are re-exported
j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins()
@@ -1075,8 +1073,6 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.staticJars = append(deps.staticJars, dep.ImplementationJars()...)
deps.staticHeaderJars = append(deps.staticHeaderJars, dep.HeaderJars()...)
deps.staticResourceJars = append(deps.staticResourceJars, dep.ResourceJars()...)
// sdk lib names from dependencies are re-exported
j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName)
deps.aidlIncludeDirs = append(deps.aidlIncludeDirs, dep.AidlIncludeDirs()...)
pluginJars, pluginClasses, disableTurbine := dep.ExportedPlugins()
addPlugins(&deps, pluginJars, pluginClasses...)
@@ -1151,6 +1147,9 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
deps.systemModules = &systemModules{outputDir, outputDeps}
}
}
// Merge dep's CLC after processing the dep itself (which may add its own <uses-library>).
maybeAddCLCFromDep(module, tag, otherName, j.classLoaderContexts)
})
return deps
@@ -2781,8 +2780,6 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
switch tag {
case libTag, staticLibTag:
flags.classpath = append(flags.classpath, dep.HeaderJars()...)
// sdk lib names from dependencies are re-exported
j.classLoaderContexts.AddContextMap(dep.ClassLoaderContexts(), otherName)
case bootClasspathTag:
flags.bootClasspath = append(flags.bootClasspath, dep.HeaderJars()...)
}
@@ -2790,10 +2787,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
switch tag {
case libTag:
flags.classpath = append(flags.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
// names of sdk libs that are directly depended are exported
j.classLoaderContexts.AddContext(ctx, otherName, dep.DexJarBuildPath(), dep.DexJarInstallPath())
}
}
// Merge dep's CLC after processing the dep itself (which may add its own <uses-library>).
maybeAddCLCFromDep(module, tag, otherName, j.classLoaderContexts)
})
var installFile android.Path
@@ -3214,3 +3213,31 @@ var Bool = proptools.Bool
var BoolDefault = proptools.BoolDefault
var String = proptools.String
var inList = android.InList
// Add class loader context of a given dependency to the given class loader context, provided that
// all the necessary conditions are met.
func maybeAddCLCFromDep(depModule android.Module, depTag blueprint.DependencyTag,
depName string, clcMap dexpreopt.ClassLoaderContextMap) {
if dep, ok := depModule.(Dependency); ok {
if depTag == libTag {
// Ok, propagate <uses-library> through non-static library dependencies.
} else if depTag == staticLibTag {
// Propagate <uses-library> through static library dependencies, unless it is a
// component library (such as stubs). Component libraries have a dependency on their
// SDK library, which should not be pulled just because of a static component library.
if comp, isComp := depModule.(SdkLibraryComponentDependency); isComp {
if compName := comp.OptionalImplicitSdkLibrary(); compName != nil {
dep = nil
}
}
} else {
// Don't propagate <uses-library> for other dependency tags.
dep = nil
}
if dep != nil {
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
}
}
}