summaryrefslogtreecommitdiff
path: root/sdk/update.go
diff options
context:
space:
mode:
Diffstat (limited to 'sdk/update.go')
-rw-r--r--sdk/update.go252
1 files changed, 151 insertions, 101 deletions
diff --git a/sdk/update.go b/sdk/update.go
index 000d200ca..3bd63369d 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -17,6 +17,7 @@ package sdk
import (
"fmt"
"path/filepath"
+ "reflect"
"strings"
"github.com/google/blueprint/proptools"
@@ -28,34 +29,37 @@ import (
var pctx = android.NewPackageContext("android/soong/sdk")
+type generatedContents struct {
+ content strings.Builder
+ indentLevel int
+}
+
// generatedFile abstracts operations for writing contents into a file and emit a build rule
// for the file.
type generatedFile struct {
- path android.OutputPath
- content strings.Builder
- indentLevel int
+ generatedContents
+ path android.OutputPath
}
func newGeneratedFile(ctx android.ModuleContext, path ...string) *generatedFile {
return &generatedFile{
- path: android.PathForModuleOut(ctx, path...).OutputPath,
- indentLevel: 0,
+ path: android.PathForModuleOut(ctx, path...).OutputPath,
}
}
-func (gf *generatedFile) Indent() {
- gf.indentLevel++
+func (gc *generatedContents) Indent() {
+ gc.indentLevel++
}
-func (gf *generatedFile) Dedent() {
- gf.indentLevel--
+func (gc *generatedContents) Dedent() {
+ gc.indentLevel--
}
-func (gf *generatedFile) Printfln(format string, args ...interface{}) {
+func (gc *generatedContents) Printfln(format string, args ...interface{}) {
// ninja consumes newline characters in rspfile_content. Prevent it by
// 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...)
+ fmt.Fprintf(&(gc.content), strings.Repeat(" ", gc.indentLevel)+format+"\\n", args...)
}
func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderContext, implicits android.Paths) {
@@ -239,15 +243,18 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
snapshotDir := android.PathForModuleOut(ctx, "snapshot")
bp := newGeneratedFile(ctx, "snapshot", "Android.bp")
- bp.Printfln("// This is auto-generated. DO NOT EDIT.")
- bp.Printfln("")
+
+ bpFile := &bpFile{
+ modules: make(map[string]*bpModule),
+ }
builder := &snapshotBuilder{
- ctx: ctx,
- version: "current",
- snapshotDir: snapshotDir.OutputPath,
- filesToZip: []android.Path{bp.path},
- androidBpFile: bp,
+ ctx: ctx,
+ version: "current",
+ snapshotDir: snapshotDir.OutputPath,
+ filesToZip: []android.Path{bp.path},
+ bpFile: bpFile,
+ prebuiltModules: make(map[string]*bpModule),
}
s.builderForTests = builder
@@ -269,41 +276,37 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
buildSharedNativeLibSnapshot(ctx, info, builder)
}
- // generate Android.bp
+ for _, unversioned := range builder.prebuiltOrder {
+ // Copy the unversioned module so it can be modified to make it versioned.
+ versioned := unversioned.copy()
+ name := versioned.properties["name"].(string)
+ versioned.setProperty("name", builder.versionedSdkMemberName(name))
+ versioned.insertAfter("name", "sdk_member_name", name)
+ bpFile.AddModule(versioned)
+
+ // Set prefer: false - this is not strictly required as that is the default.
+ unversioned.insertAfter("name", "prefer", false)
+ bpFile.AddModule(unversioned)
+ }
- bp.Printfln("sdk_snapshot {")
- bp.Indent()
- bp.Printfln("name: %q,", ctx.ModuleName()+string(android.SdkVersionSeparator)+builder.version)
+ // Create the snapshot module.
+ snapshotName := ctx.ModuleName() + string(android.SdkVersionSeparator) + builder.version
+ snapshotModule := bpFile.newModule("sdk_snapshot")
+ snapshotModule.AddProperty("name", snapshotName)
if len(s.properties.Java_libs) > 0 {
- bp.Printfln("java_libs: [")
- bp.Indent()
- for _, m := range s.properties.Java_libs {
- bp.Printfln("%q,", builder.VersionedSdkMemberName(m))
- }
- bp.Dedent()
- bp.Printfln("],") // java_libs
+ snapshotModule.AddProperty("java_libs", builder.versionedSdkMemberNames(s.properties.Java_libs))
}
if len(s.properties.Stubs_sources) > 0 {
- bp.Printfln("stubs_sources: [")
- bp.Indent()
- for _, m := range s.properties.Stubs_sources {
- bp.Printfln("%q,", builder.VersionedSdkMemberName(m))
- }
- bp.Dedent()
- bp.Printfln("],") // stubs_sources
+ snapshotModule.AddProperty("stubs_sources", builder.versionedSdkMemberNames(s.properties.Stubs_sources))
}
if len(s.properties.Native_shared_libs) > 0 {
- bp.Printfln("native_shared_libs: [")
- bp.Indent()
- for _, m := range s.properties.Native_shared_libs {
- bp.Printfln("%q,", builder.VersionedSdkMemberName(m))
- }
- bp.Dedent()
- bp.Printfln("],") // native_shared_libs
+ snapshotModule.AddProperty("native_shared_libs", builder.versionedSdkMemberNames(s.properties.Native_shared_libs))
}
- bp.Dedent()
- bp.Printfln("}") // sdk_snapshot
- bp.Printfln("")
+ bpFile.AddModule(snapshotModule)
+
+ // generate Android.bp
+ bp = newGeneratedFile(ctx, "snapshot", "Android.bp")
+ generateBpContents(&bp.generatedContents, bpFile)
bp.build(pctx, ctx, nil)
@@ -351,8 +354,61 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
return outputZipFile
}
+func generateBpContents(contents *generatedContents, bpFile *bpFile) {
+ contents.Printfln("// This is auto-generated. DO NOT EDIT.")
+ for _, bpModule := range bpFile.order {
+ contents.Printfln("")
+ contents.Printfln("%s {", bpModule.moduleType)
+ outputPropertySet(contents, &bpModule.bpPropertySet)
+ contents.Printfln("}")
+ }
+ contents.Printfln("")
+}
+
+func outputPropertySet(contents *generatedContents, set *bpPropertySet) {
+ contents.Indent()
+ for _, name := range set.order {
+ value := set.properties[name]
+
+ reflectedValue := reflect.ValueOf(value)
+ t := reflectedValue.Type()
+
+ kind := t.Kind()
+ switch kind {
+ case reflect.Slice:
+ length := reflectedValue.Len()
+ if length > 1 {
+ contents.Printfln("%s: [", name)
+ contents.Indent()
+ for i := 0; i < length; i = i + 1 {
+ contents.Printfln("%q,", reflectedValue.Index(i).Interface())
+ }
+ contents.Dedent()
+ contents.Printfln("],")
+ } else if length == 0 {
+ contents.Printfln("%s: [],", name)
+ } else {
+ contents.Printfln("%s: [%q],", name, reflectedValue.Index(0).Interface())
+ }
+ case reflect.Bool:
+ contents.Printfln("%s: %t,", name, reflectedValue.Bool())
+
+ case reflect.Ptr:
+ contents.Printfln("%s: {", name)
+ outputPropertySet(contents, reflectedValue.Interface().(*bpPropertySet))
+ contents.Printfln("},")
+
+ default:
+ contents.Printfln("%s: %q,", name, value)
+ }
+ }
+ contents.Dedent()
+}
+
func (s *sdk) GetAndroidBpContentsForTests() string {
- return s.builderForTests.androidBpFile.content.String()
+ contents := &generatedContents{}
+ generateBpContents(contents, s.builderForTests.bpFile)
+ return contents.content.String()
}
func buildSharedNativeLibSnapshot(ctx android.ModuleContext, info *nativeLibInfo, builder android.SnapshotBuilder) {
@@ -406,81 +462,57 @@ func buildSharedNativeLibSnapshot(ctx android.ModuleContext, info *nativeLibInfo
}
}
- info.generatePrebuiltLibrary(ctx, builder, true)
-
- // 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.
- info.generatePrebuiltLibrary(ctx, builder, false)
+ info.generatePrebuiltLibrary(ctx, builder)
}
-func (info *nativeLibInfo) generatePrebuiltLibrary(ctx android.ModuleContext, builder android.SnapshotBuilder, versioned bool) {
- bp := builder.AndroidBpFile()
- bp.Printfln("cc_prebuilt_library_shared {")
- bp.Indent()
- name := info.name
- if versioned {
- bp.Printfln("name: %q,", builder.VersionedSdkMemberName(name))
- bp.Printfln("sdk_member_name: %q,", name)
- } else {
- bp.Printfln("name: %q,", name)
- bp.Printfln("prefer: false,")
- }
+func (info *nativeLibInfo) generatePrebuiltLibrary(ctx android.ModuleContext, builder android.SnapshotBuilder) {
// a function for emitting include dirs
- printExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, systemInclude bool) {
+ addExportedDirsForNativeLibs := func(lib archSpecificNativeLibInfo, properties android.BpPropertySet, systemInclude bool) {
includeDirs := nativeIncludeDirPathsFor(ctx, lib, systemInclude, info.hasArchSpecificFlags)
if len(includeDirs) == 0 {
return
}
+ var propertyName string
if !systemInclude {
- bp.Printfln("export_include_dirs: [")
+ propertyName = "export_include_dirs"
} else {
- bp.Printfln("export_system_include_dirs: [")
+ propertyName = "export_system_include_dirs"
}
- bp.Indent()
- for _, dir := range includeDirs {
- bp.Printfln("%q,", dir)
- }
- bp.Dedent()
- bp.Printfln("],")
+ properties.AddProperty(propertyName, includeDirs)
}
+ pbm := builder.AddPrebuiltModule(info.name, "cc_prebuilt_library_shared")
+
if !info.hasArchSpecificFlags {
- printExportedDirsForNativeLibs(info.archVariants[0], false /*systemInclude*/)
- printExportedDirsForNativeLibs(info.archVariants[0], true /*systemInclude*/)
+ addExportedDirsForNativeLibs(info.archVariants[0], pbm, false /*systemInclude*/)
+ addExportedDirsForNativeLibs(info.archVariants[0], pbm, true /*systemInclude*/)
}
- bp.Printfln("arch: {")
- bp.Indent()
+ archProperties := pbm.AddPropertySet("arch")
for _, av := range info.archVariants {
- bp.Printfln("%s: {", av.archType)
- bp.Indent()
- bp.Printfln("srcs: [%q],", nativeStubFilePathFor(av))
+ archTypeProperties := archProperties.AddPropertySet(av.archType)
+ archTypeProperties.AddProperty("srcs", []string{nativeStubFilePathFor(av)})
if info.hasArchSpecificFlags {
// export_* properties are added inside the arch: {<arch>: {...}} block
- printExportedDirsForNativeLibs(av, false /*systemInclude*/)
- printExportedDirsForNativeLibs(av, true /*systemInclude*/)
+ addExportedDirsForNativeLibs(av, archTypeProperties, false /*systemInclude*/)
+ addExportedDirsForNativeLibs(av, archTypeProperties, 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("")
+ pbm.AddProperty("stl", "none")
+ pbm.AddProperty("system_shared_libs", []string{})
}
type snapshotBuilder struct {
- ctx android.ModuleContext
- version string
- snapshotDir android.OutputPath
- androidBpFile *generatedFile
- filesToZip android.Paths
- zipsToMerge android.Paths
+ ctx android.ModuleContext
+ version string
+ snapshotDir android.OutputPath
+ bpFile *bpFile
+ filesToZip android.Paths
+ zipsToMerge android.Paths
+
+ prebuiltModules map[string]*bpModule
+ prebuiltOrder []*bpModule
}
func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
@@ -512,10 +544,28 @@ func (s *snapshotBuilder) UnzipToSnapshot(zipPath android.Path, destDir string)
s.zipsToMerge = append(s.zipsToMerge, tmpZipPath)
}
-func (s *snapshotBuilder) AndroidBpFile() android.GeneratedSnapshotFile {
- return s.androidBpFile
+func (s *snapshotBuilder) AddPrebuiltModule(name string, moduleType string) android.BpModule {
+ if s.prebuiltModules[name] != nil {
+ panic(fmt.Sprintf("Duplicate module detected, module %s has already been added", name))
+ }
+
+ m := s.bpFile.newModule(moduleType)
+ m.AddProperty("name", name)
+
+ s.prebuiltModules[name] = m
+ s.prebuiltOrder = append(s.prebuiltOrder, m)
+ return m
}
-func (s *snapshotBuilder) VersionedSdkMemberName(unversionedName string) interface{} {
+// Get a versioned name appropriate for the SDK snapshot version being taken.
+func (s *snapshotBuilder) versionedSdkMemberName(unversionedName string) string {
return versionedSdkMemberName(s.ctx, unversionedName, s.version)
}
+
+func (s *snapshotBuilder) versionedSdkMemberNames(members []string) []string {
+ var references []string = nil
+ for _, m := range members {
+ references = append(references, s.versionedSdkMemberName(m))
+ }
+ return references
+}