Introduce system_modules property to java_api_library

System_modules property provides the jars passed as bootclasspath when
compiling the stubs in the java_api_library where its creating
java_sdk_library's sdk_version is none, as the jars will not be provided
from the full_surface_stub_libs but compiled by itself in the child
change.

The jar provided by the system_modules will also be passed to metalava
to resolve hierarchy coming from outer dependencies.

Test: m --build-from-text-stub
Bug: 288624417
Change-Id: I8f3b89efa24bceb070d7a37fae3c7334dd7f0868
This commit is contained in:
Jihoon Kang 2023-10-05 17:26:09 +00:00
parent b0f3ff43e5
commit 4ec24870e0
3 changed files with 67 additions and 8 deletions

View file

@ -1689,6 +1689,12 @@ type JavaApiLibraryProperties struct {
// Version of previously released API file for compatibility check.
Previous_api *string `android:"path"`
// java_system_modules module providing the jar to be added to the
// bootclasspath when compiling the stubs.
// The jar will also be passed to metalava as a classpath to
// generate compilable stubs.
System_modules *string
}
func ApiLibraryFactory() android.Module {
@ -1708,7 +1714,8 @@ func (al *ApiLibrary) StubsJar() android.Path {
}
func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
srcs android.Paths, homeDir android.WritablePath) *android.RuleBuilderCommand {
srcs android.Paths, homeDir android.WritablePath,
classpath android.Paths) *android.RuleBuilderCommand {
rule.Command().Text("rm -rf").Flag(homeDir.String())
rule.Command().Text("mkdir -p").Flag(homeDir.String())
@ -1747,12 +1754,17 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
FlagWithArg("--hide ", "InvalidNullabilityOverride").
FlagWithArg("--hide ", "ChangedDefault")
// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
// classes on the classpath when an API file contains missing classes. However, as this command
// does not specify `--classpath` this is not needed for that. However, this is also used as a
// signal to the special metalava code for generating stubs from text files that it needs to add
// some additional items into the API (e.g. default constructors).
cmd.FlagWithArg("--api-class-resolution ", "api")
if len(classpath) == 0 {
// The main purpose of the `--api-class-resolution api` option is to force metalava to ignore
// classes on the classpath when an API file contains missing classes. However, as this command
// does not specify `--classpath` this is not needed for that. However, this is also used as a
// signal to the special metalava code for generating stubs from text files that it needs to add
// some additional items into the API (e.g. default constructors).
cmd.FlagWithArg("--api-class-resolution ", "api")
} else {
cmd.FlagWithArg("--api-class-resolution ", "api:classpath")
cmd.FlagWithInputList("--classpath ", classpath, ":")
}
return cmd
}
@ -1815,6 +1827,9 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
if al.properties.Full_api_surface_stub != nil {
ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Full_api_surface_stub))
}
if al.properties.System_modules != nil {
ctx.AddVariationDependencies(nil, systemModulesTag, String(al.properties.System_modules))
}
}
// Map where key is the api scope name and value is the int value
@ -1854,6 +1869,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var classPaths android.Paths
var staticLibs android.Paths
var depApiSrcsStubsJar android.Path
var systemModulesPaths android.Paths
ctx.VisitDirectDeps(func(dep android.Module) {
tag := ctx.OtherModuleDependencyTag(dep)
switch tag {
@ -1872,6 +1888,9 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
case depApiSrcsTag:
provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
depApiSrcsStubsJar = provider.HeaderJars[0]
case systemModulesTag:
module := dep.(SystemModulesProvider)
systemModulesPaths = append(systemModulesPaths, module.HeaderJars()...)
}
})
@ -1885,7 +1904,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
}
cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir, systemModulesPaths)
al.stubsFlags(ctx, cmd, stubsDir)
@ -1917,6 +1936,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
flags.javaVersion = getStubsJavaVersion()
flags.javacFlags = strings.Join(al.properties.Javacflags, " ")
flags.classpath = classpath(classPaths)
flags.bootClasspath = classpath(systemModulesPaths)
annoSrcJar := android.PathForModuleOut(ctx, ctx.ModuleName(), "anno.srcjar")

View file

@ -2447,3 +2447,39 @@ func TestJavaApiLibraryApiFilesSorting(t *testing.T) {
"default/java/api/module-lib-current.txt default/java/api/system-server-current.txt"
android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag)
}
func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForJavaTest,
PrepareForTestWithJavaSdkLibraryFiles,
FixtureWithLastReleaseApis("foo"),
android.FixtureModifyConfig(func(config android.Config) {
config.SetApiLibraries([]string{"foo"})
}),
android.FixtureMergeMockFs(
map[string][]byte{
"A.java": nil,
},
),
).RunTestWithBp(t, `
java_library {
name: "bar",
srcs: ["a.java"],
}
java_system_modules {
name: "baz",
libs: ["bar"],
}
java_sdk_library {
name: "foo",
srcs: ["A.java"],
system_modules: "baz",
}
`)
m := result.ModuleForTests(apiScopePublic.apiLibraryModuleName("foo"), "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/.intermediates/bar/android_common/turbine-combined/bar.jar"
android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag)
}

View file

@ -1837,6 +1837,7 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext,
Libs []string
Static_libs []string
Full_api_surface_stub *string
System_modules *string
}{}
props.Name = proptools.StringPtr(module.apiLibraryModuleName(apiScope))
@ -1875,6 +1876,8 @@ func (module *SdkLibrary) createApiLibrary(mctx android.DefaultableHookContext,
props.Full_api_surface_stub = proptools.StringPtr(apiScope.kind.DefaultJavaLibraryName() + "_full.from-text")
}
props.System_modules = module.deviceProperties.System_modules
mctx.CreateModule(ApiLibraryFactory, &props)
}