Merge changes from topic "is_stubs_module" into main

* changes:
  Improve determination whether to propagate JarJarProvider
  Introduce library property is_stubs_module
This commit is contained in:
LaMont Jones
2024-02-14 21:38:20 +00:00
committed by Gerrit Code Review
5 changed files with 176 additions and 9 deletions

View File

@@ -23,6 +23,7 @@ import (
"android/soong/android"
"android/soong/dexpreopt"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -1245,6 +1246,7 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) {
TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars,
ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile),
ImplementationJars: android.PathsIfNonNil(a.classpathFile),
StubsLinkType: Implementation,
// TransitiveAconfigFiles: // TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})

View File

@@ -205,6 +205,13 @@ type CommonProperties struct {
// Note that currently not all actions implemented by android_apps are sandboxed, so you
// may only see this being necessary in lint builds.
Compile_data []string `android:"path"`
// Property signifying whether the module compiles stubs or not.
// Should be set to true when srcs of this module are stub files.
// This property does not need to be set to true when the module depends on
// the stubs via libs, but should be set to true when the module depends on
// the stubs via static libs.
Is_stubs_module *bool
}
// Properties that are specific to device modules. Host module factories should not add these when
@@ -532,6 +539,8 @@ type Module struct {
// Values that will be set in the JarJarProvider data for jarjar repackaging,
// and merged with our dependencies' rules.
jarjarRenameRules map[string]string
stubsLinkType StubsLinkType
}
func (j *Module) CheckStableSdkVersion(ctx android.BaseModuleContext) error {
@@ -1212,6 +1221,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ExportedPlugins: j.exportedPluginJars,
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
StubsLinkType: j.stubsLinkType,
})
j.outputFile = j.headerJarFile
@@ -1729,6 +1739,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
JacocoReportClassesFile: j.jacocoReportClassesFile,
StubsLinkType: j.stubsLinkType,
})
// Save the output file with no relative path so that it doesn't end up in a subdirectory when used as a resource
@@ -2372,11 +2383,26 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps {
// classes until a module with jarjar_prefix is reached, and all as yet unrenamed classes will then
// be renamed from that module.
// TODO: Add another property to suppress the forwarding of
type DependencyUse int
const (
RenameUseInvalid DependencyUse = iota
RenameUseInclude
RenameUseExclude
)
type RenameUseElement struct {
DepName string
RenameUse DependencyUse
Why string // token for determining where in the logic the decision was made.
}
type JarJarProviderData struct {
// Mapping of class names: original --> renamed. If the value is "", the class will be
// renamed by the next rdep that has the jarjar_prefix attribute (or this module if it has
// attribute). Rdeps of that module will inherit the renaming.
Rename map[string]string
Rename map[string]string
RenameUse []RenameUseElement
}
func (this JarJarProviderData) GetDebugString() string {
@@ -2440,17 +2466,112 @@ func (module *Module) addJarJarRenameRule(original string, renamed string) {
func collectDirectDepsProviders(ctx android.ModuleContext) (result *JarJarProviderData) {
// Gather repackage information from deps
// If the dep jas a JarJarProvider, it is used. Otherwise, any BaseJarJarProvider is used.
module := ctx.Module()
moduleName := module.Name()
ctx.VisitDirectDepsIgnoreBlueprint(func(m android.Module) {
if ctx.OtherModuleDependencyTag(m) == proguardRaiseTag {
return
}
merge := func(theirs *JarJarProviderData) {
for orig, renamed := range theirs.Rename {
if result == nil {
result = &JarJarProviderData{
Rename: make(map[string]string),
tag := ctx.OtherModuleDependencyTag(m)
// This logic mirrors that in (*Module).collectDeps above. There are several places
// where we explicitly return RenameUseExclude, even though it is the default, to
// indicate that it has been verified to be the case.
//
// Note well: there are probably cases that are getting to the unconditional return
// and are therefore wrong.
shouldIncludeRenames := func() (DependencyUse, string) {
if moduleName == m.Name() {
return RenameUseInclude, "name" // If we have the same module name, include the renames.
}
if sc, ok := module.(android.SdkContext); ok {
if ctx.Device() {
sdkDep := decodeSdkDep(ctx, sc)
if !sdkDep.invalidVersion && sdkDep.useFiles {
return RenameUseExclude, "useFiles"
}
}
}
if IsJniDepTag(tag) || tag == certificateTag || tag == proguardRaiseTag {
return RenameUseExclude, "tags"
}
if _, ok := m.(SdkLibraryDependency); ok {
switch tag {
case sdkLibTag, libTag:
return RenameUseExclude, "sdklibdep" // matches collectDeps()
}
return RenameUseInvalid, "sdklibdep" // dep is not used in collectDeps()
} else if ji, ok := android.OtherModuleProvider(ctx, m, JavaInfoProvider); ok {
switch ji.StubsLinkType {
case Stubs:
return RenameUseExclude, "info"
case Implementation:
return RenameUseInclude, "info"
default:
//fmt.Printf("LJ: %v -> %v StubsLinkType unknown\n", module, m)
// Fall through to the heuristic logic.
}
switch reflect.TypeOf(m).String() {
case "*java.GeneratedJavaLibraryModule":
// Probably a java_aconfig_library module.
// TODO: make this check better.
return RenameUseInclude, "reflect"
}
switch tag {
case bootClasspathTag:
return RenameUseExclude, "tagswitch"
case sdkLibTag, libTag, instrumentationForTag:
return RenameUseInclude, "tagswitch"
case java9LibTag:
return RenameUseExclude, "tagswitch"
case staticLibTag:
return RenameUseInclude, "tagswitch"
case pluginTag:
return RenameUseInclude, "tagswitch"
case errorpronePluginTag:
return RenameUseInclude, "tagswitch"
case exportedPluginTag:
return RenameUseInclude, "tagswitch"
case kotlinStdlibTag, kotlinAnnotationsTag:
return RenameUseExclude, "tagswitch"
case kotlinPluginTag:
return RenameUseInclude, "tagswitch"
default:
return RenameUseExclude, "tagswitch"
}
} else if _, ok := m.(android.SourceFileProducer); ok {
switch tag {
case sdkLibTag, libTag, staticLibTag:
return RenameUseInclude, "srcfile"
default:
return RenameUseExclude, "srcfile"
}
} else {
switch tag {
case bootClasspathTag:
return RenameUseExclude, "else"
case systemModulesTag:
return RenameUseInclude, "else"
}
}
// If we got here, choose the safer option, which may lead to a build failure, rather
// than runtime failures on the device.
return RenameUseExclude, "end"
}
if result == nil {
result = &JarJarProviderData{
Rename: make(map[string]string),
RenameUse: make([]RenameUseElement, 0),
}
}
how, why := shouldIncludeRenames()
result.RenameUse = append(result.RenameUse, RenameUseElement{DepName: m.Name(), RenameUse: how, Why: why})
if how != RenameUseInclude {
// Nothing to merge.
return
}
merge := func(theirs *JarJarProviderData) {
for orig, renamed := range theirs.Rename {
if preexisting, exists := (*result).Rename[orig]; !exists || preexisting == "" {
result.Rename[orig] = renamed
} else if preexisting != "" && renamed != "" && preexisting != renamed {

View File

@@ -137,6 +137,7 @@ func (d *DeviceHostConverter) GenerateAndroidBuildActions(ctx android.ModuleCont
ResourceJars: d.resourceJars,
SrcJarArgs: d.srcJarArgs,
SrcJarDeps: d.srcJarDeps,
StubsLinkType: Implementation,
// TODO: Not sure if aconfig flags that have been moved between device and host variants
// make sense.
})

View File

@@ -87,6 +87,14 @@ func RegisterJavaSdkMemberTypes() {
android.RegisterSdkMemberType(javaTestSdkMemberType)
}
type StubsLinkType int
const (
Unknown StubsLinkType = iota
Stubs
Implementation
)
var (
// Supports adding java header libraries to module_exports and sdk.
javaHeaderLibsSdkMemberType = &librarySdkMemberType{
@@ -296,6 +304,11 @@ type JavaInfo struct {
// JacocoReportClassesFile is the path to a jar containing uninstrumented classes that will be
// instrumented by jacoco.
JacocoReportClassesFile android.Path
// StubsLinkType provides information about whether the provided jars are stub jars or
// implementation jars. If the provider is set by java_sdk_library, the link type is "unknown"
// and selection between the stub jar vs implementation jar is deferred to SdkLibrary.sdkJars(...)
StubsLinkType StubsLinkType
}
var JavaInfoProvider = blueprint.NewProvider[JavaInfo]()
@@ -694,6 +707,17 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
j.minSdkVersion = j.MinSdkVersion(ctx)
j.maxSdkVersion = j.MaxSdkVersion(ctx)
// SdkLibrary.GenerateAndroidBuildActions(ctx) sets the stubsLinkType to Unknown.
// If the stubsLinkType has already been set to Unknown, the stubsLinkType should
// not be overridden.
if j.stubsLinkType != Unknown {
if proptools.Bool(j.properties.Is_stubs_module) {
j.stubsLinkType = Stubs
} else {
j.stubsLinkType = Implementation
}
}
j.stem = proptools.StringDefault(j.overridableDeviceProperties.Stem, ctx.ModuleName())
proguardSpecInfo := j.collectProguardSpecInfo(ctx)
@@ -2018,6 +2042,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ImplementationAndResourcesJars: android.PathsIfNonNil(al.stubsJar),
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
AidlIncludeDirs: android.Paths{},
StubsLinkType: Stubs,
// No aconfig libraries on api libraries
})
}
@@ -2102,6 +2127,9 @@ type ImportProperties struct {
// The name is the undecorated name of the java_sdk_library as it appears in the blueprint file
// (without any prebuilt_ prefix)
Created_by_java_sdk_library_name *string `blueprint:"mutated"`
// Property signifying whether the module provides stubs jar or not.
Is_stubs_module *bool
}
type Import struct {
@@ -2132,6 +2160,8 @@ type Import struct {
sdkVersion android.SdkSpec
minSdkVersion android.ApiLevel
stubsLinkType StubsLinkType
}
var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil)
@@ -2226,6 +2256,12 @@ func (j *Import) commonBuildActions(ctx android.ModuleContext) {
if ctx.Windows() {
j.HideFromMake()
}
if proptools.Bool(j.properties.Is_stubs_module) {
j.stubsLinkType = Stubs
} else {
j.stubsLinkType = Implementation
}
}
func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -2359,6 +2395,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile),
ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile),
AidlIncludeDirs: j.exportAidlIncludeDirs,
StubsLinkType: j.stubsLinkType,
// TODO(b/289117800): LOCAL_ACONFIG_FILES for prebuilts
})
}

View File

@@ -1572,6 +1572,8 @@ func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext)
// Only build an implementation library if required.
if module.requiresRuntimeImplementationLibrary() {
// stubsLinkType must be set before calling Library.GenerateAndroidBuildActions
module.Library.stubsLinkType = Unknown
module.Library.GenerateAndroidBuildActions(ctx)
}
@@ -1797,6 +1799,7 @@ type libraryProperties struct {
Dir *string
Tag *string
}
Is_stubs_module *bool
}
func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
@@ -1821,6 +1824,7 @@ func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext,
// We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
// interop with older developer tools that don't support 1.9.
props.Java_version = proptools.StringPtr("1.8")
props.Is_stubs_module = proptools.BoolPtr(true)
return props
}
@@ -2709,6 +2713,7 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
Libs []string
Jars []string
Compile_dex *bool
Is_stubs_module *bool
android.UserSuppliedPrebuiltProperties
}{}
@@ -2730,6 +2735,7 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl
compileDex = proptools.BoolPtr(true)
}
props.Compile_dex = compileDex
props.Is_stubs_module = proptools.BoolPtr(true)
mctx.CreateModule(ImportFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}