Merge "Add dep_api_srcs property to java_api_library module"

This commit is contained in:
Jihoon Kang
2023-04-03 23:42:19 +00:00
committed by Gerrit Code Review
2 changed files with 126 additions and 14 deletions

View File

@@ -388,6 +388,8 @@ var (
jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true}
r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
depApiSrcsTag = dependencyTag{name: "dep-api-srcs"}
jniInstallTag = installDependencyTag{name: "jni install"}
binaryInstallTag = installDependencyTag{name: "binary install"}
usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
@@ -1609,6 +1611,13 @@ func (ap *JavaApiContribution) GenerateAndroidBuildActions(ctx android.ModuleCon
})
}
type JavaApiLibraryDepsInfo struct {
StubsJar android.Path
StubsSrcJar android.Path
}
var JavaApiLibraryDepsProvider = blueprint.NewProvider(JavaApiLibraryDepsInfo{})
type ApiLibrary struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -1618,8 +1627,10 @@ type ApiLibrary struct {
properties JavaApiLibraryProperties
stubsSrcJar android.WritablePath
stubsJar android.WritablePath
stubsSrcJar android.WritablePath
stubsJar android.WritablePath
stubsJarWithoutStaticLibs android.WritablePath
extractedSrcJar android.WritablePath
// .dex of stubs, used for hiddenapi processing
dexJarFile OptionalDexJarPath
}
@@ -1645,8 +1656,13 @@ type JavaApiLibraryProperties struct {
Libs []string
// List of java libs that this module has static dependencies to and will be
// passed in metalava invocation
// merge zipped after metalava invocation
Static_libs []string
// Java Api library to provide the full API surface text files and jar file.
// If this property is set, the provided full API surface text files and
// jar file are passed to metalava invocation.
Dep_api_srcs *string
}
func ApiLibraryFactory() android.Module {
@@ -1725,7 +1741,36 @@ func (al *ApiLibrary) stubsFlags(ctx android.ModuleContext, cmd *android.RuleBui
}
}
var javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
// This method extracts the stub java files from the srcjar file provided from dep_api_srcs module
// and replaces the java stubs generated by invoking metalava in this module.
// This method is used because metalava can generate compilable from-text stubs only when
// the codebase encompasses all classes listed in the input API text file, but a class can extend
// a class that is not within the same API domain.
func (al *ApiLibrary) extractApiSrcs(ctx android.ModuleContext, rule *android.RuleBuilder, stubsDir android.OptionalPath, depApiSrcsSrcJar android.Path) {
generatedStubsList := android.PathForModuleOut(ctx, "metalava", "sources.txt")
unzippedSrcJarDir := android.PathForModuleOut(ctx, "metalava", "unzipDir")
rule.Command().
BuiltTool("list_files").
Text(stubsDir.String()).
FlagWithOutput("--out ", generatedStubsList).
FlagWithArg("--extensions ", ".java").
FlagWithArg("--root ", unzippedSrcJarDir.String())
rule.Command().
Text("unzip").
Flag("-q").
Input(depApiSrcsSrcJar).
FlagWithArg("-d ", unzippedSrcJarDir.String())
rule.Command().
BuiltTool("soong_zip").
Flag("-srcjar").
Flag("-write_if_changed").
FlagWithArg("-C ", unzippedSrcJarDir.String()).
FlagWithInput("-l ", generatedStubsList).
FlagWithOutput("-o ", al.stubsSrcJar)
}
func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
apiContributions := al.properties.Api_contributions
@@ -1734,6 +1779,9 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
}
ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...)
ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_libs...)
if al.properties.Dep_api_srcs != nil {
ctx.AddVariationDependencies(nil, depApiSrcsTag, String(al.properties.Dep_api_srcs))
}
}
func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1754,6 +1802,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
var srcFiles android.Paths
var classPaths android.Paths
var staticLibs android.Paths
var depApiSrcsStubsSrcJar android.Path
ctx.VisitDirectDeps(func(dep android.Module) {
tag := ctx.OtherModuleDependencyTag(dep)
switch tag {
@@ -1770,6 +1819,10 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
case staticLibTag:
provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
staticLibs = append(staticLibs, provider.HeaderJars...)
case depApiSrcsTag:
provider := ctx.OtherModuleProvider(dep, JavaApiLibraryDepsProvider).(JavaApiLibraryDepsInfo)
classPaths = append(classPaths, provider.StubsJar)
depApiSrcsStubsSrcJar = provider.StubsSrcJar
}
})
@@ -1780,21 +1833,31 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
srcFiles = append(srcFiles, android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), api))
}
if srcFiles == nil {
ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
}
cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
al.stubsFlags(ctx, cmd, stubsDir)
al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
rule.Command().
BuiltTool("soong_zip").
Flag("-write_if_changed").
Flag("-jar").
FlagWithOutput("-o ", al.stubsSrcJar).
FlagWithArg("-C ", stubsDir.String()).
FlagWithArg("-D ", stubsDir.String())
if depApiSrcsStubsSrcJar != nil {
al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsSrcJar)
} else {
rule.Command().
BuiltTool("soong_zip").
Flag("-write_if_changed").
Flag("-jar").
FlagWithOutput("-o ", al.stubsSrcJar).
FlagWithArg("-C ", stubsDir.String()).
FlagWithArg("-D ", stubsDir.String())
}
rule.Build("metalava", "metalava merged")
compiledStubs := android.PathForModuleOut(ctx, ctx.ModuleName(), "stubs.jar")
al.stubsJarWithoutStaticLibs = android.PathForModuleOut(ctx, ctx.ModuleName(), "stubs.jar")
al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))
var flags javaBuilderFlags
@@ -1802,14 +1865,14 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
flags.javacFlags = strings.Join(al.properties.Javacflags, " ")
flags.classpath = classpath(classPaths)
TransformJavaToClasses(ctx, compiledStubs, 0, android.Paths{},
TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{},
android.Paths{al.stubsSrcJar}, flags, android.Paths{})
builder := android.NewRuleBuilder(pctx, ctx)
builder.Command().
BuiltTool("merge_zips").
Output(al.stubsJar).
Inputs(android.Paths{compiledStubs}).
Inputs(android.Paths{al.stubsJarWithoutStaticLibs}).
Inputs(staticLibs)
builder.Build("merge_zips", "merge jar files")
@@ -1835,6 +1898,11 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
AidlIncludeDirs: android.Paths{},
})
ctx.SetProvider(JavaApiLibraryDepsProvider, JavaApiLibraryDepsInfo{
StubsJar: al.stubsJar,
StubsSrcJar: al.stubsSrcJar,
})
}
func (al *ApiLibrary) DexJarBuildPath() OptionalDexJarPath {

View File

@@ -2209,6 +2209,50 @@ func TestJavaApiLibraryStaticLibsLink(t *testing.T) {
}
}
func TestJavaApiLibraryDepApiSrcs(t *testing.T) {
provider_bp_a := `
java_api_contribution {
name: "foo1",
api_file: "foo1.txt",
}
`
provider_bp_b := `
java_api_contribution {
name: "foo2",
api_file: "foo2.txt",
}
`
lib_bp_a := `
java_api_library {
name: "lib1",
api_surface: "public",
api_contributions: ["foo1", "foo2"],
}
`
ctx, _ := testJavaWithFS(t, `
java_api_library {
name: "bar1",
api_surface: "public",
api_contributions: ["foo1"],
dep_api_srcs: "lib1",
}
`,
map[string][]byte{
"a/Android.bp": []byte(provider_bp_a),
"b/Android.bp": []byte(provider_bp_b),
"c/Android.bp": []byte(lib_bp_a),
})
m := ctx.ModuleForTests("bar1", "android_common")
manifest := m.Output("metalava.sbox.textproto")
sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest)
manifestCommand := sboxProto.Commands[0].GetCommand()
android.AssertStringDoesContain(t, "Command expected to contain module srcjar file", manifestCommand, "bar1-stubs.srcjar")
android.AssertStringDoesContain(t, "Command expected to contain output files list text file flag", manifestCommand, "--out __SBOX_SANDBOX_DIR__/out/sources.txt")
}
func TestTradefedOptions(t *testing.T) {
result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
java_test_host {