Propagate AconfigFiles in ModuleBase.

Aconfig file dependencies are module-independent, and properly part of
ModuleBase.

Bug: b/308625757
Test: manual

Change-Id: I38c5907d1671cc69bb198345201316ae781fdc9f
This commit is contained in:
LaMont Jones
2024-01-10 23:42:36 +00:00
parent dbc88dc4d0
commit b509938e4f
10 changed files with 164 additions and 17 deletions

View File

@@ -163,7 +163,6 @@ func TestAndroidMkCcLibrary(t *testing.T) {
entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0] entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"] makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"]
android.AssertIntEquals(t, "len(LOCAL_ACONFIG_FILES)", 1, len(makeVar))
android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/intermediate.pb") android.EnsureListContainsSuffix(t, makeVar, "my_aconfig_declarations_foo/intermediate.pb")
} }

View File

@@ -60,7 +60,6 @@ func runJavaAndroidMkTest(t *testing.T, bp string) {
entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0] entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"] makeVar := entry.EntryMap["LOCAL_ACONFIG_FILES"]
android.AssertIntEquals(t, "len(LOCAL_ACONFIG_FILES)", 1, len(makeVar))
android.EnsureListContainsSuffix(t, makeVar, "android_common/aconfig_merged.pb") android.EnsureListContainsSuffix(t, makeVar, "android_common/aconfig_merged.pb")
} }

View File

@@ -15,6 +15,10 @@
package android package android
import ( import (
"fmt"
"io"
"reflect"
"github.com/google/blueprint" "github.com/google/blueprint"
) )
@@ -45,6 +49,8 @@ type AconfigTransitiveDeclarationsInfo struct {
var AconfigTransitiveDeclarationsInfoProvider = blueprint.NewProvider[AconfigTransitiveDeclarationsInfo]() var AconfigTransitiveDeclarationsInfoProvider = blueprint.NewProvider[AconfigTransitiveDeclarationsInfo]()
// CollectDependencyAconfigFiles is used by some module types to provide finer dependency graphing than
// we can do in ModuleBase.
func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[string]Paths) { func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[string]Paths) {
if *mergedAconfigFiles == nil { if *mergedAconfigFiles == nil {
*mergedAconfigFiles = make(map[string]Paths) *mergedAconfigFiles = make(map[string]Paths)
@@ -54,7 +60,14 @@ func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[st
(*mergedAconfigFiles)[dep.Container] = append((*mergedAconfigFiles)[dep.Container], dep.IntermediateCacheOutputPath) (*mergedAconfigFiles)[dep.Container] = append((*mergedAconfigFiles)[dep.Container], dep.IntermediateCacheOutputPath)
return return
} }
if dep, _ := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); len(dep.AconfigFiles) > 0 { if dep, ok := OtherModuleProvider(ctx, module, aconfigPropagatingProviderKey); ok {
for container, v := range dep.AconfigFiles {
(*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...)
}
}
// We process these last, so that they determine the final value, eliminating any duplicates that we picked up
// from UpdateAndroidBuildActions.
if dep, ok := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); ok {
for container, v := range dep.AconfigFiles { for container, v := range dep.AconfigFiles {
(*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...) (*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...)
} }
@@ -62,7 +75,7 @@ func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[st
}) })
for container, aconfigFiles := range *mergedAconfigFiles { for container, aconfigFiles := range *mergedAconfigFiles {
(*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, container, aconfigFiles) (*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, container, aconfigFiles, false)
} }
SetProvider(ctx, AconfigTransitiveDeclarationsInfoProvider, AconfigTransitiveDeclarationsInfo{ SetProvider(ctx, AconfigTransitiveDeclarationsInfoProvider, AconfigTransitiveDeclarationsInfo{
@@ -70,7 +83,94 @@ func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[st
}) })
} }
func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths) Paths { func SetAconfigFileMkEntries(m *ModuleBase, entries *AndroidMkEntries, aconfigFiles map[string]Paths) {
setAconfigFileMkEntries(m, entries, aconfigFiles)
}
type aconfigPropagatingDeclarationsInfo struct {
AconfigFiles map[string]Paths
}
var aconfigPropagatingProviderKey = blueprint.NewProvider[aconfigPropagatingDeclarationsInfo]()
func aconfigUpdateAndroidBuildActions(ctx ModuleContext) {
mergedAconfigFiles := make(map[string]Paths)
ctx.VisitDirectDepsIgnoreBlueprint(func(module Module) {
// If any of our dependencies have aconfig declarations (directly or propagated), then merge those and provide them.
if dep, ok := OtherModuleProvider(ctx, module, AconfigDeclarationsProviderKey); ok {
mergedAconfigFiles[dep.Container] = append(mergedAconfigFiles[dep.Container], dep.IntermediateCacheOutputPath)
}
if dep, ok := OtherModuleProvider(ctx, module, aconfigPropagatingProviderKey); ok {
for container, v := range dep.AconfigFiles {
mergedAconfigFiles[container] = append(mergedAconfigFiles[container], v...)
}
}
if dep, ok := OtherModuleProvider(ctx, module, AconfigTransitiveDeclarationsInfoProvider); ok {
for container, v := range dep.AconfigFiles {
mergedAconfigFiles[container] = append(mergedAconfigFiles[container], v...)
}
}
})
// We only need to set the provider if we have aconfig files.
if len(mergedAconfigFiles) > 0 {
for container, aconfigFiles := range mergedAconfigFiles {
mergedAconfigFiles[container] = mergeAconfigFiles(ctx, container, aconfigFiles, true)
}
SetProvider(ctx, aconfigPropagatingProviderKey, aconfigPropagatingDeclarationsInfo{
AconfigFiles: mergedAconfigFiles,
})
}
}
func aconfigUpdateAndroidMkData(ctx fillInEntriesContext, mod Module, data *AndroidMkData) {
info, ok := SingletonModuleProvider(ctx, mod, aconfigPropagatingProviderKey)
// If there is no aconfigPropagatingProvider, or there are no AconfigFiles, then we are done.
if !ok || len(info.AconfigFiles) == 0 {
return
}
data.Extra = append(data.Extra, func(w io.Writer, outputFile Path) {
AndroidMkEmitAssignList(w, "LOCAL_ACONFIG_FILES", getAconfigFilePaths(mod.base(), info.AconfigFiles).Strings())
})
// If there is a Custom writer, it needs to support this provider.
if data.Custom != nil {
switch reflect.TypeOf(mod).String() {
case "*aidl.aidlApi": // writes non-custom before adding .phony
case "*android_sdk.sdkRepoHost": // doesn't go through base_rules
case "*apex.apexBundle": // aconfig_file properties written
case "*bpf.bpf": // properties written (both for module and objs)
case "*genrule.Module": // writes non-custom before adding .phony
case "*java.SystemModules": // doesn't go through base_rules
case "*phony.phony": // properties written
case "*phony.PhonyRule": // writes phony deps and acts like `.PHONY`
case "*sysprop.syspropLibrary": // properties written
default:
panic(fmt.Errorf("custom make rules do not handle aconfig files for %q (%q) module %q", ctx.ModuleType(mod), reflect.TypeOf(mod), mod))
}
}
}
func aconfigUpdateAndroidMkEntries(ctx fillInEntriesContext, mod Module, entries *[]AndroidMkEntries) {
// If there are no entries, then we can ignore this module, even if it has aconfig files.
if len(*entries) == 0 {
return
}
info, ok := SingletonModuleProvider(ctx, mod, aconfigPropagatingProviderKey)
if !ok || len(info.AconfigFiles) == 0 {
return
}
// All of the files in the module potentially depend on the aconfig flag values.
for idx, _ := range *entries {
(*entries)[idx].ExtraEntries = append((*entries)[idx].ExtraEntries,
func(ctx AndroidMkExtraEntriesContext, entries *AndroidMkEntries) {
setAconfigFileMkEntries(mod.base(), entries, info.AconfigFiles)
},
)
}
}
func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths, generateRule bool) Paths {
inputs = LastUniquePaths(inputs) inputs = LastUniquePaths(inputs)
if len(inputs) == 1 { if len(inputs) == 1 {
return Paths{inputs[0]} return Paths{inputs[0]}
@@ -78,22 +178,28 @@ func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths) Paths
output := PathForModuleOut(ctx, container, "aconfig_merged.pb") output := PathForModuleOut(ctx, container, "aconfig_merged.pb")
ctx.Build(pctx, BuildParams{ if generateRule {
Rule: mergeAconfigFilesRule, ctx.Build(pctx, BuildParams{
Description: "merge aconfig files", Rule: mergeAconfigFilesRule,
Inputs: inputs, Description: "merge aconfig files",
Output: output, Inputs: inputs,
Args: map[string]string{ Output: output,
"flags": JoinWithPrefix(inputs.Strings(), "--cache "), Args: map[string]string{
}, "flags": JoinWithPrefix(inputs.Strings(), "--cache "),
}) },
})
}
return Paths{output} return Paths{output}
} }
func SetAconfigFileMkEntries(m *ModuleBase, entries *AndroidMkEntries, aconfigFiles map[string]Paths) { func setAconfigFileMkEntries(m *ModuleBase, entries *AndroidMkEntries, aconfigFiles map[string]Paths) {
entries.AddPaths("LOCAL_ACONFIG_FILES", getAconfigFilePaths(m, aconfigFiles))
}
func getAconfigFilePaths(m *ModuleBase, aconfigFiles map[string]Paths) (paths Paths) {
// TODO(b/311155208): The default container here should be system. // TODO(b/311155208): The default container here should be system.
container := "" container := "system"
if m.SocSpecific() { if m.SocSpecific() {
container = "vendor" container = "vendor"
@@ -103,5 +209,18 @@ func SetAconfigFileMkEntries(m *ModuleBase, entries *AndroidMkEntries, aconfigFi
container = "system_ext" container = "system_ext"
} }
entries.SetPaths("LOCAL_ACONFIG_FILES", aconfigFiles[container]) paths = append(paths, aconfigFiles[container]...)
if container == "system" {
// TODO(b/311155208): Once the default container is system, we can drop this.
paths = append(paths, aconfigFiles[""]...)
}
if container != "system" {
if len(aconfigFiles[container]) == 0 && len(aconfigFiles[""]) > 0 {
// TODO(b/308625757): Either we guessed the container wrong, or the flag is misdeclared.
// For now, just include the system (aka "") container if we get here.
//fmt.Printf("container_mismatch: module=%v container=%v files=%v\n", m, container, aconfigFiles)
}
paths = append(paths, aconfigFiles[""]...)
}
return
} }

View File

@@ -859,6 +859,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *
} }
data.fillInData(ctx, mod) data.fillInData(ctx, mod)
aconfigUpdateAndroidMkData(ctx, mod.(Module), &data)
prefix := "" prefix := ""
if amod.ArchSpecific() { if amod.ArchSpecific() {
@@ -943,6 +944,7 @@ func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleIn
} }
entriesList := provider.AndroidMkEntries() entriesList := provider.AndroidMkEntries()
aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList)
// Any new or special cases here need review to verify correct propagation of license information. // Any new or special cases here need review to verify correct propagation of license information.
for _, entries := range entriesList { for _, entries := range entriesList {

View File

@@ -1777,6 +1777,11 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
return return
} }
aconfigUpdateAndroidBuildActions(ctx)
if ctx.Failed() {
return
}
// Create the set of tagged dist files after calling GenerateAndroidBuildActions // Create the set of tagged dist files after calling GenerateAndroidBuildActions
// as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the // as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
// output paths being set which must be done before or during // output paths being set which must be done before or during

View File

@@ -1121,6 +1121,7 @@ func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod blueprint.Modul
} }
entriesList := p.AndroidMkEntries() entriesList := p.AndroidMkEntries()
aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList)
for i, _ := range entriesList { for i, _ := range entriesList {
entriesList[i].fillInEntries(ctx, mod) entriesList[i].fillInEntries(ctx, mod)
} }
@@ -1136,6 +1137,7 @@ func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod blueprint.Module)
} }
data := p.AndroidMk() data := p.AndroidMk()
data.fillInData(ctx, mod) data.fillInData(ctx, mod)
aconfigUpdateAndroidMkData(ctx, mod.(Module), &data)
return data return data
} }

View File

@@ -124,6 +124,10 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st
pathForSymbol := filepath.Join("$(PRODUCT_OUT)", "apex", apexBundleName, fi.installDir) pathForSymbol := filepath.Join("$(PRODUCT_OUT)", "apex", apexBundleName, fi.installDir)
modulePath := pathForSymbol modulePath := pathForSymbol
fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath) fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath)
// AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
for _, extra := range apexAndroidMkData.Extra {
extra(w, fi.builtFile)
}
// For non-flattend APEXes, the merged notice file is attached to the APEX itself. // For non-flattend APEXes, the merged notice file is attached to the APEX itself.
// We don't need to have notice file for the individual modules in it. Otherwise, // We don't need to have notice file for the individual modules in it. Otherwise,
@@ -229,6 +233,7 @@ func (a *apexBundle) writeRequiredModules(w io.Writer, moduleNames []string) {
func (a *apexBundle) androidMkForType() android.AndroidMkData { func (a *apexBundle) androidMkForType() android.AndroidMkData {
return android.AndroidMkData{ return android.AndroidMkData{
// While we do not provide a value for `Extra`, AconfigUpdateAndroidMkData may add some, which we must honor.
Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) {
moduleNames := []string{} moduleNames := []string{}
if a.installable() { if a.installable() {
@@ -269,6 +274,10 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", a.overridableProperties.Overrides) android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", a.overridableProperties.Overrides)
a.writeRequiredModules(w, moduleNames) a.writeRequiredModules(w, moduleNames)
// AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
for _, extra := range data.Extra {
extra(w, a.outputFile)
}
fmt.Fprintln(w, "include $(BUILD_PREBUILT)") fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String()) fmt.Fprintln(w, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())

View File

@@ -231,6 +231,10 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData {
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base()) fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
fmt.Fprintln(w, localModulePath) fmt.Fprintln(w, localModulePath)
// AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
for _, extra := range data.Extra {
extra(w, nil)
}
fmt.Fprintln(w, "include $(BUILD_PREBUILT)") fmt.Fprintln(w, "include $(BUILD_PREBUILT)")
fmt.Fprintln(w) fmt.Fprintln(w)
} }

View File

@@ -68,6 +68,10 @@ func (p *phony) AndroidMk() android.AndroidMkData {
fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES :=", fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES :=",
strings.Join(p.targetRequiredModuleNames, " ")) strings.Join(p.targetRequiredModuleNames, " "))
} }
// AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
for _, extra := range data.Extra {
extra(w, nil)
}
fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)") fmt.Fprintln(w, "include $(BUILD_PHONY_PACKAGE)")
}, },
} }

View File

@@ -345,6 +345,10 @@ func (m *syspropLibrary) AndroidMk() android.AndroidMkData {
fmt.Fprintln(w, "LOCAL_MODULE :=", m.Name()) fmt.Fprintln(w, "LOCAL_MODULE :=", m.Name())
fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\n") fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\n")
fmt.Fprintf(w, "LOCAL_MODULE_TAGS := optional\n") fmt.Fprintf(w, "LOCAL_MODULE_TAGS := optional\n")
// AconfigUpdateAndroidMkData may have added elements to Extra. Process them here.
for _, extra := range data.Extra {
extra(w, nil)
}
fmt.Fprintf(w, "include $(BUILD_SYSTEM)/base_rules.mk\n\n") fmt.Fprintf(w, "include $(BUILD_SYSTEM)/base_rules.mk\n\n")
fmt.Fprintf(w, "$(LOCAL_BUILT_MODULE): %s\n", m.checkApiFileTimeStamp.String()) fmt.Fprintf(w, "$(LOCAL_BUILT_MODULE): %s\n", m.checkApiFileTimeStamp.String())
fmt.Fprintf(w, "\ttouch $@\n\n") fmt.Fprintf(w, "\ttouch $@\n\n")