Merge "Generate "exportable" stubs library in java_sdk_library" into main

This commit is contained in:
Jihoon Kang
2024-01-09 06:02:12 +00:00
committed by Gerrit Code Review
3 changed files with 194 additions and 69 deletions

View File

@@ -1329,7 +1329,9 @@ type PrebuiltStubsSources struct {
func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) { func (p *PrebuiltStubsSources) OutputFiles(tag string) (android.Paths, error) {
switch tag { switch tag {
case "": // prebuilt droidstubs does not output "exportable" stubs.
// Output the "everything" stubs srcjar file if the tag is ".exportable".
case "", ".exportable":
return android.Paths{p.stubsSrcJar}, nil return android.Paths{p.stubsSrcJar}, nil
default: default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag) return nil, fmt.Errorf("unsupported module reference tag %q", tag)

View File

@@ -231,6 +231,10 @@ func (scope *apiScope) stubsLibraryModuleNameSuffix() string {
return ".stubs" + scope.moduleSuffix return ".stubs" + scope.moduleSuffix
} }
func (scope *apiScope) exportableStubsLibraryModuleNameSuffix() string {
return ".stubs.exportable" + scope.moduleSuffix
}
func (scope *apiScope) apiLibraryModuleName(baseName string) string { func (scope *apiScope) apiLibraryModuleName(baseName string) string {
return scope.stubsLibraryModuleName(baseName) + ".from-text" return scope.stubsLibraryModuleName(baseName) + ".from-text"
} }
@@ -239,10 +243,18 @@ func (scope *apiScope) sourceStubLibraryModuleName(baseName string) string {
return scope.stubsLibraryModuleName(baseName) + ".from-source" return scope.stubsLibraryModuleName(baseName) + ".from-source"
} }
func (scope *apiScope) exportableSourceStubsLibraryModuleName(baseName string) string {
return scope.exportableStubsLibraryModuleName(baseName) + ".from-source"
}
func (scope *apiScope) stubsLibraryModuleName(baseName string) string { func (scope *apiScope) stubsLibraryModuleName(baseName string) string {
return baseName + scope.stubsLibraryModuleNameSuffix() return baseName + scope.stubsLibraryModuleNameSuffix()
} }
func (scope *apiScope) exportableStubsLibraryModuleName(baseName string) string {
return baseName + scope.exportableStubsLibraryModuleNameSuffix()
}
func (scope *apiScope) stubsSourceModuleName(baseName string) string { func (scope *apiScope) stubsSourceModuleName(baseName string) string {
return baseName + ".stubs.source" + scope.moduleSuffix return baseName + ".stubs.source" + scope.moduleSuffix
} }
@@ -895,6 +907,12 @@ func (c *commonToSdkLibraryAndImport) stubsLibraryModuleName(apiScope *apiScope)
return c.namingScheme.stubsLibraryModuleName(apiScope, baseName) return c.namingScheme.stubsLibraryModuleName(apiScope, baseName)
} }
// Name of the java_library module that compiles the exportable stubs source.
func (c *commonToSdkLibraryAndImport) exportableStubsLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.BaseModuleName()
return c.namingScheme.exportableStubsLibraryModuleName(apiScope, baseName)
}
// Name of the droidstubs module that generates the stubs source and may also // Name of the droidstubs module that generates the stubs source and may also
// generate/check the API. // generate/check the API.
func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string { func (c *commonToSdkLibraryAndImport) stubsSourceModuleName(apiScope *apiScope) string {
@@ -911,9 +929,16 @@ func (c *commonToSdkLibraryAndImport) apiLibraryModuleName(apiScope *apiScope) s
// Name of the java_library module that compiles the stubs // Name of the java_library module that compiles the stubs
// generated from source Java files. // generated from source Java files.
func (c *commonToSdkLibraryAndImport) sourceStubLibraryModuleName(apiScope *apiScope) string { func (c *commonToSdkLibraryAndImport) sourceStubsLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.BaseModuleName() baseName := c.module.BaseModuleName()
return c.namingScheme.sourceStubLibraryModuleName(apiScope, baseName) return c.namingScheme.sourceStubsLibraryModuleName(apiScope, baseName)
}
// Name of the java_library module that compiles the exportable stubs
// generated from source Java files.
func (c *commonToSdkLibraryAndImport) exportableSourceStubsLibraryModuleName(apiScope *apiScope) string {
baseName := c.module.BaseModuleName()
return c.namingScheme.exportableSourceStubsLibraryModuleName(apiScope, baseName)
} }
// The component names for different outputs of the java_sdk_library. // The component names for different outputs of the java_sdk_library.
@@ -1629,36 +1654,34 @@ func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext)
mctx.CreateModule(LibraryFactory, properties...) mctx.CreateModule(LibraryFactory, properties...)
} }
// Creates a static java library that has API stubs type libraryProperties struct {
func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) { Name *string
props := struct { Visibility []string
Name *string Srcs []string
Visibility []string Installable *bool
Srcs []string Sdk_version *string
Installable *bool System_modules *string
Sdk_version *string Patch_module *string
System_modules *string Libs []string
Patch_module *string Static_libs []string
Libs []string Compile_dex *bool
Static_libs []string Java_version *string
Compile_dex *bool Openjdk9 struct {
Java_version *string Srcs []string
Openjdk9 struct { Javacflags []string
Srcs []string }
Javacflags []string Dist struct {
} Targets []string
Dist struct { Dest *string
Targets []string Dir *string
Dest *string Tag *string
Dir *string }
Tag *string }
}
}{}
props.Name = proptools.StringPtr(module.sourceStubLibraryModuleName(apiScope)) func (module *SdkLibrary) stubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
props := libraryProperties{}
props.Visibility = []string{"//visibility:override", "//visibility:private"} props.Visibility = []string{"//visibility:override", "//visibility:private"}
// sources are generated from the droiddoc // sources are generated from the droiddoc
props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope) sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
props.Sdk_version = proptools.StringPtr(sdkVersion) props.Sdk_version = proptools.StringPtr(sdkVersion)
props.System_modules = module.deviceProperties.System_modules props.System_modules = module.deviceProperties.System_modules
@@ -1678,6 +1701,25 @@ func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext
// interop with older developer tools that don't support 1.9. // interop with older developer tools that don't support 1.9.
props.Java_version = proptools.StringPtr("1.8") props.Java_version = proptools.StringPtr("1.8")
return props
}
// Creates a static java library that has API stubs
func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
props := module.stubsLibraryProps(mctx, apiScope)
props.Name = proptools.StringPtr(module.sourceStubsLibraryModuleName(apiScope))
props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope)}
mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
// Create a static java library that compiles the "exportable" stubs
func (module *SdkLibrary) createExportableStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
props := module.stubsLibraryProps(mctx, apiScope)
props.Name = proptools.StringPtr(module.exportableSourceStubsLibraryModuleName(apiScope))
props.Srcs = []string{":" + module.stubsSourceModuleName(apiScope) + "{.exportable}"}
mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary()) mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
} }
@@ -1908,43 +1950,15 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext,
mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary()) mctx.CreateModule(ApiLibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
} }
func (module *SdkLibrary) createTopLevelStubsLibrary( func (module *SdkLibrary) topLevelStubsLibraryProps(mctx android.DefaultableHookContext, apiScope *apiScope) libraryProperties {
mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) { props := libraryProperties{}
props := struct {
Name *string
Visibility []string
Sdk_version *string
Static_libs []string
System_modules *string
Dist struct {
Targets []string
Dest *string
Dir *string
Tag *string
}
Compile_dex *bool
}{}
props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility) props.Visibility = childModuleVisibility(module.sdkLibraryProperties.Stubs_library_visibility)
sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope) sdkVersion := module.sdkVersionForStubsLibrary(mctx, apiScope)
props.Sdk_version = proptools.StringPtr(sdkVersion) props.Sdk_version = proptools.StringPtr(sdkVersion)
// Add the stub compiling java_library/java_api_library as static lib based on build config
staticLib := module.sourceStubLibraryModuleName(apiScope)
if mctx.Config().BuildFromTextStub() && contributesToApiSurface {
staticLib = module.apiLibraryModuleName(apiScope)
}
props.Static_libs = append(props.Static_libs, staticLib)
props.System_modules = module.deviceProperties.System_modules props.System_modules = module.deviceProperties.System_modules
// Dist the class jar artifact for sdk builds.
if !Bool(module.sdkLibraryProperties.No_dist) {
props.Dist.Targets = []string{"sdk", "win_sdk"}
props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
props.Dist.Tag = proptools.StringPtr(".jar")
}
// The imports need to be compiled to dex if the java_sdk_library requests it. // The imports need to be compiled to dex if the java_sdk_library requests it.
compileDex := module.dexProperties.Compile_dex compileDex := module.dexProperties.Compile_dex
if module.stubLibrariesCompiledForDex() { if module.stubLibrariesCompiledForDex() {
@@ -1952,6 +1966,43 @@ func (module *SdkLibrary) createTopLevelStubsLibrary(
} }
props.Compile_dex = compileDex props.Compile_dex = compileDex
return props
}
func (module *SdkLibrary) createTopLevelStubsLibrary(
mctx android.DefaultableHookContext, apiScope *apiScope, contributesToApiSurface bool) {
props := module.topLevelStubsLibraryProps(mctx, apiScope)
props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope))
// Add the stub compiling java_library/java_api_library as static lib based on build config
staticLib := module.sourceStubsLibraryModuleName(apiScope)
if mctx.Config().BuildFromTextStub() && contributesToApiSurface {
staticLib = module.apiLibraryModuleName(apiScope)
}
props.Static_libs = append(props.Static_libs, staticLib)
mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
}
func (module *SdkLibrary) createTopLevelExportableStubsLibrary(
mctx android.DefaultableHookContext, apiScope *apiScope) {
props := module.topLevelStubsLibraryProps(mctx, apiScope)
props.Name = proptools.StringPtr(module.exportableStubsLibraryModuleName(apiScope))
// Dist the class jar artifact for sdk builds.
// "exportable" stubs are copied to dist for sdk builds instead of the "everything" stubs.
if !Bool(module.sdkLibraryProperties.No_dist) {
props.Dist.Targets = []string{"sdk", "win_sdk"}
props.Dist.Dest = proptools.StringPtr(fmt.Sprintf("%v.jar", module.distStem()))
props.Dist.Dir = proptools.StringPtr(module.apiDistPath(apiScope))
props.Dist.Tag = proptools.StringPtr(".jar")
}
staticLib := module.exportableSourceStubsLibraryModuleName(apiScope)
props.Static_libs = append(props.Static_libs, staticLib)
mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary()) mctx.CreateModule(LibraryFactory, &props, module.sdkComponentPropertiesForChildLibrary())
} }
@@ -2157,6 +2208,7 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont
module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs) module.createStubsSourcesAndApi(mctx, scope, module.stubsSourceModuleName(scope), scope.droidstubsArgs)
module.createStubsLibrary(mctx, scope) module.createStubsLibrary(mctx, scope)
module.createExportableStubsLibrary(mctx, scope)
alternativeFullApiSurfaceStubLib := "" alternativeFullApiSurfaceStubLib := ""
if scope == apiScopePublic { if scope == apiScopePublic {
@@ -2168,6 +2220,7 @@ func (module *SdkLibrary) CreateInternalModules(mctx android.DefaultableHookCont
} }
module.createTopLevelStubsLibrary(mctx, scope, contributesToApiSurface) module.createTopLevelStubsLibrary(mctx, scope, contributesToApiSurface)
module.createTopLevelExportableStubsLibrary(mctx, scope)
} }
if module.requiresRuntimeImplementationLibrary() { if module.requiresRuntimeImplementationLibrary() {
@@ -2223,7 +2276,11 @@ type sdkLibraryComponentNamingScheme interface {
apiLibraryModuleName(scope *apiScope, baseName string) string apiLibraryModuleName(scope *apiScope, baseName string) string
sourceStubLibraryModuleName(scope *apiScope, baseName string) string sourceStubsLibraryModuleName(scope *apiScope, baseName string) string
exportableStubsLibraryModuleName(scope *apiScope, baseName string) string
exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string
} }
type defaultNamingScheme struct { type defaultNamingScheme struct {
@@ -2241,34 +2298,47 @@ func (s *defaultNamingScheme) apiLibraryModuleName(scope *apiScope, baseName str
return scope.apiLibraryModuleName(baseName) return scope.apiLibraryModuleName(baseName)
} }
func (s *defaultNamingScheme) sourceStubLibraryModuleName(scope *apiScope, baseName string) string { func (s *defaultNamingScheme) sourceStubsLibraryModuleName(scope *apiScope, baseName string) string {
return scope.sourceStubLibraryModuleName(baseName) return scope.sourceStubLibraryModuleName(baseName)
} }
func (s *defaultNamingScheme) exportableStubsLibraryModuleName(scope *apiScope, baseName string) string {
return scope.exportableStubsLibraryModuleName(baseName)
}
func (s *defaultNamingScheme) exportableSourceStubsLibraryModuleName(scope *apiScope, baseName string) string {
return scope.exportableSourceStubsLibraryModuleName(baseName)
}
var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil) var _ sdkLibraryComponentNamingScheme = (*defaultNamingScheme)(nil)
func hasStubsLibrarySuffix(name string, apiScope *apiScope) bool {
return strings.HasSuffix(name, apiScope.stubsLibraryModuleNameSuffix()) ||
strings.HasSuffix(name, apiScope.exportableStubsLibraryModuleNameSuffix())
}
func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) { func moduleStubLinkType(name string) (stub bool, ret sdkLinkType) {
name = strings.TrimSuffix(name, ".from-source") name = strings.TrimSuffix(name, ".from-source")
// This suffix-based approach is fragile and could potentially mis-trigger. // This suffix-based approach is fragile and could potentially mis-trigger.
// TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly. // TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly.
if strings.HasSuffix(name, apiScopePublic.stubsLibraryModuleNameSuffix()) { if hasStubsLibrarySuffix(name, apiScopePublic) {
if name == "hwbinder.stubs" || name == "libcore_private.stubs" { if name == "hwbinder.stubs" || name == "libcore_private.stubs" {
// Due to a previous bug, these modules were not considered stubs, so we retain that. // Due to a previous bug, these modules were not considered stubs, so we retain that.
return false, javaPlatform return false, javaPlatform
} }
return true, javaSdk return true, javaSdk
} }
if strings.HasSuffix(name, apiScopeSystem.stubsLibraryModuleNameSuffix()) { if hasStubsLibrarySuffix(name, apiScopeSystem) {
return true, javaSystem return true, javaSystem
} }
if strings.HasSuffix(name, apiScopeModuleLib.stubsLibraryModuleNameSuffix()) { if hasStubsLibrarySuffix(name, apiScopeModuleLib) {
return true, javaModule return true, javaModule
} }
if strings.HasSuffix(name, apiScopeTest.stubsLibraryModuleNameSuffix()) { if hasStubsLibrarySuffix(name, apiScopeTest) {
return true, javaSystem return true, javaSystem
} }
if strings.HasSuffix(name, apiScopeSystemServer.stubsLibraryModuleNameSuffix()) { if hasStubsLibrarySuffix(name, apiScopeSystemServer) {
return true, javaSystemServer return true, javaSystemServer
} }
return false, javaPlatform return false, javaPlatform

View File

@@ -1423,7 +1423,7 @@ func TestJavaSdkLibraryDist(t *testing.T) {
for _, tt := range testCases { for _, tt := range testCases {
t.Run(tt.module, func(t *testing.T) { t.Run(tt.module, func(t *testing.T) {
m := result.ModuleForTests(tt.module+".stubs", "android_common").Module().(*Library) m := result.ModuleForTests(apiScopePublic.exportableStubsLibraryModuleName(tt.module), "android_common").Module().(*Library)
dists := m.Dists() dists := m.Dists()
if len(dists) != 1 { if len(dists) != 1 {
t.Fatalf("expected exactly 1 dist entry, got %d", len(dists)) t.Fatalf("expected exactly 1 dist entry, got %d", len(dists))
@@ -1693,3 +1693,56 @@ func TestSdkLibraryDependency(t *testing.T) {
android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barPermissions.RuleParams.Command, `dependency=\"foo\"`) android.AssertStringDoesContain(t, "bar.xml java_sdk_xml command", barPermissions.RuleParams.Command, `dependency=\"foo\"`)
} }
func TestSdkLibraryExportableStubsLibrary(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("foo"),
android.FixtureModifyConfig(func(config android.Config) {
config.SetApiLibraries([]string{"foo"})
}),
).RunTestWithBp(t, `
aconfig_declarations {
name: "bar",
package: "com.example.package",
srcs: [
"bar.aconfig",
],
}
java_sdk_library {
name: "foo",
srcs: ["a.java", "b.java"],
api_packages: ["foo"],
system: {
enabled: true,
},
module_lib: {
enabled: true,
},
test: {
enabled: true,
},
aconfig_declarations: [
"bar",
],
}
`)
exportableStubsLibraryModuleName := apiScopePublic.exportableStubsLibraryModuleName("foo")
exportableSourceStubsLibraryModuleName := apiScopePublic.exportableSourceStubsLibraryModuleName("foo")
// Check modules generation
topLevelModule := result.ModuleForTests(exportableStubsLibraryModuleName, "android_common")
result.ModuleForTests(exportableSourceStubsLibraryModuleName, "android_common")
// Check static lib dependency
android.AssertBoolEquals(t, "exportable top level stubs library module depends on the"+
"exportable source stubs library module", true,
CheckModuleHasDependency(t, result.TestContext, exportableStubsLibraryModuleName,
"android_common", exportableSourceStubsLibraryModuleName),
)
android.AssertArrayString(t, "exportable source stub library is a static lib of the"+
"top level exportable stubs library", []string{exportableSourceStubsLibraryModuleName},
topLevelModule.Module().(*Library).properties.Static_libs)
}