Add dep_api_srcs property to java_api_library module
Users can pass the jar-file creating module via dep_api_srcs property in java_api_library to create the jar file not by compiling the stubs generated from metalava but by extracting and zipping the class files from the jar file of the input module. Test: m android-non-updatable.stubs.from-text Bug: 273381329 Change-Id: Id1b75179111cc7ff45faaff58388db1347bb18e5
This commit is contained in:
96
java/java.go
96
java/java.go
@@ -388,6 +388,8 @@ var (
|
|||||||
jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true}
|
jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true}
|
||||||
r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
|
r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true}
|
||||||
syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
|
syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
|
||||||
|
javaApiContributionTag = dependencyTag{name: "java-api-contribution"}
|
||||||
|
depApiSrcsTag = dependencyTag{name: "dep-api-srcs"}
|
||||||
jniInstallTag = installDependencyTag{name: "jni install"}
|
jniInstallTag = installDependencyTag{name: "jni install"}
|
||||||
binaryInstallTag = installDependencyTag{name: "binary install"}
|
binaryInstallTag = installDependencyTag{name: "binary install"}
|
||||||
usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
|
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 {
|
type ApiLibrary struct {
|
||||||
android.ModuleBase
|
android.ModuleBase
|
||||||
android.DefaultableModuleBase
|
android.DefaultableModuleBase
|
||||||
@@ -1618,8 +1627,10 @@ type ApiLibrary struct {
|
|||||||
|
|
||||||
properties JavaApiLibraryProperties
|
properties JavaApiLibraryProperties
|
||||||
|
|
||||||
stubsSrcJar android.WritablePath
|
stubsSrcJar android.WritablePath
|
||||||
stubsJar android.WritablePath
|
stubsJar android.WritablePath
|
||||||
|
stubsJarWithoutStaticLibs android.WritablePath
|
||||||
|
extractedSrcJar android.WritablePath
|
||||||
// .dex of stubs, used for hiddenapi processing
|
// .dex of stubs, used for hiddenapi processing
|
||||||
dexJarFile OptionalDexJarPath
|
dexJarFile OptionalDexJarPath
|
||||||
}
|
}
|
||||||
@@ -1645,8 +1656,13 @@ type JavaApiLibraryProperties struct {
|
|||||||
Libs []string
|
Libs []string
|
||||||
|
|
||||||
// List of java libs that this module has static dependencies to and will be
|
// 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
|
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 {
|
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) {
|
func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
|
||||||
apiContributions := al.properties.Api_contributions
|
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, libTag, al.properties.Libs...)
|
||||||
ctx.AddVariationDependencies(nil, staticLibTag, al.properties.Static_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) {
|
func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
@@ -1754,6 +1802,7 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
var srcFiles android.Paths
|
var srcFiles android.Paths
|
||||||
var classPaths android.Paths
|
var classPaths android.Paths
|
||||||
var staticLibs android.Paths
|
var staticLibs android.Paths
|
||||||
|
var depApiSrcsStubsSrcJar android.Path
|
||||||
ctx.VisitDirectDeps(func(dep android.Module) {
|
ctx.VisitDirectDeps(func(dep android.Module) {
|
||||||
tag := ctx.OtherModuleDependencyTag(dep)
|
tag := ctx.OtherModuleDependencyTag(dep)
|
||||||
switch tag {
|
switch tag {
|
||||||
@@ -1770,6 +1819,10 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
case staticLibTag:
|
case staticLibTag:
|
||||||
provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
|
provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo)
|
||||||
staticLibs = append(staticLibs, provider.HeaderJars...)
|
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))
|
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)
|
cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
|
||||||
|
|
||||||
al.stubsFlags(ctx, cmd, stubsDir)
|
al.stubsFlags(ctx, cmd, stubsDir)
|
||||||
|
|
||||||
al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
|
al.stubsSrcJar = android.PathForModuleOut(ctx, "metalava", ctx.ModuleName()+"-"+"stubs.srcjar")
|
||||||
rule.Command().
|
|
||||||
BuiltTool("soong_zip").
|
if depApiSrcsStubsSrcJar != nil {
|
||||||
Flag("-write_if_changed").
|
al.extractApiSrcs(ctx, rule, stubsDir, depApiSrcsStubsSrcJar)
|
||||||
Flag("-jar").
|
} else {
|
||||||
FlagWithOutput("-o ", al.stubsSrcJar).
|
rule.Command().
|
||||||
FlagWithArg("-C ", stubsDir.String()).
|
BuiltTool("soong_zip").
|
||||||
FlagWithArg("-D ", stubsDir.String())
|
Flag("-write_if_changed").
|
||||||
|
Flag("-jar").
|
||||||
|
FlagWithOutput("-o ", al.stubsSrcJar).
|
||||||
|
FlagWithArg("-C ", stubsDir.String()).
|
||||||
|
FlagWithArg("-D ", stubsDir.String())
|
||||||
|
}
|
||||||
|
|
||||||
rule.Build("metalava", "metalava merged")
|
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()))
|
al.stubsJar = android.PathForModuleOut(ctx, ctx.ModuleName(), fmt.Sprintf("%s.jar", ctx.ModuleName()))
|
||||||
|
|
||||||
var flags javaBuilderFlags
|
var flags javaBuilderFlags
|
||||||
@@ -1802,14 +1865,14 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
flags.javacFlags = strings.Join(al.properties.Javacflags, " ")
|
flags.javacFlags = strings.Join(al.properties.Javacflags, " ")
|
||||||
flags.classpath = classpath(classPaths)
|
flags.classpath = classpath(classPaths)
|
||||||
|
|
||||||
TransformJavaToClasses(ctx, compiledStubs, 0, android.Paths{},
|
TransformJavaToClasses(ctx, al.stubsJarWithoutStaticLibs, 0, android.Paths{},
|
||||||
android.Paths{al.stubsSrcJar}, flags, android.Paths{})
|
android.Paths{al.stubsSrcJar}, flags, android.Paths{})
|
||||||
|
|
||||||
builder := android.NewRuleBuilder(pctx, ctx)
|
builder := android.NewRuleBuilder(pctx, ctx)
|
||||||
builder.Command().
|
builder.Command().
|
||||||
BuiltTool("merge_zips").
|
BuiltTool("merge_zips").
|
||||||
Output(al.stubsJar).
|
Output(al.stubsJar).
|
||||||
Inputs(android.Paths{compiledStubs}).
|
Inputs(android.Paths{al.stubsJarWithoutStaticLibs}).
|
||||||
Inputs(staticLibs)
|
Inputs(staticLibs)
|
||||||
builder.Build("merge_zips", "merge jar files")
|
builder.Build("merge_zips", "merge jar files")
|
||||||
|
|
||||||
@@ -1835,6 +1898,11 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
|
ImplementationJars: android.PathsIfNonNil(al.stubsJar),
|
||||||
AidlIncludeDirs: android.Paths{},
|
AidlIncludeDirs: android.Paths{},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ctx.SetProvider(JavaApiLibraryDepsProvider, JavaApiLibraryDepsInfo{
|
||||||
|
StubsJar: al.stubsJar,
|
||||||
|
StubsSrcJar: al.stubsSrcJar,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (al *ApiLibrary) DexJarBuildPath() OptionalDexJarPath {
|
func (al *ApiLibrary) DexJarBuildPath() OptionalDexJarPath {
|
||||||
|
@@ -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) {
|
func TestTradefedOptions(t *testing.T) {
|
||||||
result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
|
result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, `
|
||||||
java_test_host {
|
java_test_host {
|
||||||
|
Reference in New Issue
Block a user