Merge changes Ie274263a,I45993324
* changes:
Adds droidstubs support to sdk module
Simplify building an SDK snapshot from the command line
diff --git a/android/sdk.go b/android/sdk.go
index d66816d..73cb256 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -164,6 +164,9 @@
// to the zip
CopyToSnapshot(src Path, dest string)
+ // Unzip the supplied zip into the snapshot relative directory destDir.
+ UnzipToSnapshot(zipPath Path, destDir string)
+
// Get the AndroidBpFile for the snapshot.
AndroidBpFile() GeneratedSnapshotFile
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 54f93fe..83a1ad5 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -37,6 +37,8 @@
android.RegisterModuleType("droidstubs", DroidstubsFactory)
android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
+
+ android.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
}
var (
@@ -1163,6 +1165,7 @@
//
type Droidstubs struct {
Javadoc
+ android.SdkBase
properties DroidstubsProperties
apiFile android.WritablePath
@@ -1208,6 +1211,7 @@
&module.Javadoc.properties)
InitDroiddocModule(module, android.HostAndDeviceSupported)
+ android.InitSdkAwareModule(module)
return module
}
@@ -1913,3 +1917,88 @@
func zipSyncCleanupCmd(rule *android.RuleBuilder, srcJarDir android.ModuleOutPath) {
rule.Command().Text("rm -rf").Text(srcJarDir.String())
}
+
+var _ android.PrebuiltInterface = (*PrebuiltStubsSources)(nil)
+
+type PrebuiltStubsSourcesProperties struct {
+ Srcs []string `android:"path"`
+}
+
+type PrebuiltStubsSources struct {
+ android.ModuleBase
+ android.DefaultableModuleBase
+ prebuilt android.Prebuilt
+ android.SdkBase
+
+ properties PrebuiltStubsSourcesProperties
+
+ srcs android.Paths
+ stubsSrcJar android.ModuleOutPath
+}
+
+func (p *PrebuiltStubsSources) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ p.srcs = android.PathsForModuleSrc(ctx, p.properties.Srcs)
+}
+
+func (p *PrebuiltStubsSources) Prebuilt() *android.Prebuilt {
+ return &p.prebuilt
+}
+
+func (p *PrebuiltStubsSources) Name() string {
+ return p.prebuilt.Name(p.ModuleBase.Name())
+}
+
+func (p *PrebuiltStubsSources) Srcs() android.Paths {
+ return append(android.Paths{}, p.srcs...)
+}
+
+// prebuilt_stubs_sources imports a set of java source files as if they were
+// generated by droidstubs.
+//
+// By default, a prebuilt_stubs_sources has a single variant that expects a
+// set of `.java` files generated by droidstubs.
+//
+// Specifying `host_supported: true` will produce two variants, one for use as a dependency of device modules and one
+// for host modules.
+//
+// Intended only for use by sdk snapshots.
+func PrebuiltStubsSourcesFactory() android.Module {
+ module := &PrebuiltStubsSources{}
+
+ module.AddProperties(&module.properties)
+
+ android.InitPrebuiltModule(module, &module.properties.Srcs)
+ android.InitSdkAwareModule(module)
+ InitDroiddocModule(module, android.HostAndDeviceSupported)
+ return module
+}
+
+func (d *Droidstubs) BuildSnapshot(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder) {
+ stubsSrcJar := d.stubsSrcJar
+
+ snapshotRelativeDir := filepath.Join("java", d.Name()+"_stubs_sources")
+ builder.UnzipToSnapshot(stubsSrcJar, snapshotRelativeDir)
+
+ name := d.Name()
+ bp := builder.AndroidBpFile()
+ bp.Printfln("prebuilt_stubs_sources {")
+ bp.Indent()
+ bp.Printfln("name: %q,", builder.VersionedSdkMemberName(name))
+ bp.Printfln("sdk_member_name: %q,", name)
+ bp.Printfln("srcs: [%q],", snapshotRelativeDir)
+ bp.Dedent()
+ bp.Printfln("}")
+ bp.Printfln("")
+
+ // This module is for the case when the source tree for the unversioned module
+ // doesn't exist (i.e. building in an unbundled tree). "prefer:" is set to false
+ // so that this module does not eclipse the unversioned module if it exists.
+ bp.Printfln("prebuilt_stubs_sources {")
+ bp.Indent()
+ bp.Printfln("name: %q,", name)
+ bp.Printfln("srcs: [%q],", snapshotRelativeDir)
+ bp.Printfln("prefer: false,")
+ bp.Dedent()
+ bp.Printfln("}")
+ bp.Printfln("")
+}
diff --git a/java/java_test.go b/java/java_test.go
index 0f7e6de..71aba3a 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -89,6 +89,7 @@
ctx.RegisterModuleType("droiddoc", android.ModuleFactoryAdaptor(DroiddocFactory))
ctx.RegisterModuleType("droiddoc_host", android.ModuleFactoryAdaptor(DroiddocHostFactory))
ctx.RegisterModuleType("droiddoc_template", android.ModuleFactoryAdaptor(ExportedDroiddocDirFactory))
+ ctx.RegisterModuleType("prebuilt_stubs_sources", android.ModuleFactoryAdaptor(PrebuiltStubsSourcesFactory))
ctx.RegisterModuleType("java_sdk_library", android.ModuleFactoryAdaptor(SdkLibraryFactory))
ctx.RegisterModuleType("java_sdk_library_import", android.ModuleFactoryAdaptor(sdkLibraryImportFactory))
ctx.RegisterModuleType("override_android_app", android.ModuleFactoryAdaptor(OverrideAndroidAppModuleFactory))
@@ -207,6 +208,9 @@
"cert/new_cert.pk8": nil,
"testdata/data": nil,
+
+ "stubs-sources/foo/Foo.java": nil,
+ "stubs/sources/foo/Foo.java": nil,
}
for k, v := range fs {
@@ -415,7 +419,7 @@
ctx, _ := testJava(t, `
java_library {
name: "foo",
- srcs: ["a.java"],
+ srcs: ["a.java", ":stubs-source"],
libs: ["bar", "sdklib"],
static_libs: ["baz"],
}
@@ -439,6 +443,11 @@
name: "sdklib",
jars: ["b.jar"],
}
+
+ prebuilt_stubs_sources {
+ name: "stubs-source",
+ srcs: ["stubs/sources/**/*.java"],
+ }
`)
javac := ctx.ModuleForTests("foo", "android_common").Rule("javac")
@@ -447,6 +456,19 @@
bazJar := ctx.ModuleForTests("baz", "android_common").Rule("combineJar").Output
sdklibStubsJar := ctx.ModuleForTests("sdklib.stubs", "android_common").Rule("combineJar").Output
+ inputs := []string{}
+ for _, p := range javac.BuildParams.Inputs {
+ inputs = append(inputs, p.String())
+ }
+
+ expected := []string{
+ "a.java",
+ "stubs/sources/foo/Foo.java",
+ }
+ if !reflect.DeepEqual(expected, inputs) {
+ t.Errorf("foo inputs incorrect: expected %q, found %q", expected, inputs)
+ }
+
if !strings.Contains(javac.Args["classpath"], barJar.String()) {
t.Errorf("foo classpath %v does not contain %q", javac.Args["classpath"], barJar.String())
}
diff --git a/sdk/sdk.go b/sdk/sdk.go
index 4eb3665..ed2f26c 100644
--- a/sdk/sdk.go
+++ b/sdk/sdk.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "io"
"strconv"
"github.com/google/blueprint"
@@ -50,6 +51,8 @@
Java_libs []string
// The list of native libraries in this SDK
Native_shared_libs []string
+ // The list of stub sources in this SDK
+ Stubs_sources []string
Snapshot bool `blueprint:"mutated"`
}
@@ -121,6 +124,13 @@
OutputFile: s.snapshotFile,
DistFile: s.snapshotFile,
Include: "$(BUILD_PHONY_PACKAGE)",
+ ExtraFooters: []android.AndroidMkExtraFootersFunc{
+ func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) {
+ // Allow the sdk to be built by simply passing its name on the command line.
+ fmt.Fprintln(w, ".PHONY:", s.Name())
+ fmt.Fprintln(w, s.Name()+":", s.snapshotFile.String())
+ },
+ },
}
}
@@ -167,6 +177,7 @@
func memberMutator(mctx android.BottomUpMutatorContext) {
if m, ok := mctx.Module().(*sdk); ok {
mctx.AddVariationDependencies(nil, sdkMemberDepTag, m.properties.Java_libs...)
+ mctx.AddVariationDependencies(nil, sdkMemberDepTag, m.properties.Stubs_sources...)
targets := mctx.MultiTargets()
for _, target := range targets {
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 3471bc9..99192be 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -45,6 +45,8 @@
ctx.RegisterModuleType("android_app_certificate", android.ModuleFactoryAdaptor(java.AndroidAppCertificateFactory))
ctx.RegisterModuleType("java_library", android.ModuleFactoryAdaptor(java.LibraryFactory))
ctx.RegisterModuleType("java_import", android.ModuleFactoryAdaptor(java.ImportFactory))
+ ctx.RegisterModuleType("droidstubs", android.ModuleFactoryAdaptor(java.DroidstubsFactory))
+ ctx.RegisterModuleType("prebuilt_stubs_sources", android.ModuleFactoryAdaptor(java.PrebuiltStubsSourcesFactory))
// from cc package
ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(cc.LibraryFactory))
@@ -104,6 +106,8 @@
"include/Test.h": nil,
"aidl/foo/bar/Test.aidl": nil,
"libfoo.so": nil,
+ "stubs-sources/foo/bar/Foo.java": nil,
+ "foo/bar/Foo.java": nil,
})
return ctx, config
@@ -323,6 +327,39 @@
ensureListContains(t, pathsToStrings(cpplibForMyApex2.Rule("ld").Implicits), sdkMemberV2.String())
}
+// Note: This test does not verify that a droidstubs can be referenced, either
+// directly or indirectly from an APEX as droidstubs can never be a part of an
+// apex.
+func TestBasicSdkWithDroidstubs(t *testing.T) {
+ testSdk(t, `
+ sdk {
+ name: "mysdk",
+ stubs_sources: ["mystub"],
+ }
+ sdk_snapshot {
+ name: "mysdk@10",
+ stubs_sources: ["mystub_mysdk@10"],
+ }
+ prebuilt_stubs_sources {
+ name: "mystub_mysdk@10",
+ sdk_member_name: "mystub",
+ srcs: ["stubs-sources/foo/bar/Foo.java"],
+ }
+ droidstubs {
+ name: "mystub",
+ srcs: ["foo/bar/Foo.java"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ java_library {
+ name: "myjavalib",
+ srcs: [":mystub"],
+ sdk_version: "none",
+ system_modules: "none",
+ }
+ `)
+}
+
func TestDepNotInRequiredSdks(t *testing.T) {
testSdkError(t, `module "myjavalib".*depends on "otherlib".*that isn't part of the required SDKs:.*`, `
sdk {
@@ -417,6 +454,7 @@
name: "mysdk",
java_libs: ["myjavalib"],
native_shared_libs: ["mynativelib"],
+ stubs_sources: ["myjavaapistubs"],
}
java_library {
@@ -444,15 +482,26 @@
system_shared_libs: [],
stl: "none",
}
+
+ droidstubs {
+ name: "myjavaapistubs",
+ srcs: ["foo/bar/Foo.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ }
`)
var copySrcs []string
var copyDests []string
buildParams := ctx.ModuleForTests("mysdk", "android_common").Module().BuildParamsForTests()
+ var zipBp android.BuildParams
for _, bp := range buildParams {
- if bp.Rule.String() == "android/soong/android.Cp" {
+ ruleString := bp.Rule.String()
+ if ruleString == "android/soong/android.Cp" {
copySrcs = append(copySrcs, bp.Input.String())
copyDests = append(copyDests, bp.Output.Rel()) // rooted at the snapshot root
+ } else if ruleString == "<local rule>:m.mysdk_android_common.snapshot" {
+ zipBp = bp
}
}
@@ -472,6 +521,19 @@
ensureListContains(t, copyDests, "arm64/include_gen/mynativelib/aidl/foo/bar/Test.h")
ensureListContains(t, copyDests, "java/myjavalib.jar")
ensureListContains(t, copyDests, "arm64/lib/mynativelib.so")
+
+ // Ensure that the droidstubs .srcjar as repackaged into a temporary zip file
+ // and then merged together with the intermediate snapshot zip.
+ snapshotCreationInputs := zipBp.Implicits.Strings()
+ ensureListContains(t, snapshotCreationInputs,
+ filepath.Join(buildDir, ".intermediates/mysdk/android_common/tmp/java/myjavaapistubs_stubs_sources.zip"))
+ ensureListContains(t, snapshotCreationInputs,
+ filepath.Join(buildDir, ".intermediates/mysdk/android_common/mysdk-current.unmerged.zip"))
+ actual := zipBp.Output.String()
+ expected := filepath.Join(buildDir, ".intermediates/mysdk/android_common/mysdk-current.zip")
+ if actual != expected {
+ t.Errorf("Expected snapshot output to be %q but was %q", expected, actual)
+ }
}
var buildDir string
diff --git a/sdk/update.go b/sdk/update.go
index 9fa9e04..7daede3 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -80,6 +80,16 @@
return result
}
+func (s *sdk) stubsSources(ctx android.ModuleContext) []android.SdkAware {
+ result := []android.SdkAware{}
+ ctx.VisitDirectDeps(func(m android.Module) {
+ if j, ok := m.(*java.Droidstubs); ok {
+ result = append(result, j)
+ }
+ })
+ return result
+}
+
// archSpecificNativeLibInfo represents an arch-specific variant of a native lib
type archSpecificNativeLibInfo struct {
name string
@@ -236,8 +246,8 @@
ctx: ctx,
version: "current",
snapshotDir: snapshotDir.OutputPath,
- androidBpFile: bp,
filesToZip: []android.Path{bp.path},
+ androidBpFile: bp,
}
// copy exported AIDL files and stub jar files
@@ -246,6 +256,12 @@
m.BuildSnapshot(ctx, builder)
}
+ // copy stubs sources
+ stubsSources := s.stubsSources(ctx)
+ for _, m := range stubsSources {
+ m.BuildSnapshot(ctx, builder)
+ }
+
// copy exported header files and stub *.so files
nativeLibInfos := s.nativeMemberInfos(ctx)
for _, info := range nativeLibInfos {
@@ -266,6 +282,15 @@
bp.Dedent()
bp.Printfln("],") // java_libs
}
+ if len(stubsSources) > 0 {
+ bp.Printfln("stubs_sources: [")
+ bp.Indent()
+ for _, m := range stubsSources {
+ bp.Printfln("%q,", builder.VersionedSdkMemberName(m.Name()))
+ }
+ bp.Dedent()
+ bp.Printfln("],") // stubs_sources
+ }
if len(nativeLibInfos) > 0 {
bp.Printfln("native_shared_libs: [")
bp.Indent()
@@ -284,16 +309,45 @@
filesToZip := builder.filesToZip
// zip them all
- zipFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.zip").OutputPath
+ outputZipFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.zip").OutputPath
+ outputRuleName := "snapshot"
+ outputDesc := "Building snapshot for " + ctx.ModuleName()
+
+ // If there are no zips to merge then generate the output zip directly.
+ // Otherwise, generate an intermediate zip file into which other zips can be
+ // merged.
+ var zipFile android.OutputPath
+ var ruleName string
+ var desc string
+ if len(builder.zipsToMerge) == 0 {
+ zipFile = outputZipFile
+ ruleName = outputRuleName
+ desc = outputDesc
+ } else {
+ zipFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.unmerged.zip").OutputPath
+ ruleName = "intermediate snapshot"
+ desc = "Building intermediate snapshot for " + ctx.ModuleName()
+ }
+
rb := android.NewRuleBuilder()
rb.Command().
BuiltTool(ctx, "soong_zip").
FlagWithArg("-C ", builder.snapshotDir.String()).
FlagWithRspFileInputList("-l ", filesToZip).
FlagWithOutput("-o ", zipFile)
- rb.Build(pctx, ctx, "snapshot", "Building snapshot for "+ctx.ModuleName())
+ rb.Build(pctx, ctx, ruleName, desc)
- return zipFile
+ if len(builder.zipsToMerge) != 0 {
+ rb := android.NewRuleBuilder()
+ rb.Command().
+ BuiltTool(ctx, "merge_zips").
+ Output(outputZipFile).
+ Input(zipFile).
+ Inputs(builder.zipsToMerge)
+ rb.Build(pctx, ctx, outputRuleName, outputDesc)
+ }
+
+ return outputZipFile
}
func buildSharedNativeLibSnapshot(ctx android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder) {
@@ -404,8 +458,9 @@
ctx android.ModuleContext
version string
snapshotDir android.OutputPath
- filesToZip android.Paths
androidBpFile *generatedFile
+ filesToZip android.Paths
+ zipsToMerge android.Paths
}
func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
@@ -418,6 +473,25 @@
s.filesToZip = append(s.filesToZip, path)
}
+func (s *snapshotBuilder) UnzipToSnapshot(zipPath android.Path, destDir string) {
+ ctx := s.ctx
+
+ // Repackage the zip file so that the entries are in the destDir directory.
+ // This will allow the zip file to be merged into the snapshot.
+ tmpZipPath := android.PathForModuleOut(ctx, "tmp", destDir+".zip").OutputPath
+ rb := android.NewRuleBuilder()
+ rb.Command().
+ BuiltTool(ctx, "zip2zip").
+ FlagWithInput("-i ", zipPath).
+ FlagWithOutput("-o ", tmpZipPath).
+ Flag("**/*:" + destDir)
+ rb.Build(pctx, ctx, "repackaging "+destDir,
+ "Repackaging zip file "+destDir+" for snapshot "+ctx.ModuleName())
+
+ // Add the repackaged zip file to the files to merge.
+ s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
+}
+
func (s *snapshotBuilder) AndroidBpFile() android.GeneratedSnapshotFile {
return s.androidBpFile
}