Merge changes Ie274263a,I45993324

* changes:
  Adds droidstubs support to sdk module
  Simplify building an SDK snapshot from the command line
This commit is contained in:
Paul Duffin 2019-11-25 17:32:53 +00:00 committed by Gerrit Code Review
commit 62835fd85f
6 changed files with 268 additions and 7 deletions

View File

@ -164,6 +164,9 @@ type SnapshotBuilder interface {
// 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

View File

@ -37,6 +37,8 @@ func init() {
android.RegisterModuleType("droidstubs", DroidstubsFactory)
android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory)
android.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory)
}
var (
@ -1163,6 +1165,7 @@ func (d *Droiddoc) GenerateAndroidBuildActions(ctx android.ModuleContext) {
//
type Droidstubs struct {
Javadoc
android.SdkBase
properties DroidstubsProperties
apiFile android.WritablePath
@ -1208,6 +1211,7 @@ func DroidstubsFactory() android.Module {
&module.Javadoc.properties)
InitDroiddocModule(module, android.HostAndDeviceSupported)
android.InitSdkAwareModule(module)
return module
}
@ -1913,3 +1917,88 @@ func zipSyncCmd(ctx android.ModuleContext, rule *android.RuleBuilder,
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("")
}

View File

@ -89,6 +89,7 @@ func testContext(bp string, fs map[string][]byte) *android.TestContext {
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 @@ func testContext(bp string, fs map[string][]byte) *android.TestContext {
"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 @@ func TestPrebuilts(t *testing.T) {
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 @@ func TestPrebuilts(t *testing.T) {
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 @@ func TestPrebuilts(t *testing.T) {
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())
}

View File

@ -16,6 +16,7 @@ package sdk
import (
"fmt"
"io"
"strconv"
"github.com/google/blueprint"
@ -50,6 +51,8 @@ type sdkProperties struct {
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 @@ func (s *sdk) AndroidMkEntries() android.AndroidMkEntries {
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 @@ type sdkMemberVesionedDepTag struct {
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 {

View File

@ -45,6 +45,8 @@ func testSdkContext(t *testing.T, bp string) (*android.TestContext, android.Conf
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 @@ func testSdkContext(t *testing.T, bp string) (*android.TestContext, android.Conf
"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 @@ func TestBasicSdkWithCc(t *testing.T) {
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 @@ func TestSnapshot(t *testing.T) {
name: "mysdk",
java_libs: ["myjavalib"],
native_shared_libs: ["mynativelib"],
stubs_sources: ["myjavaapistubs"],
}
java_library {
@ -444,15 +482,26 @@ func TestSnapshot(t *testing.T) {
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 @@ func TestSnapshot(t *testing.T) {
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

View File

@ -80,6 +80,16 @@ func (s *sdk) javaLibs(ctx android.ModuleContext) []android.SdkAware {
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 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
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 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
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 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
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 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
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 @@ type snapshotBuilder struct {
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 @@ func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
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
}