Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/build/build/soong/filesystem/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 7 kB image not shown  

Quelle  logical_partition.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright (C) 2021 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package filesystem

import (
 "fmt"
 "strconv"

 "github.com/google/blueprint/proptools"

 "android/soong/android"
)

func init() {
 android.RegisterModuleType("logical_partition", logicalPartitionFactory)
}

type logicalPartition struct {
 android.ModuleBase

 properties logicalPartitionProperties

 output     android.Path
 installDir android.InstallPath
}

type logicalPartitionProperties struct {
 // Set the name of the output. Defaults to <module_name>.img.
 Stem *string

 // Total size of the logical partition. If set to "auto", total size is automatically
 // calcaulted as minimum.
 Size *string

 // List of partitions for default group. Default group has no size limit and automatically
 // minimized when creating an image.
 Default_group []partitionProperties

 // List of groups. A group defines a fixed sized region. It can host one or more logical
 // partitions and their total size is limited by the size of the group they are in.
 Groups []groupProperties

 // Whether the output is a sparse image or not. Default is false.
 Sparse *bool
}

type groupProperties struct {
 // Name of the partition group. Can't be "default"; use default_group instead.
 Name *string

 // Size of the partition group
 Size *string

 // List of logical partitions in this group
 Partitions []partitionProperties
}

type partitionProperties struct {
 // Name of the partition
 Name *string

 // Filesystem that is placed on the partition
 Filesystem *string `android:"path"`
}

// logical_partition is a partition image which has one or more logical partitions in it.
func logicalPartitionFactory() android.Module {
 module := &logicalPartition{}
 module.AddProperties(&module.properties)
 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
 return module
}

func (l *logicalPartition) DepsMutator(ctx android.BottomUpMutatorContext) {
 // do nothing
}

func (l *logicalPartition) installFileName() string {
 return proptools.StringDefault(l.properties.Stem, l.BaseModuleName()+".img")
}

func (l *logicalPartition) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 builder := android.NewRuleBuilder(pctx, ctx).SandboxDisabled()

 // Sparse the filesystem images and calculate their sizes
 sparseImages := make(map[string]android.Path)
 sparseImageSizes := make(map[string]android.Path)

 sparsePartitions := func(partitions []partitionProperties) {
  for _, part := range partitions {
   if part.Filesystem == nil {
    continue
   }
   sparseImg, sizeTxt := sparseFilesystem(ctx, part, builder)
   pName := proptools.String(part.Name)
   sparseImages[pName] = sparseImg
   sparseImageSizes[pName] = sizeTxt
  }
 }

 for _, group := range l.properties.Groups {
  sparsePartitions(group.Partitions)
 }

 sparsePartitions(l.properties.Default_group)

 cmd := builder.Command().BuiltTool("lpmake")

 size := proptools.String(l.properties.Size)
 if size == "" {
  ctx.PropertyErrorf("size", "must be set")
 } else if _, err := strconv.Atoi(size); err != nil && size != "auto" {
  ctx.PropertyErrorf("size", `must be a number or "auto"`)
 }
 cmd.FlagWithArg("--device-size=", size)

 // TODO(jiyong): consider supporting A/B devices. Then we need to adjust num of slots.
 cmd.FlagWithArg("--metadata-slots=", "2")
 cmd.FlagWithArg("--metadata-size=", "65536")

 if proptools.Bool(l.properties.Sparse) {
  cmd.Flag("--sparse")
 }

 groupNames := make(map[string]bool)
 partitionNames := make(map[string]bool)

 addPartitionsToGroup := func(partitions []partitionProperties, gName string) {
  for _, part := range partitions {
   pName := proptools.String(part.Name)
   if pName == "" {
    ctx.PropertyErrorf("groups.partitions.name", "must be set")
   }
   if _, ok := partitionNames[pName]; ok {
    ctx.PropertyErrorf("groups.partitions.name", "already exists")
   } else {
    partitionNames[pName] = true
   }
   // Get size of the partition by reading the -size.txt file
   var pSize string
   if size, hasSize := sparseImageSizes[pName]; hasSize {
    pSize = fmt.Sprintf("$(cat %s)", size)
   } else {
    pSize = "0"
   }
   cmd.FlagWithArg("--partition=", fmt.Sprintf("%s:readonly:%s:%s", pName, pSize, gName))
   if image, hasImage := sparseImages[pName]; hasImage {
    cmd.FlagWithInput("--image="+pName+"=", image)
   }
  }
 }

 addPartitionsToGroup(l.properties.Default_group, "default")

 for _, group := range l.properties.Groups {
  gName := proptools.String(group.Name)
  if gName == "" {
   ctx.PropertyErrorf("groups.name", "must be set")
  } else if gName == "default" {
   ctx.PropertyErrorf("groups.name", `can't use "default" as a group name. Use default_group instead`)
  }
  if _, ok := groupNames[gName]; ok {
   ctx.PropertyErrorf("group.name", "already exists")
  } else {
   groupNames[gName] = true
  }
  gSize := proptools.String(group.Size)
  if gSize == "" {
   ctx.PropertyErrorf("groups.size", "must be set")
  }
  if _, err := strconv.Atoi(gSize); err != nil {
   ctx.PropertyErrorf("groups.size", "must be a number")
  }
  cmd.FlagWithArg("--group=", gName+":"+gSize)

  addPartitionsToGroup(group.Partitions, gName)
 }

 output := android.PathForModuleOut(ctx, l.installFileName())
 cmd.FlagWithOutput("--output=", output)

 builder.Build("build_logical_partition", fmt.Sprintf("Creating %s", l.BaseModuleName()))

 l.installDir = android.PathForModuleInstall(ctx, "etc")
 ctx.InstallFile(l.installDir, l.installFileName(), output)

 ctx.SetOutputFiles([]android.Path{output}, "")
 l.output = output

 setCommonFilesystemInfo(ctx, l)
}

// Add a rule that converts the filesystem for the given partition to the given rule builder. The
// path to the sparse file and the text file having the size of the partition are returned.
func sparseFilesystem(ctx android.ModuleContext, p partitionProperties, builder *android.RuleBuilder) (android.Path, android.Path) {
 img := android.PathForModuleSrc(ctx, *p.Filesystem)
 name := proptools.String(p.Name)

 sparseImg := android.PathForModuleOut(ctx, name+".img")
 builder.Temporary(sparseImg)
 builder.Command().BuiltTool("img2simg").Input(img).Output(sparseImg)

 sizeTxt := android.PathForModuleOut(ctx, name+"-size.txt")
 builder.Temporary(sizeTxt)
 builder.Command().BuiltTool("sparse_img").Flag("--get_partition_size").Input(sparseImg).
  Text("| ").Text("tr").FlagWithArg("-d ", "'\n'").
  Text("> ").Output(sizeTxt)

 return sparseImg, sizeTxt
}

var _ android.AndroidMkEntriesProvider = (*logicalPartition)(nil)

// Implements android.AndroidMkEntriesProvider
func (l *logicalPartition) AndroidMkEntries() []android.AndroidMkEntries {
 return []android.AndroidMkEntries{android.AndroidMkEntries{
  Class:      "ETC",
  OutputFile: android.OptionalPathForPath(l.output),
  ExtraEntries: []android.AndroidMkExtraEntriesFunc{
   func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
    entries.SetString("LOCAL_MODULE_PATH", l.installDir.String())
    entries.SetString("LOCAL_INSTALLED_MODULE_STEM", l.installFileName())
   },
  },
 }}
}

var _ Filesystem = (*logicalPartition)(nil)

func (l *logicalPartition) OutputPath() android.Path {
 return l.output
}

func (l *logicalPartition) SignedOutputPath() android.Path {
 return nil // logical partition is not signed by itself
}

[Dauer der Verarbeitung: 0.20 Sekunden, vorverarbeitet 2026-06-28]