Add framework for using provider on AndroidMKEntries

In the context of incremental soong, the inter-module communication
through AndroidMkEntries and AndroidMkData should be changed to
through the real provider.

This change adds the framework for the provider(AndroidMkInfoProvider).
A module will set its AndroidMkInfoProvider, which includes what's
in its AndroidMkEntries method, to be used in translateAndroidMkModule.

This change also changes module type vbmeta to use
AndroidMKInfoProvider.

The next step is to replace the AndroidMkEntries methods of all the
other module types to set the AndroidMkInfoProvider.

Test: m with tests and CI
Bug: 357907638
Change-Id: Icfd1363f97d31548bb78c6615e0f7076b22dcbe4
This commit is contained in:
mrziwang
2024-09-03 15:12:51 -07:00
parent 28b806c9eb
commit 1842097928
3 changed files with 601 additions and 22 deletions

View File

@@ -187,6 +187,20 @@ func aconfigUpdateAndroidMkEntries(ctx fillInEntriesContext, mod Module, entries
}
}
func aconfigUpdateAndroidMkInfos(ctx fillInEntriesContext, mod Module, infos *AndroidMkProviderInfo) {
info, ok := OtherModuleProvider(ctx, mod, AconfigPropagatingProviderKey)
if !ok || len(info.AconfigFiles) == 0 {
return
}
// All of the files in the module potentially depend on the aconfig flag values.
infos.PrimaryInfo.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
if len(infos.ExtraInfo) > 0 {
for _, ei := range (*infos).ExtraInfo {
ei.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles))
}
}
}
func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths, generateRule bool) Paths {
inputs = SortedUniquePaths(inputs)
if len(inputs) == 1 {

View File

@@ -806,6 +806,11 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs
// Additional cases here require review for correct license propagation to make.
var err error
if info, ok := ctx.otherModuleProvider(mod, AndroidMkInfoProvider); ok {
androidMkEntriesInfos := info.(*AndroidMkProviderInfo)
err = translateAndroidMkEntriesInfoModule(ctx, w, moduleInfoJSONs, mod, androidMkEntriesInfos)
} else {
switch x := mod.(type) {
case AndroidMkDataProvider:
err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x)
@@ -816,6 +821,7 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs
default:
// Not exported to make so no make variables to set.
}
}
if err != nil {
return err
@@ -1063,3 +1069,564 @@ func AndroidMkEmitAssignList(w io.Writer, varName string, lists ...[]string) {
}
fmt.Fprintln(w)
}
type AndroidMkProviderInfo struct {
PrimaryInfo AndroidMkInfo
ExtraInfo []AndroidMkInfo
}
type AndroidMkInfo struct {
// Android.mk class string, e.g. EXECUTABLES, JAVA_LIBRARIES, ETC
Class string
// Optional suffix to append to the module name. Useful when a module wants to return multiple
// AndroidMkEntries objects. For example, when a java_library returns an additional entry for
// its hostdex sub-module, this SubName field is set to "-hostdex" so that it can have a
// different name than the parent's.
SubName string
// If set, this value overrides the base module name. SubName is still appended.
OverrideName string
// Dist files to output
DistFiles TaggedDistFiles
// The output file for Kati to process and/or install. If absent, the module is skipped.
OutputFile OptionalPath
// If true, the module is skipped and does not appear on the final Android-<product name>.mk
// file. Useful when a module needs to be skipped conditionally.
Disabled bool
// The postprocessing mk file to include, e.g. $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk
// If not set, $(BUILD_SYSTEM)/prebuilt.mk is used.
Include string
// Required modules that need to be built and included in the final build output when building
// this module.
Required []string
// Required host modules that need to be built and included in the final build output when
// building this module.
Host_required []string
// Required device modules that need to be built and included in the final build output when
// building this module.
Target_required []string
HeaderStrings []string
FooterStrings []string
// A map that holds the up-to-date Make variable values. Can be accessed from tests.
EntryMap map[string][]string
// A list of EntryMap keys in insertion order. This serves a few purposes:
// 1. Prevents churns. Golang map doesn't provide consistent iteration order, so without this,
// the outputted Android-*.mk file may change even though there have been no content changes.
// 2. Allows modules to refer to other variables, like LOCAL_BAR_VAR := $(LOCAL_FOO_VAR),
// without worrying about the variables being mixed up in the actual mk file.
// 3. Makes troubleshooting and spotting errors easier.
EntryOrder []string
}
// TODO: rename it to AndroidMkEntriesProvider after AndroidMkEntriesProvider interface is gone.
var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]()
func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
mod blueprint.Module, providerInfo *AndroidMkProviderInfo) error {
if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) {
return nil
}
// Deep copy the provider info since we need to modify the info later
info := deepCopyAndroidMkProviderInfo(providerInfo)
aconfigUpdateAndroidMkInfos(ctx, mod.(Module), &info)
// Any new or special cases here need review to verify correct propagation of license information.
info.PrimaryInfo.fillInEntries(ctx, mod)
info.PrimaryInfo.write(w)
if len(info.ExtraInfo) > 0 {
for _, ei := range info.ExtraInfo {
ei.fillInEntries(ctx, mod)
ei.write(w)
}
}
if !info.PrimaryInfo.disabled() {
if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
*moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON)
}
}
return nil
}
// Utility funcs to manipulate Android.mk variable entries.
// SetString sets a Make variable with the given name to the given value.
func (a *AndroidMkInfo) SetString(name, value string) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = []string{value}
}
// SetPath sets a Make variable with the given name to the given path string.
func (a *AndroidMkInfo) SetPath(name string, path Path) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = []string{path.String()}
}
// SetOptionalPath sets a Make variable with the given name to the given path string if it is valid.
// It is a no-op if the given path is invalid.
func (a *AndroidMkInfo) SetOptionalPath(name string, path OptionalPath) {
if path.Valid() {
a.SetPath(name, path.Path())
}
}
// AddPath appends the given path string to a Make variable with the given name.
func (a *AndroidMkInfo) AddPath(name string, path Path) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = append(a.EntryMap[name], path.String())
}
// AddOptionalPath appends the given path string to a Make variable with the given name if it is
// valid. It is a no-op if the given path is invalid.
func (a *AndroidMkInfo) AddOptionalPath(name string, path OptionalPath) {
if path.Valid() {
a.AddPath(name, path.Path())
}
}
// SetPaths sets a Make variable with the given name to a slice of the given path strings.
func (a *AndroidMkInfo) SetPaths(name string, paths Paths) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = paths.Strings()
}
// SetOptionalPaths sets a Make variable with the given name to a slice of the given path strings
// only if there are a non-zero amount of paths.
func (a *AndroidMkInfo) SetOptionalPaths(name string, paths Paths) {
if len(paths) > 0 {
a.SetPaths(name, paths)
}
}
// AddPaths appends the given path strings to a Make variable with the given name.
func (a *AndroidMkInfo) AddPaths(name string, paths Paths) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
}
// SetBoolIfTrue sets a Make variable with the given name to true if the given flag is true.
// It is a no-op if the given flag is false.
func (a *AndroidMkInfo) SetBoolIfTrue(name string, flag bool) {
if flag {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = []string{"true"}
}
}
// SetBool sets a Make variable with the given name to if the given bool flag value.
func (a *AndroidMkInfo) SetBool(name string, flag bool) {
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
if flag {
a.EntryMap[name] = []string{"true"}
} else {
a.EntryMap[name] = []string{"false"}
}
}
// AddStrings appends the given strings to a Make variable with the given name.
func (a *AndroidMkInfo) AddStrings(name string, value ...string) {
if len(value) == 0 {
return
}
if _, ok := a.EntryMap[name]; !ok {
a.EntryOrder = append(a.EntryOrder, name)
}
a.EntryMap[name] = append(a.EntryMap[name], value...)
}
// AddCompatibilityTestSuites adds the supplied test suites to the EntryMap, with special handling
// for partial MTS and MCTS test suites.
func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) {
// M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
// To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
// we add the full test suite to our list.
if PrefixInList(suites, "mts-") && !InList("mts", suites) {
suites = append(suites, "mts")
}
if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
suites = append(suites, "mcts")
}
a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...)
}
func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
helperInfo := AndroidMkInfo{
EntryMap: make(map[string][]string),
}
amod := mod.(Module)
base := amod.base()
name := base.BaseModuleName()
if a.OverrideName != "" {
name = a.OverrideName
}
if a.Include == "" {
a.Include = "$(BUILD_PREBUILT)"
}
a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...)
a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
for _, distString := range a.GetDistForGoals(ctx, mod) {
a.HeaderStrings = append(a.HeaderStrings, distString)
}
a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS) # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod)))
// Collect make variable assignment entries.
helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
helperInfo.SetString("LOCAL_MODULE", name+a.SubName)
helperInfo.SetString("LOCAL_MODULE_CLASS", a.Class)
helperInfo.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
helperInfo.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
helperInfo.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
helperInfo.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod))
// If the install rule was generated by Soong tell Make about it.
info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
if len(info.KatiInstalls) > 0 {
// Assume the primary install file is last since it probably needs to depend on any other
// installed files. If that is not the case we can add a method to specify the primary
// installed file.
helperInfo.SetPath("LOCAL_SOONG_INSTALLED_MODULE", info.KatiInstalls[len(info.KatiInstalls)-1].to)
helperInfo.SetString("LOCAL_SOONG_INSTALL_PAIRS", info.KatiInstalls.BuiltInstalled())
helperInfo.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", info.KatiSymlinks.InstallPaths().Paths())
} else {
// Soong may not have generated the install rule also when `no_full_install: true`.
// Mark this module as uninstallable in order to prevent Make from creating an
// install rule there.
helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install))
}
if len(info.TestData) > 0 {
helperInfo.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...)
}
if am, ok := mod.(ApexModule); ok {
helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
}
archStr := base.Arch().ArchType.String()
host := false
switch base.Os().Class {
case Host:
if base.Target().HostCross {
// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
if base.Arch().ArchType != Common {
helperInfo.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
}
} else {
// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
if base.Arch().ArchType != Common {
helperInfo.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
}
}
host = true
case Device:
// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
if base.Arch().ArchType != Common {
if base.Target().NativeBridge {
hostArchStr := base.Target().NativeBridgeHostArchName
if hostArchStr != "" {
helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
}
} else {
helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
}
}
if !base.InVendorRamdisk() {
helperInfo.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths)
}
if len(info.VintfFragmentsPaths) > 0 {
helperInfo.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths)
}
helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
helperInfo.SetString("LOCAL_VENDOR_MODULE", "true")
}
helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
if base.commonProperties.Owner != nil {
helperInfo.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
}
}
if host {
makeOs := base.Os().String()
if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
makeOs = "linux"
}
helperInfo.SetString("LOCAL_MODULE_HOST_OS", makeOs)
helperInfo.SetString("LOCAL_IS_HOST_MODULE", "true")
}
prefix := ""
if base.ArchSpecific() {
switch base.Os().Class {
case Host:
if base.Target().HostCross {
prefix = "HOST_CROSS_"
} else {
prefix = "HOST_"
}
case Device:
prefix = "TARGET_"
}
if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType {
prefix = "2ND_" + prefix
}
}
if licenseMetadata, ok := OtherModuleProvider(ctx, mod, LicenseMetadataProvider); ok {
helperInfo.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath)
}
if _, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
helperInfo.SetBool("LOCAL_SOONG_MODULE_INFO_JSON", true)
}
a.mergeEntries(&helperInfo)
// Write to footer.
a.FooterStrings = append([]string{"include " + a.Include}, a.FooterStrings...)
}
// This method merges the entries to helperInfo, then replaces a's EntryMap and
// EntryOrder with helperInfo's
func (a *AndroidMkInfo) mergeEntries(helperInfo *AndroidMkInfo) {
for _, extraEntry := range a.EntryOrder {
if v, ok := helperInfo.EntryMap[extraEntry]; ok {
v = append(v, a.EntryMap[extraEntry]...)
} else {
helperInfo.EntryMap[extraEntry] = a.EntryMap[extraEntry]
helperInfo.EntryOrder = append(helperInfo.EntryOrder, extraEntry)
}
}
a.EntryOrder = helperInfo.EntryOrder
a.EntryMap = helperInfo.EntryMap
}
func (a *AndroidMkInfo) disabled() bool {
return a.Disabled || !a.OutputFile.Valid()
}
// write flushes the AndroidMkEntries's in-struct data populated by AndroidMkEntries into the
// given Writer object.
func (a *AndroidMkInfo) write(w io.Writer) {
if a.disabled() {
return
}
combinedHeaderString := strings.Join(a.HeaderStrings, "\n")
combinedFooterString := strings.Join(a.FooterStrings, "\n")
w.Write([]byte(combinedHeaderString))
for _, name := range a.EntryOrder {
AndroidMkEmitAssignList(w, name, a.EntryMap[name])
}
w.Write([]byte(combinedFooterString))
}
// Compute the list of Make strings to declare phony goals and dist-for-goals
// calls from the module's dist and dists properties.
func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint.Module) []string {
distContributions := a.getDistContributions(ctx, mod)
if distContributions == nil {
return nil
}
return generateDistContributionsForMake(distContributions)
}
// Compute the contributions that the module makes to the dist.
func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod blueprint.Module) *distContributions {
amod := mod.(Module).base()
name := amod.BaseModuleName()
// Collate the set of associated tag/paths available for copying to the dist.
// Start with an empty (nil) set.
var availableTaggedDists TaggedDistFiles
// Then merge in any that are provided explicitly by the module.
if a.DistFiles != nil {
// Merge the DistFiles into the set.
availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
}
// If no paths have been provided for the DefaultDistTag and the output file is
// valid then add that as the default dist path.
if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
}
info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
// If the distFiles created by GenerateTaggedDistFiles contains paths for the
// DefaultDistTag then that takes priority so delete any existing paths.
if _, ok := info.DistFiles[DefaultDistTag]; ok {
delete(availableTaggedDists, DefaultDistTag)
}
// Finally, merge the distFiles created by GenerateTaggedDistFiles.
availableTaggedDists = availableTaggedDists.merge(info.DistFiles)
if len(availableTaggedDists) == 0 {
// Nothing dist-able for this module.
return nil
}
// Collate the contributions this module makes to the dist.
distContributions := &distContributions{}
if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
distContributions.licenseMetadataFile = info.LicenseMetadataFile
}
// Iterate over this module's dist structs, merged from the dist and dists properties.
for _, dist := range amod.Dists() {
// Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
goals := strings.Join(dist.Targets, " ")
// Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
var tag string
if dist.Tag == nil {
// If the dist struct does not specify a tag, use the default output files tag.
tag = DefaultDistTag
} else {
tag = *dist.Tag
}
// Get the paths of the output files to be dist'd, represented by the tag.
// Can be an empty list.
tagPaths := availableTaggedDists[tag]
if len(tagPaths) == 0 {
// Nothing to dist for this tag, continue to the next dist.
continue
}
if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
errorMessage := "%s: Cannot apply dest/suffix for more than one dist " +
"file for %q goals tag %q in module %s. The list of dist files, " +
"which should have a single element, is:\n%s"
panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths))
}
copiesForGoals := distContributions.getCopiesForGoals(goals)
// Iterate over each path adding a copy instruction to copiesForGoals
for _, path := range tagPaths {
// It's possible that the Path is nil from errant modules. Be defensive here.
if path == nil {
tagName := "default" // for error message readability
if dist.Tag != nil {
tagName = *dist.Tag
}
panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
}
dest := filepath.Base(path.String())
if dist.Dest != nil {
var err error
if dest, err = validateSafePath(*dist.Dest); err != nil {
// This was checked in ModuleBase.GenerateBuildActions
panic(err)
}
}
ext := filepath.Ext(dest)
suffix := ""
if dist.Suffix != nil {
suffix = *dist.Suffix
}
productString := ""
if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product {
productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct())
}
if suffix != "" || productString != "" {
dest = strings.TrimSuffix(dest, ext) + suffix + productString + ext
}
if dist.Dir != nil {
var err error
if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
// This was checked in ModuleBase.GenerateBuildActions
panic(err)
}
}
copiesForGoals.addCopyInstruction(path, dest)
}
}
return distContributions
}
func deepCopyAndroidMkProviderInfo(providerInfo *AndroidMkProviderInfo) AndroidMkProviderInfo {
info := AndroidMkProviderInfo{
PrimaryInfo: deepCopyAndroidMkInfo(&providerInfo.PrimaryInfo),
}
if len(providerInfo.ExtraInfo) > 0 {
for _, i := range providerInfo.ExtraInfo {
info.ExtraInfo = append(info.ExtraInfo, deepCopyAndroidMkInfo(&i))
}
}
return info
}
func deepCopyAndroidMkInfo(mkinfo *AndroidMkInfo) AndroidMkInfo {
info := AndroidMkInfo{
Class: mkinfo.Class,
SubName: mkinfo.SubName,
OverrideName: mkinfo.OverrideName,
// There is no modification on DistFiles or OutputFile, so no need to
// make their deep copy.
DistFiles: mkinfo.DistFiles,
OutputFile: mkinfo.OutputFile,
Disabled: mkinfo.Disabled,
Include: mkinfo.Include,
Required: deepCopyStringSlice(mkinfo.Required),
Host_required: deepCopyStringSlice(mkinfo.Host_required),
Target_required: deepCopyStringSlice(mkinfo.Target_required),
HeaderStrings: deepCopyStringSlice(mkinfo.HeaderStrings),
FooterStrings: deepCopyStringSlice(mkinfo.FooterStrings),
EntryOrder: deepCopyStringSlice(mkinfo.EntryOrder),
}
info.EntryMap = make(map[string][]string)
for k, v := range mkinfo.EntryMap {
info.EntryMap[k] = deepCopyStringSlice(v)
}
return info
}
func deepCopyStringSlice(original []string) []string {
result := make([]string, len(original))
copy(result, original)
return result
}

View File

@@ -213,6 +213,7 @@ func (v *vbmeta) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.InstallFile(v.installDir, v.installFileName(), v.output)
ctx.SetOutputFiles([]android.Path{v.output}, "")
android.SetProvider(ctx, android.AndroidMkInfoProvider, v.prepareAndroidMKProviderInfo())
}
// Returns the embedded shell command that prints the rollback index
@@ -265,20 +266,17 @@ func (v *vbmeta) extractPublicKeys(ctx android.ModuleContext) map[string]android
return result
}
var _ android.AndroidMkEntriesProvider = (*vbmeta)(nil)
// Implements android.AndroidMkEntriesProvider
func (v *vbmeta) AndroidMkEntries() []android.AndroidMkEntries {
return []android.AndroidMkEntries{android.AndroidMkEntries{
func (v *vbmeta) prepareAndroidMKProviderInfo() *android.AndroidMkProviderInfo {
providerData := android.AndroidMkProviderInfo{
PrimaryInfo: android.AndroidMkInfo{
Class: "ETC",
OutputFile: android.OptionalPathForPath(v.output),
ExtraEntries: []android.AndroidMkExtraEntriesFunc{
func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
entries.SetString("LOCAL_MODULE_PATH", v.installDir.String())
entries.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName())
EntryMap: make(map[string][]string),
},
},
}}
}
providerData.PrimaryInfo.SetString("LOCAL_MODULE_PATH", v.installDir.String())
providerData.PrimaryInfo.SetString("LOCAL_INSTALLED_MODULE_STEM", v.installFileName())
return &providerData
}
var _ Filesystem = (*vbmeta)(nil)