Refactor sdk update mechanism
Creates a SnapshotBuilder and GeneratedSnapshotFile interfaces to allow
the java library snapshot work to be moved into the java package.
Test: m -j60 checkbuild
Change-Id: I857167616026149d5e85885621b53876b419ba9b
diff --git a/sdk/update.go b/sdk/update.go
index 171bb3f..9fa9e04 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -43,17 +43,17 @@
}
}
-func (gf *generatedFile) indent() {
+func (gf *generatedFile) Indent() {
gf.indentLevel++
}
-func (gf *generatedFile) dedent() {
+func (gf *generatedFile) Dedent() {
gf.indentLevel--
}
-func (gf *generatedFile) printfln(format string, args ...interface{}) {
+func (gf *generatedFile) Printfln(format string, args ...interface{}) {
// ninja consumes newline characters in rspfile_content. Prevent it by
- // escaping the backslash in the newline character. The extra backshash
+ // escaping the backslash in the newline character. The extra backslash
// is removed when the rspfile is written to the actual script file
fmt.Fprintf(&(gf.content), strings.Repeat(" ", gf.indentLevel)+format+"\\n", args...)
}
@@ -70,8 +70,8 @@
rb.Build(pctx, ctx, gf.path.Base(), "Build "+gf.path.Base())
}
-func (s *sdk) javaLibs(ctx android.ModuleContext) []*java.Library {
- result := []*java.Library{}
+func (s *sdk) javaLibs(ctx android.ModuleContext) []android.SdkAware {
+ result := []android.SdkAware{}
ctx.VisitDirectDeps(func(m android.Module) {
if j, ok := m.(*java.Library); ok {
result = append(result, j)
@@ -180,20 +180,12 @@
// libFoo.so : a stub library
const (
- aidlIncludeDir = "aidl"
- javaStubDir = "java"
- javaStubFileSuffix = ".jar"
nativeIncludeDir = "include"
nativeGeneratedIncludeDir = "include_gen"
nativeStubDir = "lib"
nativeStubFileSuffix = ".so"
)
-// path to the stub file of a java library. Relative to <sdk_root>/<api_dir>
-func javaStubFilePathFor(javaLib *java.Library) string {
- return filepath.Join(javaStubDir, javaLib.Name()+javaStubFileSuffix)
-}
-
// path to the stub file of a native shared library. Relative to <sdk_root>/<api_dir>
func nativeStubFilePathFor(lib archSpecificNativeLibInfo) string {
return filepath.Join(lib.archType,
@@ -231,227 +223,205 @@
return ctx.ModuleName() + "_" + memberName + string(android.SdkVersionSeparator) + version
}
-// buildAndroidBp creates the blueprint file that defines prebuilt modules for each of
-// the SDK members, and the entire sdk_snapshot module for the specified version
-// TODO(jiyong): create a meta info file (e.g. json, protobuf, etc.) instead, and convert it to
-// Android.bp in the (presumably old) branch where the snapshots will be used. This will give us
-// some flexibility to introduce backwards incompatible changes in soong.
-func (s *sdk) buildAndroidBp(ctx android.ModuleContext, version string) android.OutputPath {
- bp := newGeneratedFile(ctx, "snapshot", "Android.bp")
- bp.printfln("// This is auto-generated. DO NOT EDIT.")
- bp.printfln("")
-
- javaLibModules := s.javaLibs(ctx)
- for _, m := range javaLibModules {
- name := m.Name()
- bp.printfln("java_import {")
- bp.indent()
- bp.printfln("name: %q,", versionedSdkMemberName(ctx, name, version))
- bp.printfln("sdk_member_name: %q,", name)
- bp.printfln("jars: [%q],", javaStubFilePathFor(m))
- 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("java_import {")
- bp.indent()
- bp.printfln("name: %q,", name)
- bp.printfln("jars: [%q],", javaStubFilePathFor(m))
- bp.printfln("prefer: false,")
- bp.dedent()
- bp.printfln("}")
- bp.printfln("")
- }
-
- nativeLibInfos := s.nativeMemberInfos(ctx)
- for _, info := range nativeLibInfos {
- bp.printfln("cc_prebuilt_library_shared {")
- bp.indent()
- bp.printfln("name: %q,", versionedSdkMemberName(ctx, info.name, version))
- bp.printfln("sdk_member_name: %q,", info.name)
-
- // a function for emitting include dirs
- printExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, systemInclude bool) {
- includeDirs := nativeIncludeDirPathsFor(ctx, lib, systemInclude, info.hasArchSpecificFlags)
- if len(includeDirs) == 0 {
- return
- }
- if !systemInclude {
- bp.printfln("export_include_dirs: [")
- } else {
- bp.printfln("export_system_include_dirs: [")
- }
- bp.indent()
- for _, dir := range includeDirs {
- bp.printfln("%q,", dir)
- }
- bp.dedent()
- bp.printfln("],")
- }
-
- if !info.hasArchSpecificFlags {
- printExportedDirsForNativeLibs(info.archVariants[0], false /*systemInclude*/)
- printExportedDirsForNativeLibs(info.archVariants[0], true /*systemInclude*/)
- }
-
- bp.printfln("arch: {")
- bp.indent()
- for _, av := range info.archVariants {
- bp.printfln("%s: {", av.archType)
- bp.indent()
- bp.printfln("srcs: [%q],", nativeStubFilePathFor(av))
- if info.hasArchSpecificFlags {
- // export_* properties are added inside the arch: {<arch>: {...}} block
- printExportedDirsForNativeLibs(av, false /*systemInclude*/)
- printExportedDirsForNativeLibs(av, true /*systemInclude*/)
- }
- bp.dedent()
- bp.printfln("},") // <arch>
- }
- bp.dedent()
- bp.printfln("},") // arch
- bp.printfln("stl: \"none\",")
- bp.printfln("system_shared_libs: [],")
- bp.dedent()
- bp.printfln("}") // cc_prebuilt_library_shared
- bp.printfln("")
- }
-
- bp.printfln("sdk_snapshot {")
- bp.indent()
- bp.printfln("name: %q,", ctx.ModuleName()+string(android.SdkVersionSeparator)+version)
- if len(javaLibModules) > 0 {
- bp.printfln("java_libs: [")
- bp.indent()
- for _, m := range javaLibModules {
- bp.printfln("%q,", versionedSdkMemberName(ctx, m.Name(), version))
- }
- bp.dedent()
- bp.printfln("],") // java_libs
- }
- if len(nativeLibInfos) > 0 {
- bp.printfln("native_shared_libs: [")
- bp.indent()
- for _, info := range nativeLibInfos {
- bp.printfln("%q,", versionedSdkMemberName(ctx, info.name, version))
- }
- bp.dedent()
- bp.printfln("],") // native_shared_libs
- }
- bp.dedent()
- bp.printfln("}") // sdk_snapshot
- bp.printfln("")
-
- bp.build(pctx, ctx, nil)
- return bp.path
-}
-
// buildSnapshot is the main function in this source file. It creates rules to copy
// the contents (header files, stub libraries, etc) into the zip file.
func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
- snapshotPath := func(paths ...string) android.OutputPath {
- return android.PathForModuleOut(ctx, "snapshot").Join(ctx, paths...)
- }
+ snapshotDir := android.PathForModuleOut(ctx, "snapshot")
- var filesToZip android.Paths
- // copy src to dest and add the dest to the zip
- copy := func(src android.Path, dest android.OutputPath) {
- ctx.Build(pctx, android.BuildParams{
- Rule: android.Cp,
- Input: src,
- Output: dest,
- })
- filesToZip = append(filesToZip, dest)
+ bp := newGeneratedFile(ctx, "snapshot", "Android.bp")
+ bp.Printfln("// This is auto-generated. DO NOT EDIT.")
+ bp.Printfln("")
+
+ builder := &snapshotBuilder{
+ ctx: ctx,
+ version: "current",
+ snapshotDir: snapshotDir.OutputPath,
+ androidBpFile: bp,
+ filesToZip: []android.Path{bp.path},
}
// copy exported AIDL files and stub jar files
- for _, m := range s.javaLibs(ctx) {
- headerJars := m.HeaderJars()
- if len(headerJars) != 1 {
- panic(fmt.Errorf("there must be only one header jar from %q", m.Name()))
- }
- copy(headerJars[0], snapshotPath(javaStubFilePathFor(m)))
-
- for _, dir := range m.AidlIncludeDirs() {
- // TODO(jiyong): copy parcelable declarations only
- aidlFiles, _ := ctx.GlobWithDeps(dir.String()+"/**/*.aidl", nil)
- for _, file := range aidlFiles {
- copy(android.PathForSource(ctx, file), snapshotPath(aidlIncludeDir, file))
- }
- }
+ javaLibs := s.javaLibs(ctx)
+ for _, m := range javaLibs {
+ m.BuildSnapshot(ctx, builder)
}
// copy exported header files and stub *.so files
nativeLibInfos := s.nativeMemberInfos(ctx)
for _, info := range nativeLibInfos {
-
- // a function for emitting include dirs
- printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
- includeDirs := lib.exportedIncludeDirs
- includeDirs = append(includeDirs, lib.exportedSystemIncludeDirs...)
- if len(includeDirs) == 0 {
- return
- }
- for _, dir := range includeDirs {
- if _, gen := dir.(android.WritablePath); gen {
- // generated headers are copied via exportedDeps. See below.
- continue
- }
- targetDir := nativeIncludeDir
- if info.hasArchSpecificFlags {
- targetDir = filepath.Join(lib.archType, targetDir)
- }
-
- // TODO(jiyong) copy headers having other suffixes
- headers, _ := ctx.GlobWithDeps(dir.String()+"/**/*.h", nil)
- for _, file := range headers {
- src := android.PathForSource(ctx, file)
- dest := snapshotPath(targetDir, file)
- copy(src, dest)
- }
- }
-
- genHeaders := lib.exportedDeps
- for _, file := range genHeaders {
- targetDir := nativeGeneratedIncludeDir
- if info.hasArchSpecificFlags {
- targetDir = filepath.Join(lib.archType, targetDir)
- }
- dest := snapshotPath(targetDir, lib.name, file.Rel())
- copy(file, dest)
- }
- }
-
- if !info.hasArchSpecificFlags {
- printExportedDirCopyCommandsForNativeLibs(info.archVariants[0])
- }
-
- // for each architecture
- for _, av := range info.archVariants {
- copy(av.outputFile, snapshotPath(nativeStubFilePathFor(av)))
-
- if info.hasArchSpecificFlags {
- printExportedDirCopyCommandsForNativeLibs(av)
- }
- }
+ buildSharedNativeLibSnapshot(ctx, info, builder)
}
// generate Android.bp
- bp := s.buildAndroidBp(ctx, "current")
- filesToZip = append(filesToZip, bp)
+
+ bp.Printfln("sdk_snapshot {")
+ bp.Indent()
+ bp.Printfln("name: %q,", ctx.ModuleName()+string(android.SdkVersionSeparator)+builder.version)
+ if len(javaLibs) > 0 {
+ bp.Printfln("java_libs: [")
+ bp.Indent()
+ for _, m := range javaLibs {
+ bp.Printfln("%q,", builder.VersionedSdkMemberName(m.Name()))
+ }
+ bp.Dedent()
+ bp.Printfln("],") // java_libs
+ }
+ if len(nativeLibInfos) > 0 {
+ bp.Printfln("native_shared_libs: [")
+ bp.Indent()
+ for _, info := range nativeLibInfos {
+ bp.Printfln("%q,", builder.VersionedSdkMemberName(info.name))
+ }
+ bp.Dedent()
+ bp.Printfln("],") // native_shared_libs
+ }
+ bp.Dedent()
+ bp.Printfln("}") // sdk_snapshot
+ bp.Printfln("")
+
+ bp.build(pctx, ctx, nil)
+
+ filesToZip := builder.filesToZip
// zip them all
zipFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.zip").OutputPath
rb := android.NewRuleBuilder()
rb.Command().
BuiltTool(ctx, "soong_zip").
- FlagWithArg("-C ", snapshotPath().String()).
+ FlagWithArg("-C ", builder.snapshotDir.String()).
FlagWithRspFileInputList("-l ", filesToZip).
FlagWithOutput("-o ", zipFile)
rb.Build(pctx, ctx, "snapshot", "Building snapshot for "+ctx.ModuleName())
return zipFile
}
+
+func buildSharedNativeLibSnapshot(ctx android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder) {
+ // a function for emitting include dirs
+ printExportedDirCopyCommandsForNativeLibs := func(lib archSpecificNativeLibInfo) {
+ includeDirs := lib.exportedIncludeDirs
+ includeDirs = append(includeDirs, lib.exportedSystemIncludeDirs...)
+ if len(includeDirs) == 0 {
+ return
+ }
+ for _, dir := range includeDirs {
+ if _, gen := dir.(android.WritablePath); gen {
+ // generated headers are copied via exportedDeps. See below.
+ continue
+ }
+ targetDir := nativeIncludeDir
+ if info.hasArchSpecificFlags {
+ targetDir = filepath.Join(lib.archType, targetDir)
+ }
+
+ // TODO(jiyong) copy headers having other suffixes
+ headers, _ := ctx.GlobWithDeps(dir.String()+"/**/*.h", nil)
+ for _, file := range headers {
+ src := android.PathForSource(ctx, file)
+ dest := filepath.Join(targetDir, file)
+ builder.CopyToSnapshot(src, dest)
+ }
+ }
+
+ genHeaders := lib.exportedDeps
+ for _, file := range genHeaders {
+ targetDir := nativeGeneratedIncludeDir
+ if info.hasArchSpecificFlags {
+ targetDir = filepath.Join(lib.archType, targetDir)
+ }
+ dest := filepath.Join(targetDir, lib.name, file.Rel())
+ builder.CopyToSnapshot(file, dest)
+ }
+ }
+
+ if !info.hasArchSpecificFlags {
+ printExportedDirCopyCommandsForNativeLibs(info.archVariants[0])
+ }
+
+ // for each architecture
+ for _, av := range info.archVariants {
+ builder.CopyToSnapshot(av.outputFile, nativeStubFilePathFor(av))
+
+ if info.hasArchSpecificFlags {
+ printExportedDirCopyCommandsForNativeLibs(av)
+ }
+ }
+
+ bp := builder.AndroidBpFile()
+ bp.Printfln("cc_prebuilt_library_shared {")
+ bp.Indent()
+ bp.Printfln("name: %q,", builder.VersionedSdkMemberName(info.name))
+ bp.Printfln("sdk_member_name: %q,", info.name)
+
+ // a function for emitting include dirs
+ printExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, systemInclude bool) {
+ includeDirs := nativeIncludeDirPathsFor(ctx, lib, systemInclude, info.hasArchSpecificFlags)
+ if len(includeDirs) == 0 {
+ return
+ }
+ if !systemInclude {
+ bp.Printfln("export_include_dirs: [")
+ } else {
+ bp.Printfln("export_system_include_dirs: [")
+ }
+ bp.Indent()
+ for _, dir := range includeDirs {
+ bp.Printfln("%q,", dir)
+ }
+ bp.Dedent()
+ bp.Printfln("],")
+ }
+
+ if !info.hasArchSpecificFlags {
+ printExportedDirsForNativeLibs(info.archVariants[0], false /*systemInclude*/)
+ printExportedDirsForNativeLibs(info.archVariants[0], true /*systemInclude*/)
+ }
+
+ bp.Printfln("arch: {")
+ bp.Indent()
+ for _, av := range info.archVariants {
+ bp.Printfln("%s: {", av.archType)
+ bp.Indent()
+ bp.Printfln("srcs: [%q],", nativeStubFilePathFor(av))
+ if info.hasArchSpecificFlags {
+ // export_* properties are added inside the arch: {<arch>: {...}} block
+ printExportedDirsForNativeLibs(av, false /*systemInclude*/)
+ printExportedDirsForNativeLibs(av, true /*systemInclude*/)
+ }
+ bp.Dedent()
+ bp.Printfln("},") // <arch>
+ }
+ bp.Dedent()
+ bp.Printfln("},") // arch
+ bp.Printfln("stl: \"none\",")
+ bp.Printfln("system_shared_libs: [],")
+ bp.Dedent()
+ bp.Printfln("}") // cc_prebuilt_library_shared
+ bp.Printfln("")
+}
+
+type snapshotBuilder struct {
+ ctx android.ModuleContext
+ version string
+ snapshotDir android.OutputPath
+ filesToZip android.Paths
+ androidBpFile *generatedFile
+}
+
+func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
+ path := s.snapshotDir.Join(s.ctx, dest)
+ s.ctx.Build(pctx, android.BuildParams{
+ Rule: android.Cp,
+ Input: src,
+ Output: path,
+ })
+ s.filesToZip = append(s.filesToZip, path)
+}
+
+func (s *snapshotBuilder) AndroidBpFile() android.GeneratedSnapshotFile {
+ return s.androidBpFile
+}
+
+func (s *snapshotBuilder) VersionedSdkMemberName(unversionedName string) interface{} {
+ return versionedSdkMemberName(s.ctx, unversionedName, s.version)
+}