Reapply "Add super.img to android_device"
This reverts commit 4173c5bed6853af9a6ca44b1dcfafb6bb5848b43.
This resubmission moves the check that all partitions are specified
to execution time, because on aosp-main-future-without-vendor
BUILDING_VENDOR_IMAGE is false while
BOARD_GOOGLE_DYNAMIC_PARTITIONS_PARTITION_LIST still lists the vendor
partition.
Bug: 376727180
Test: Presubmits
Change-Id: I485574c98ba78f7eea3878135ff71fd6da94587e
diff --git a/filesystem/android_device.go b/filesystem/android_device.go
index 6a939e8..3d9f8b9 100644
--- a/filesystem/android_device.go
+++ b/filesystem/android_device.go
@@ -25,6 +25,8 @@
)
type PartitionNameProperties struct {
+ // Name of the super partition filesystem module
+ Super_partition_name *string
// Name of the boot partition filesystem module
Boot_partition_name *string
// Name of the vendor boot partition filesystem module
@@ -86,6 +88,11 @@
blueprint.BaseDependencyTag
}
+type superPartitionDepTagType struct {
+ blueprint.BaseDependencyTag
+}
+
+var superPartitionDepTag superPartitionDepTagType
var filesystemDepTag partitionDepTagType
func (a *androidDevice) DepsMutator(ctx android.BottomUpMutatorContext) {
@@ -95,6 +102,9 @@
}
}
+ if a.partitionProps.Super_partition_name != nil {
+ ctx.AddDependency(ctx.Module(), superPartitionDepTag, *a.partitionProps.Super_partition_name)
+ }
addDependencyIfDefined(a.partitionProps.Boot_partition_name)
addDependencyIfDefined(a.partitionProps.Init_boot_partition_name)
addDependencyIfDefined(a.partitionProps.Vendor_boot_partition_name)
@@ -134,6 +144,44 @@
func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) {
a.buildTargetFilesZip(ctx)
var deps []android.Path
+ if proptools.String(a.partitionProps.Super_partition_name) != "" {
+ superImage := ctx.GetDirectDepWithTag(*a.partitionProps.Super_partition_name, superPartitionDepTag)
+ if info, ok := android.OtherModuleProvider(ctx, superImage, SuperImageProvider); ok {
+ assertUnset := func(prop *string, propName string) {
+ if prop != nil && *prop != "" {
+ ctx.PropertyErrorf(propName, "Cannot be set because it's already part of the super image")
+ }
+ }
+ for _, subPartitionType := range android.SortedKeys(info.SubImageInfo) {
+ switch subPartitionType {
+ case "system":
+ assertUnset(a.partitionProps.System_partition_name, "system_partition_name")
+ case "system_ext":
+ assertUnset(a.partitionProps.System_ext_partition_name, "system_ext_partition_name")
+ case "system_dlkm":
+ assertUnset(a.partitionProps.System_dlkm_partition_name, "system_dlkm_partition_name")
+ case "system_other":
+ // TODO
+ case "product":
+ assertUnset(a.partitionProps.Product_partition_name, "product_partition_name")
+ case "vendor":
+ assertUnset(a.partitionProps.Vendor_partition_name, "vendor_partition_name")
+ case "vendor_dlkm":
+ assertUnset(a.partitionProps.Vendor_dlkm_partition_name, "vendor_dlkm_partition_name")
+ case "odm":
+ assertUnset(a.partitionProps.Odm_partition_name, "odm_partition_name")
+ case "odm_dlkm":
+ assertUnset(a.partitionProps.Odm_dlkm_partition_name, "odm_dlkm_partition_name")
+ default:
+ ctx.ModuleErrorf("Unsupported sub-partition of super partition: %q", subPartitionType)
+ }
+ }
+
+ deps = append(deps, info.SuperImage)
+ } else {
+ ctx.ModuleErrorf("Expected super image dep to provide SuperImageProvider")
+ }
+ }
ctx.VisitDirectDepsWithTag(filesystemDepTag, func(m android.Module) {
imageOutput, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider)
if !ok {
diff --git a/filesystem/super_image.go b/filesystem/super_image.go
index 0f8f614..d8c7345 100644
--- a/filesystem/super_image.go
+++ b/filesystem/super_image.go
@@ -21,6 +21,7 @@
"strings"
"android/soong/android"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -88,6 +89,17 @@
Odm_dlkm_partition *string
}
+type SuperImageInfo struct {
+ // The built super.img file, which contains the sub-partitions
+ SuperImage android.Path
+
+ // Mapping from the sub-partition type to its re-exported FileSystemInfo providers from the
+ // sub-partitions.
+ SubImageInfo map[string]FilesystemInfo
+}
+
+var SuperImageProvider = blueprint.NewProvider[SuperImageInfo]()
+
func SuperImageFactory() android.Module {
module := &superImage{}
module.AddProperties(&module.properties, &module.partitionProps)
@@ -99,12 +111,12 @@
blueprint.BaseDependencyTag
}
-var superImageDepTag superImageDepTagType
+var subImageDepTag superImageDepTagType
func (s *superImage) DepsMutator(ctx android.BottomUpMutatorContext) {
addDependencyIfDefined := func(dep *string) {
if dep != nil {
- ctx.AddDependency(ctx.Module(), superImageDepTag, proptools.String(dep))
+ ctx.AddDependency(ctx.Module(), subImageDepTag, proptools.String(dep))
}
}
@@ -120,7 +132,7 @@
}
func (s *superImage) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- miscInfo, deps := s.buildMiscInfo(ctx)
+ miscInfo, deps, subImageInfos := s.buildMiscInfo(ctx)
builder := android.NewRuleBuilder(pctx, ctx)
output := android.PathForModuleOut(ctx, s.installFileName())
lpMake := ctx.Config().HostToolPath(ctx, "lpmake")
@@ -133,14 +145,19 @@
Implicits(deps).
Output(output)
builder.Build("build_super_image", fmt.Sprintf("Creating super image %s", s.BaseModuleName()))
+ android.SetProvider(ctx, SuperImageProvider, SuperImageInfo{
+ SuperImage: output,
+ SubImageInfo: subImageInfos,
+ })
ctx.SetOutputFiles([]android.Path{output}, "")
+ ctx.CheckbuildFile(output)
}
func (s *superImage) installFileName() string {
return s.BaseModuleName() + ".img"
}
-func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, android.Paths) {
+func (s *superImage) buildMiscInfo(ctx android.ModuleContext) (android.Path, android.Paths, map[string]FilesystemInfo) {
var miscInfoString strings.Builder
addStr := func(name string, value string) {
miscInfoString.WriteString(name)
@@ -164,6 +181,11 @@
addStr("super_"+groupInfo.Name+"_group_size", groupInfo.GroupSize)
addStr("super_"+groupInfo.Name+"_partition_list", strings.Join(groupInfo.PartitionList, " "))
}
+ initialPartitionListLen := len(partitionList)
+ partitionList = android.SortedUniqueStrings(partitionList)
+ if len(partitionList) != initialPartitionListLen {
+ ctx.ModuleErrorf("Duplicate partitions found in the partition_groups property")
+ }
addStr("super_partition_groups", strings.Join(groups, " "))
addStr("dynamic_partition_list", strings.Join(partitionList, " "))
@@ -172,65 +194,80 @@
addStr("ab_update", strconv.FormatBool(proptools.Bool(s.properties.Ab_update)))
addStr("build_non_sparse_super_partition", strconv.FormatBool(!proptools.Bool(s.properties.Sparse)))
- partitionToImagePath := make(map[string]string)
- nameToPartition := make(map[string]string)
- var systemOtherPartitionNameNeeded string
- addEntryToPartitionToName := func(p string, s *string) {
- if proptools.String(s) != "" {
- nameToPartition[*s] = p
+ subImageInfo := make(map[string]FilesystemInfo)
+ var deps android.Paths
+
+ missingPartitionErrorMessage := ""
+ handleSubPartition := func(partitionType string, name *string) {
+ if proptools.String(name) == "" {
+ missingPartitionErrorMessage += fmt.Sprintf("%s image listed in partition groups, but its module was not specified. ", partitionType)
+ return
}
+ mod := ctx.GetDirectDepWithTag(*name, subImageDepTag)
+ if mod == nil {
+ ctx.ModuleErrorf("Could not get dep %q", *name)
+ return
+ }
+ info, ok := android.OtherModuleProvider(ctx, mod, FilesystemProvider)
+ if !ok {
+ ctx.ModuleErrorf("Expected dep %q to provide FilesystemInfo", *name)
+ return
+ }
+ addStr(partitionType+"_image", info.Output.String())
+ deps = append(deps, info.Output)
+ if _, ok := subImageInfo[partitionType]; ok {
+ ctx.ModuleErrorf("Already set subimageInfo for %q", partitionType)
+ }
+ subImageInfo[partitionType] = info
}
// Build partitionToImagePath, because system partition may need system_other
// partition image path
for _, p := range partitionList {
- if _, ok := nameToPartition[p]; ok {
- continue
- }
switch p {
case "system":
- addEntryToPartitionToName(p, s.partitionProps.System_partition)
- systemOtherPartitionNameNeeded = proptools.String(s.partitionProps.System_other_partition)
+ handleSubPartition("system", s.partitionProps.System_partition)
+ // TODO: add system_other to deps after it can be generated
+ //getFsInfo("system_other", s.partitionProps.System_other_partition, &subImageInfo.System_other)
case "system_dlkm":
- addEntryToPartitionToName(p, s.partitionProps.System_dlkm_partition)
+ handleSubPartition("system_dlkm", s.partitionProps.System_dlkm_partition)
case "system_ext":
- addEntryToPartitionToName(p, s.partitionProps.System_ext_partition)
+ handleSubPartition("system_ext", s.partitionProps.System_ext_partition)
case "product":
- addEntryToPartitionToName(p, s.partitionProps.Product_partition)
+ handleSubPartition("product", s.partitionProps.Product_partition)
case "vendor":
- addEntryToPartitionToName(p, s.partitionProps.Vendor_partition)
+ handleSubPartition("vendor", s.partitionProps.Vendor_partition)
case "vendor_dlkm":
- addEntryToPartitionToName(p, s.partitionProps.Vendor_dlkm_partition)
+ handleSubPartition("vendor_dlkm", s.partitionProps.Vendor_dlkm_partition)
case "odm":
- addEntryToPartitionToName(p, s.partitionProps.Odm_partition)
+ handleSubPartition("odm", s.partitionProps.Odm_partition)
case "odm_dlkm":
- addEntryToPartitionToName(p, s.partitionProps.Odm_dlkm_partition)
+ handleSubPartition("odm_dlkm", s.partitionProps.Odm_dlkm_partition)
default:
- ctx.ModuleErrorf("current partition %s not a super image supported partition", p)
+ ctx.ModuleErrorf("partition %q is not a super image supported partition", p)
}
}
- var deps android.Paths
- ctx.VisitDirectDeps(func(m android.Module) {
- if p, ok := nameToPartition[m.Name()]; ok {
- if output, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider); ok {
- partitionToImagePath[p] = output.DefaultOutputFiles[0].String()
- deps = append(deps, output.DefaultOutputFiles[0])
- }
- } else if systemOtherPartitionNameNeeded != "" && m.Name() == systemOtherPartitionNameNeeded {
- if output, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider); ok {
- partitionToImagePath["system_other"] = output.DefaultOutputFiles[0].String()
- // TODO: add system_other to deps after it can be generated
- // deps = append(deps, output.DefaultOutputFiles[0])
- }
- }
- })
-
- for _, p := range android.SortedKeys(partitionToImagePath) {
- addStr(p+"_image", partitionToImagePath[p])
+ // Delay the error message until execution time because on aosp-main-future-without-vendor,
+ // BUILDING_VENDOR_IMAGE is false so we don't get the vendor image, but it's still listed in
+ // BOARD_GOOGLE_DYNAMIC_PARTITIONS_PARTITION_LIST.
+ missingPartitionErrorMessageFile := android.PathForModuleOut(ctx, "missing_partition_error.txt")
+ if missingPartitionErrorMessage != "" {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.ErrorRule,
+ Output: missingPartitionErrorMessageFile,
+ Args: map[string]string{
+ "error": missingPartitionErrorMessage,
+ },
+ })
+ } else {
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.Touch,
+ Output: missingPartitionErrorMessageFile,
+ })
}
miscInfo := android.PathForModuleOut(ctx, "misc_info.txt")
- android.WriteFileRule(ctx, miscInfo, miscInfoString.String())
- return miscInfo, deps
+ android.WriteFileRule(ctx, miscInfo, miscInfoString.String(), missingPartitionErrorMessageFile)
+ return miscInfo, deps, subImageInfo
}
diff --git a/fsgen/filesystem_creator.go b/fsgen/filesystem_creator.go
index a070e01..9d61a60 100644
--- a/fsgen/filesystem_creator.go
+++ b/fsgen/filesystem_creator.go
@@ -161,13 +161,14 @@
f.properties.Vbmeta_partition_names = append(f.properties.Vbmeta_partition_names, x.partitionName)
}
+ var superImageSubpartitions []string
if buildingSuperImage(partitionVars) {
- createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars)
+ superImageSubpartitions = createSuperImage(ctx, finalSoongGeneratedPartitions, partitionVars)
f.properties.Super_image = ":" + generatedModuleNameForPartition(ctx.Config(), "super")
}
ctx.Config().Get(fsGenStateOnceKey).(*FsGenState).soongGeneratedPartitions = finalSoongGeneratedPartitions
- f.createDeviceModule(ctx, finalSoongGeneratedPartitions, f.properties.Vbmeta_module_names)
+ f.createDeviceModule(ctx, finalSoongGeneratedPartitions, f.properties.Vbmeta_module_names, superImageSubpartitions)
}
func generatedModuleName(cfg android.Config, suffix string) string {
@@ -206,6 +207,7 @@
ctx android.LoadHookContext,
generatedPartitionTypes []string,
vbmetaPartitions []string,
+ superImageSubPartitions []string,
) {
baseProps := &struct {
Name *string
@@ -217,19 +219,22 @@
// Currently, only the system and system_ext partition module is created.
partitionProps := &filesystem.PartitionNameProperties{}
- if android.InList("system", generatedPartitionTypes) {
+ if f.properties.Super_image != "" {
+ partitionProps.Super_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "super"))
+ }
+ if android.InList("system", generatedPartitionTypes) && !android.InList("system", superImageSubPartitions) {
partitionProps.System_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
}
- if android.InList("system_ext", generatedPartitionTypes) {
+ if android.InList("system_ext", generatedPartitionTypes) && !android.InList("system_ext", superImageSubPartitions) {
partitionProps.System_ext_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
}
- if android.InList("vendor", generatedPartitionTypes) {
+ if android.InList("vendor", generatedPartitionTypes) && !android.InList("vendor", superImageSubPartitions) {
partitionProps.Vendor_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
}
- if android.InList("product", generatedPartitionTypes) {
+ if android.InList("product", generatedPartitionTypes) && !android.InList("product", superImageSubPartitions) {
partitionProps.Product_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
}
- if android.InList("odm", generatedPartitionTypes) {
+ if android.InList("odm", generatedPartitionTypes) && !android.InList("odm", superImageSubPartitions) {
partitionProps.Odm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm"))
}
if android.InList("userdata", f.properties.Generated_partition_types) {
@@ -238,13 +243,13 @@
if android.InList("recovery", f.properties.Generated_partition_types) {
partitionProps.Recovery_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "recovery"))
}
- if android.InList("system_dlkm", f.properties.Generated_partition_types) {
+ if android.InList("system_dlkm", f.properties.Generated_partition_types) && !android.InList("system_dlkm", superImageSubPartitions) {
partitionProps.System_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
}
- if android.InList("vendor_dlkm", f.properties.Generated_partition_types) {
+ if android.InList("vendor_dlkm", f.properties.Generated_partition_types) && !android.InList("vendor_dlkm", superImageSubPartitions) {
partitionProps.Vendor_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
}
- if android.InList("odm_dlkm", f.properties.Generated_partition_types) {
+ if android.InList("odm_dlkm", f.properties.Generated_partition_types) && !android.InList("odm_dlkm", superImageSubPartitions) {
partitionProps.Odm_dlkm_partition_name = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
}
if f.properties.Boot_image != "" {
diff --git a/fsgen/super_img.go b/fsgen/super_img.go
index a36f614..5994fb6 100644
--- a/fsgen/super_img.go
+++ b/fsgen/super_img.go
@@ -27,7 +27,7 @@
return partitionVars.ProductBuildSuperPartition
}
-func createSuperImage(ctx android.LoadHookContext, partitions []string, partitionVars android.PartitionVariables) {
+func createSuperImage(ctx android.LoadHookContext, partitions []string, partitionVars android.PartitionVariables) []string {
baseProps := &struct {
Name *string
}{
@@ -59,34 +59,45 @@
}
superImageProps.Partition_groups = partitionGroupsInfo
+ var superImageSubpartitions []string
partitionNameProps := &filesystem.SuperImagePartitionNameProperties{}
if android.InList("system", partitions) {
partitionNameProps.System_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system"))
+ superImageSubpartitions = append(superImageSubpartitions, "system")
}
if android.InList("system_ext", partitions) {
partitionNameProps.System_ext_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_ext"))
+ superImageSubpartitions = append(superImageSubpartitions, "system_ext")
}
if android.InList("system_dlkm", partitions) {
partitionNameProps.System_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_dlkm"))
+ superImageSubpartitions = append(superImageSubpartitions, "system_dlkm")
}
if android.InList("system_other", partitions) {
partitionNameProps.System_other_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "system_other"))
+ superImageSubpartitions = append(superImageSubpartitions, "system_other")
}
if android.InList("product", partitions) {
partitionNameProps.Product_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "product"))
+ superImageSubpartitions = append(superImageSubpartitions, "product")
}
if android.InList("vendor", partitions) {
partitionNameProps.Vendor_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor"))
+ superImageSubpartitions = append(superImageSubpartitions, "vendor")
}
if android.InList("vendor_dlkm", partitions) {
partitionNameProps.Vendor_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "vendor_dlkm"))
+ superImageSubpartitions = append(superImageSubpartitions, "vendor_dlkm")
}
if android.InList("odm", partitions) {
partitionNameProps.Odm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm"))
+ superImageSubpartitions = append(superImageSubpartitions, "odm")
}
if android.InList("odm_dlkm", partitions) {
partitionNameProps.Odm_dlkm_partition = proptools.StringPtr(generatedModuleNameForPartition(ctx.Config(), "odm_dlkm"))
+ superImageSubpartitions = append(superImageSubpartitions, "odm_dlkm")
}
ctx.CreateModule(filesystem.SuperImageFactory, baseProps, superImageProps, partitionNameProps)
+ return superImageSubpartitions
}