Retry: "Improve tracking of exported sdk libraries" am: 64e6199756

Change-Id: I1ce69a094492316ba50da15e44968490f15a8bd8
This commit is contained in:
Paul Duffin 2020-05-26 09:21:47 +00:00 committed by Automerger Merge Worker
commit 007f650bbb
5 changed files with 166 additions and 14 deletions

View File

@ -379,8 +379,11 @@ func aaptLibs(ctx android.ModuleContext, sdkContext sdkContext) (transitiveStati
sharedLibs = append(sharedLibs, exportPackage)
}
if _, ok := module.(SdkLibraryDependency); ok {
sdkLibraries = append(sdkLibraries, ctx.OtherModuleName(module))
// If the module is (or possibly could be) a component of a java_sdk_library
// (including the java_sdk_library) itself then append any implicit sdk library
// names to the list of sdk libraries to be added to the manifest.
if component, ok := module.(SdkLibraryComponentDependency); ok {
sdkLibraries = append(sdkLibraries, component.OptionalImplicitSdkLibrary()...)
}
case frameworkResTag:

View File

@ -2542,6 +2542,20 @@ func TestUsesLibraries(t *testing.T) {
sdk_version: "current",
}
java_sdk_library {
name: "qux",
srcs: ["a.java"],
api_packages: ["qux"],
sdk_version: "current",
}
java_sdk_library {
name: "quuz",
srcs: ["a.java"],
api_packages: ["quuz"],
sdk_version: "current",
}
java_sdk_library {
name: "bar",
srcs: ["a.java"],
@ -2552,6 +2566,7 @@ func TestUsesLibraries(t *testing.T) {
android_app {
name: "app",
srcs: ["a.java"],
libs: ["qux", "quuz.stubs"],
uses_libs: ["foo"],
sdk_version: "current",
optional_uses_libs: [
@ -2582,6 +2597,15 @@ func TestUsesLibraries(t *testing.T) {
app := ctx.ModuleForTests("app", "android_common")
prebuilt := ctx.ModuleForTests("prebuilt", "android_common")
// Test that implicit dependencies on java_sdk_library instances are passed to the manifest.
manifestFixerArgs := app.Output("manifest_fixer/AndroidManifest.xml").Args["args"]
if w := "--uses-library qux"; !strings.Contains(manifestFixerArgs, w) {
t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
}
if w := "--uses-library quuz"; !strings.Contains(manifestFixerArgs, w) {
t.Errorf("unexpected manifest_fixer args: wanted %q in %q", w, manifestFixerArgs)
}
// Test that all libraries are verified
cmd := app.Rule("verify_uses_libraries").RuleParams.Command
if w := "--uses-library foo"; !strings.Contains(cmd, w) {

View File

@ -355,7 +355,17 @@ func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
}
// Functionality common to Module and Import
//
// It is embedded in Module so its functionality can be used by methods in Module
// but it is currently only initialized by Import and Library.
type embeddableInModuleAndImport struct {
// Functionality related to this being used as a component of a java_sdk_library.
EmbeddableSdkLibraryComponent
}
func (e *embeddableInModuleAndImport) initModuleAndImport(moduleBase *android.ModuleBase) {
e.initSdkLibraryComponent(moduleBase)
}
// Module/Import's DepIsInSameApex(...) delegates to this method.
@ -496,11 +506,6 @@ type Dependency interface {
JacocoReportClassesFile() android.Path
}
type SdkLibraryDependency interface {
SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
}
type xref interface {
XrefJavaFiles() android.Paths
}
@ -930,6 +935,12 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
}
}
// If this is a component library (stubs, etc.) for a java_sdk_library then
// add the name of that java_sdk_library to the exported sdk libs to make sure
// that, if necessary, a <uses-library> element for that java_sdk_library is
// added to the Android manifest.
j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@ -949,7 +960,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
case libTag:
deps.classpath = append(deps.classpath, dep.SdkHeaderJars(ctx, j.sdkVersion())...)
// names of sdk libs that are directly depended are exported
j.exportedSdkLibs = append(j.exportedSdkLibs, otherName)
j.exportedSdkLibs = append(j.exportedSdkLibs, dep.OptionalImplicitSdkLibrary()...)
case staticLibTag:
ctx.ModuleErrorf("dependency on java_sdk_library %q can only be in libs", otherName)
}
@ -1990,6 +2001,8 @@ func LibraryFactory() android.Module {
&module.Module.protoProperties,
&module.libraryProperties)
module.initModuleAndImport(&module.ModuleBase)
android.InitApexModule(module)
android.InitSdkAwareModule(module)
InitJavaModule(module, android.HostAndDeviceSupported)
@ -2462,6 +2475,12 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
}
j.combinedClasspathFile = outputFile
// If this is a component library (impl, stubs, etc.) for a java_sdk_library then
// add the name of that java_sdk_library to the exported sdk libs to make sure
// that, if necessary, a <uses-library> element for that java_sdk_library is
// added to the Android manifest.
j.exportedSdkLibs = append(j.exportedSdkLibs, j.OptionalImplicitSdkLibrary()...)
ctx.VisitDirectDeps(func(module android.Module) {
otherName := ctx.OtherModuleName(module)
tag := ctx.OtherModuleDependencyTag(module)
@ -2580,6 +2599,8 @@ func ImportFactory() android.Module {
module.AddProperties(&module.properties)
module.initModuleAndImport(&module.ModuleBase)
android.InitPrebuiltModule(module, &module.properties.Jars)
android.InitApexModule(module)
android.InitSdkAwareModule(module)

View File

@ -19,6 +19,7 @@ import (
"os"
"path/filepath"
"reflect"
"sort"
"strconv"
"strings"
"testing"
@ -1153,13 +1154,25 @@ func TestJavaSdkLibrary(t *testing.T) {
java_library {
name: "baz",
srcs: ["c.java"],
libs: ["foo", "bar"],
libs: ["foo", "bar.stubs"],
sdk_version: "system_current",
}
java_sdk_library_import {
name: "quuz",
public: {
jars: ["c.jar"],
},
}
java_sdk_library_import {
name: "fred",
public: {
jars: ["b.jar"],
},
}
java_library {
name: "qux",
srcs: ["c.java"],
libs: ["baz"],
libs: ["baz", "fred", "quuz.stubs"],
sdk_version: "system_current",
}
java_library {
@ -1224,8 +1237,9 @@ func TestJavaSdkLibrary(t *testing.T) {
qux := ctx.ModuleForTests("qux", "android_common")
if quxLib, ok := qux.Module().(*Library); ok {
sdkLibs := quxLib.ExportedSdkLibs()
if len(sdkLibs) != 2 || !android.InList("foo", sdkLibs) || !android.InList("bar", sdkLibs) {
t.Errorf("qux should export \"foo\" and \"bar\" but exports %v", sdkLibs)
sort.Strings(sdkLibs)
if w := []string{"bar", "foo", "fred", "quuz"}; !reflect.DeepEqual(w, sdkLibs) {
t.Errorf("qux should export %q but exports %q", w, sdkLibs)
}
}
}

View File

@ -543,12 +543,18 @@ type commonToSdkLibraryAndImport struct {
namingScheme sdkLibraryComponentNamingScheme
commonProperties commonToSdkLibraryAndImportProperties
// Functionality related to this being used as a component of a java_sdk_library.
EmbeddableSdkLibraryComponent
}
func (c *commonToSdkLibraryAndImport) initCommon(moduleBase *android.ModuleBase) {
c.moduleBase = moduleBase
moduleBase.AddProperties(&c.commonProperties)
// Initialize this as an sdk library component.
c.initSdkLibraryComponent(moduleBase)
}
func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android.DefaultableHookContext) bool {
@ -563,6 +569,9 @@ func (c *commonToSdkLibraryAndImport) initCommonAfterDefaultsApplied(ctx android
return false
}
// Use the name specified in the module definition as the owner.
c.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack = proptools.StringPtr(c.moduleBase.BaseModuleName())
return true
}
@ -728,6 +737,84 @@ func (c *commonToSdkLibraryAndImport) selectHeaderJarsForSdkVersion(ctx android.
return paths.stubsHeaderPath
}
func (c *commonToSdkLibraryAndImport) sdkComponentPropertiesForChildLibrary() interface{} {
componentProps := &struct {
SdkLibraryToImplicitlyTrack *string
}{
// Mark the stubs library as being components of this java_sdk_library so that
// any app that includes code which depends (directly or indirectly) on the stubs
// library will have the appropriate <uses-library> invocation inserted into its
// manifest if necessary.
SdkLibraryToImplicitlyTrack: proptools.StringPtr(c.moduleBase.BaseModuleName()),
}
return componentProps
}
// Properties related to the use of a module as an component of a java_sdk_library.
type SdkLibraryComponentProperties struct {
// The name of the java_sdk_library/_import to add to a <uses-library> entry
// in the AndroidManifest.xml of any Android app that includes code that references
// this module. If not set then no java_sdk_library/_import is tracked.
SdkLibraryToImplicitlyTrack *string `blueprint:"mutated"`
}
// Structure to be embedded in a module struct that needs to support the
// SdkLibraryComponentDependency interface.
type EmbeddableSdkLibraryComponent struct {
sdkLibraryComponentProperties SdkLibraryComponentProperties
}
func (e *EmbeddableSdkLibraryComponent) initSdkLibraryComponent(moduleBase *android.ModuleBase) {
moduleBase.AddProperties(&e.sdkLibraryComponentProperties)
}
// to satisfy SdkLibraryComponentDependency
func (e *EmbeddableSdkLibraryComponent) OptionalImplicitSdkLibrary() []string {
if e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack != nil {
return []string{*e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack}
}
return nil
}
// Implemented by modules that are (or possibly could be) a component of a java_sdk_library
// (including the java_sdk_library) itself.
type SdkLibraryComponentDependency interface {
// The optional name of the sdk library that should be implicitly added to the
// AndroidManifest of an app that contains code which references the sdk library.
//
// Returns an array containing 0 or 1 items rather than a *string to make it easier
// to append this to the list of exported sdk libraries.
OptionalImplicitSdkLibrary() []string
}
// Make sure that all the module types that are components of java_sdk_library/_import
// and which can be referenced (directly or indirectly) from an android app implement
// the SdkLibraryComponentDependency interface.
var _ SdkLibraryComponentDependency = (*Library)(nil)
var _ SdkLibraryComponentDependency = (*Import)(nil)
var _ SdkLibraryComponentDependency = (*SdkLibrary)(nil)
var _ SdkLibraryComponentDependency = (*sdkLibraryImport)(nil)
// Provides access to sdk_version related header and implentation jars.
type SdkLibraryDependency interface {
SdkLibraryComponentDependency
// Get the header jars appropriate for the supplied sdk_version.
//
// These are turbine generated jars so they only change if the externals of the
// class changes but it does not contain and implementation or JavaDoc.
SdkHeaderJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
// Get the implementation jars appropriate for the supplied sdk version.
//
// These are either the implementation jar for the whole sdk library or the implementation
// jars for the stubs. The latter should only be needed when generating JavaDoc as otherwise
// they are identical to the corresponding header jars.
SdkImplementationJars(ctx android.BaseModuleContext, sdkVersion sdkSpec) android.Paths
}
type SdkLibrary struct {
Library
@ -980,7 +1067,7 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
props.Dist.Tag = proptools.StringPtr(".jar")
}
mctx.CreateModule(LibraryFactory, &props)
mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
// Creates a droidstubs module that creates stubs source files from the given full source
@ -1323,6 +1410,8 @@ func (module *SdkLibrary) InitSdkLibraryProperties() {
&module.protoProperties,
)
module.initSdkLibraryComponent(&module.ModuleBase)
module.properties.Installable = proptools.BoolPtr(true)
module.deviceProperties.IsSDKLibrary = true
}
@ -1571,7 +1660,8 @@ func (module *sdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
// The imports are preferred if the java_sdk_library_import is preferred.
props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer())
mctx.CreateModule(ImportFactory, &props)
mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
func (module *sdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) {