Merge "Allow walkPayloadDeps visitor to control walk flow"

This commit is contained in:
Paul Duffin
2020-04-01 17:54:04 +00:00
committed by Gerrit Code Review
2 changed files with 32 additions and 17 deletions

View File

@@ -1791,9 +1791,13 @@ func (c *flattenedApexContext) InstallBypassMake() bool {
return true return true
} }
// Function called while walking an APEX's payload dependencies.
//
// Return true if the `to` module should be visited, false otherwise.
type payloadDepsCallback func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool
// Visit dependencies that contributes to the payload of this APEX // Visit dependencies that contributes to the payload of this APEX
func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext, func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext, do payloadDepsCallback) {
do func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool)) {
ctx.WalkDeps(func(child, parent android.Module) bool { ctx.WalkDeps(func(child, parent android.Module) bool {
am, ok := child.(android.ApexModule) am, ok := child.(android.ApexModule)
if !ok || !am.CanHaveApexVariants() { if !ok || !am.CanHaveApexVariants() {
@@ -1803,22 +1807,18 @@ func (a *apexBundle) walkPayloadDeps(ctx android.ModuleContext,
// Check for the direct dependencies that contribute to the payload // Check for the direct dependencies that contribute to the payload
if dt, ok := ctx.OtherModuleDependencyTag(child).(dependencyTag); ok { if dt, ok := ctx.OtherModuleDependencyTag(child).(dependencyTag); ok {
if dt.payload { if dt.payload {
do(ctx, parent, am, false /* externalDep */) return do(ctx, parent, am, false /* externalDep */)
return true
} }
// As soon as the dependency graph crosses the APEX boundary, don't go further.
return false return false
} }
// Check for the indirect dependencies if it is considered as part of the APEX // Check for the indirect dependencies if it is considered as part of the APEX
if am.ApexName() != "" { if am.ApexName() != "" {
do(ctx, parent, am, false /* externalDep */) return do(ctx, parent, am, false /* externalDep */)
return true
} }
do(ctx, parent, am, true /* externalDep */) return do(ctx, parent, am, true /* externalDep */)
// As soon as the dependency graph crosses the APEX boundary, don't go further.
return false
}) })
} }
@@ -1848,28 +1848,36 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
return return
} }
a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) { a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if externalDep {
// As soon as the dependency graph crosses the APEX boundary, don't go further.
return false
}
apexName := ctx.ModuleName() apexName := ctx.ModuleName()
fromName := ctx.OtherModuleName(from) fromName := ctx.OtherModuleName(from)
toName := ctx.OtherModuleName(to) toName := ctx.OtherModuleName(to)
if externalDep || to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) { if to.AvailableFor(apexName) || whitelistedApexAvailable(apexName, toName) {
return return true
} }
message := "" message := ""
for _, m := range ctx.GetWalkPath()[1:] { for _, m := range ctx.GetWalkPath()[1:] {
message = fmt.Sprintf("%s\n -> %s", message, m.String()) message = fmt.Sprintf("%s\n -> %s", message, m.String())
} }
ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, message) ctx.ModuleErrorf("%q requires %q that is not available for the APEX. Dependency path:%s", fromName, toName, message)
// Visit this module's dependencies to check and report any issues with their availability.
return true
}) })
} }
// Collects the list of module names that directly or indirectly contributes to the payload of this APEX // Collects the list of module names that directly or indirectly contributes to the payload of this APEX
func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) { func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) {
a.depInfos = make(map[string]depInfo) a.depInfos = make(map[string]depInfo)
a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) { a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if from.Name() == to.Name() { if from.Name() == to.Name() {
// This can happen for cc.reuseObjTag. We are not interested in tracking this. // This can happen for cc.reuseObjTag. We are not interested in tracking this.
return // As soon as the dependency graph crosses the APEX boundary, don't go further.
return !externalDep
} }
if info, exists := a.depInfos[to.Name()]; exists { if info, exists := a.depInfos[to.Name()]; exists {
@@ -1885,6 +1893,9 @@ func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) {
isExternal: externalDep, isExternal: externalDep,
} }
} }
// As soon as the dependency graph crosses the APEX boundary, don't go further.
return !externalDep
}) })
} }

View File

@@ -230,12 +230,16 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs,
func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs { func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName string) android.NoticeOutputs {
var noticeFiles android.Paths var noticeFiles android.Paths
a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) { a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
if externalDep { if externalDep {
return // As soon as the dependency graph crosses the APEX boundary, don't go further.
return false
} }
notices := to.NoticeFiles() notices := to.NoticeFiles()
noticeFiles = append(noticeFiles, notices...) noticeFiles = append(noticeFiles, notices...)
return true
}) })
if len(noticeFiles) == 0 { if len(noticeFiles) == 0 {