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:
parent
dbc88dc4d0
commit
b509938e4f
10 changed files with 164 additions and 17 deletions
|
@ -163,7 +163,6 @@ func TestAndroidMkCcLibrary(t *testing.T) {
|
|||
entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ func runJavaAndroidMkTest(t *testing.T, bp string) {
|
|||
entry := android.AndroidMkEntriesForTest(t, result.TestContext, module)[0]
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
package android
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
)
|
||||
|
||||
|
@ -45,6 +49,8 @@ type AconfigTransitiveDeclarationsInfo struct {
|
|||
|
||||
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) {
|
||||
if *mergedAconfigFiles == nil {
|
||||
*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)
|
||||
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 {
|
||||
(*mergedAconfigFiles)[container] = append((*mergedAconfigFiles)[container], v...)
|
||||
}
|
||||
|
@ -62,7 +75,7 @@ func CollectDependencyAconfigFiles(ctx ModuleContext, mergedAconfigFiles *map[st
|
|||
})
|
||||
|
||||
for container, aconfigFiles := range *mergedAconfigFiles {
|
||||
(*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, container, aconfigFiles)
|
||||
(*mergedAconfigFiles)[container] = mergeAconfigFiles(ctx, container, aconfigFiles, false)
|
||||
}
|
||||
|
||||
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)
|
||||
if len(inputs) == 1 {
|
||||
return Paths{inputs[0]}
|
||||
|
@ -78,22 +178,28 @@ func mergeAconfigFiles(ctx ModuleContext, container string, inputs Paths) Paths
|
|||
|
||||
output := PathForModuleOut(ctx, container, "aconfig_merged.pb")
|
||||
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: mergeAconfigFilesRule,
|
||||
Description: "merge aconfig files",
|
||||
Inputs: inputs,
|
||||
Output: output,
|
||||
Args: map[string]string{
|
||||
"flags": JoinWithPrefix(inputs.Strings(), "--cache "),
|
||||
},
|
||||
})
|
||||
if generateRule {
|
||||
ctx.Build(pctx, BuildParams{
|
||||
Rule: mergeAconfigFilesRule,
|
||||
Description: "merge aconfig files",
|
||||
Inputs: inputs,
|
||||
Output: output,
|
||||
Args: map[string]string{
|
||||
"flags": JoinWithPrefix(inputs.Strings(), "--cache "),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
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.
|
||||
container := ""
|
||||
container := "system"
|
||||
|
||||
if m.SocSpecific() {
|
||||
container = "vendor"
|
||||
|
@ -103,5 +209,18 @@ func SetAconfigFileMkEntries(m *ModuleBase, entries *AndroidMkEntries, aconfigFi
|
|||
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
|
||||
}
|
||||
|
|
|
@ -859,6 +859,7 @@ func translateAndroidModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *
|
|||
}
|
||||
|
||||
data.fillInData(ctx, mod)
|
||||
aconfigUpdateAndroidMkData(ctx, mod.(Module), &data)
|
||||
|
||||
prefix := ""
|
||||
if amod.ArchSpecific() {
|
||||
|
@ -943,6 +944,7 @@ func translateAndroidMkEntriesModule(ctx SingletonContext, w io.Writer, moduleIn
|
|||
}
|
||||
|
||||
entriesList := provider.AndroidMkEntries()
|
||||
aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList)
|
||||
|
||||
// Any new or special cases here need review to verify correct propagation of license information.
|
||||
for _, entries := range entriesList {
|
||||
|
|
|
@ -1777,6 +1777,11 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
|
|||
return
|
||||
}
|
||||
|
||||
aconfigUpdateAndroidBuildActions(ctx)
|
||||
if ctx.Failed() {
|
||||
return
|
||||
}
|
||||
|
||||
// Create the set of tagged dist files after calling GenerateAndroidBuildActions
|
||||
// as GenerateTaggedDistFiles() calls OutputFiles(tag) and so relies on the
|
||||
// output paths being set which must be done before or during
|
||||
|
|
|
@ -1121,6 +1121,7 @@ func AndroidMkEntriesForTest(t *testing.T, ctx *TestContext, mod blueprint.Modul
|
|||
}
|
||||
|
||||
entriesList := p.AndroidMkEntries()
|
||||
aconfigUpdateAndroidMkEntries(ctx, mod.(Module), &entriesList)
|
||||
for i, _ := range entriesList {
|
||||
entriesList[i].fillInEntries(ctx, mod)
|
||||
}
|
||||
|
@ -1136,6 +1137,7 @@ func AndroidMkDataForTest(t *testing.T, ctx *TestContext, mod blueprint.Module)
|
|||
}
|
||||
data := p.AndroidMk()
|
||||
data.fillInData(ctx, mod)
|
||||
aconfigUpdateAndroidMkData(ctx, mod.(Module), &data)
|
||||
return data
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,10 @@ func (a *apexBundle) androidMkForFiles(w io.Writer, apexBundleName, moduleDir st
|
|||
pathForSymbol := filepath.Join("$(PRODUCT_OUT)", "apex", apexBundleName, fi.installDir)
|
||||
modulePath := pathForSymbol
|
||||
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.
|
||||
// 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 {
|
||||
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) {
|
||||
moduleNames := []string{}
|
||||
if a.installable() {
|
||||
|
@ -269,6 +274,10 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
|
|||
|
||||
android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", a.overridableProperties.Overrides)
|
||||
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, "ALL_MODULES.$(my_register_name).BUNDLE :=", a.bundleModuleFile.String())
|
||||
|
|
|
@ -231,6 +231,10 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData {
|
|||
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base())
|
||||
fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC")
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -68,6 +68,10 @@ func (p *phony) AndroidMk() android.AndroidMkData {
|
|||
fmt.Fprintln(w, "LOCAL_TARGET_REQUIRED_MODULES :=",
|
||||
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)")
|
||||
},
|
||||
}
|
||||
|
|
|
@ -345,6 +345,10 @@ func (m *syspropLibrary) AndroidMk() android.AndroidMkData {
|
|||
fmt.Fprintln(w, "LOCAL_MODULE :=", m.Name())
|
||||
fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\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, "$(LOCAL_BUILT_MODULE): %s\n", m.checkApiFileTimeStamp.String())
|
||||
fmt.Fprintf(w, "\ttouch $@\n\n")
|
||||
|
|
Loading…
Reference in a new issue