diff options
-rw-r--r-- | android/module.go | 15 | ||||
-rw-r--r-- | apex/apex.go | 26 | ||||
-rw-r--r-- | apex/apex_test.go | 6 |
3 files changed, 45 insertions, 2 deletions
diff --git a/android/module.go b/android/module.go index ada68587..f300e057 100644 --- a/android/module.go +++ b/android/module.go @@ -128,6 +128,13 @@ type BaseModuleContext interface { // and returns a top-down dependency path from a start module to current child module. GetWalkPath() []Module + // GetTagPath is supposed to be called in visit function passed in WalkDeps() + // and returns a top-down dependency tags path from a start module to current child module. + // It has one less entry than GetWalkPath() as it contains the dependency tags that + // exist between each adjacent pair of modules in the GetWalkPath(). + // GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1] + GetTagPath() []blueprint.DependencyTag + AddMissingDependencies(missingDeps []string) Target() Target @@ -1386,6 +1393,7 @@ type baseModuleContext struct { debug bool walkPath []Module + tagPath []blueprint.DependencyTag strictVisitDeps bool // If true, enforce that all dependencies are enabled } @@ -1675,6 +1683,7 @@ func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, bluep func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { b.walkPath = []Module{b.Module()} + b.tagPath = []blueprint.DependencyTag{} b.bp.WalkDeps(func(child, parent blueprint.Module) bool { childAndroidModule, _ := child.(Module) parentAndroidModule, _ := parent.(Module) @@ -1682,8 +1691,10 @@ func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) { // record walkPath before visit for b.walkPath[len(b.walkPath)-1] != parentAndroidModule { b.walkPath = b.walkPath[0 : len(b.walkPath)-1] + b.tagPath = b.tagPath[0 : len(b.tagPath)-1] } b.walkPath = append(b.walkPath, childAndroidModule) + b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule)) return visit(childAndroidModule, parentAndroidModule) } else { return false @@ -1695,6 +1706,10 @@ func (b *baseModuleContext) GetWalkPath() []Module { return b.walkPath } +func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag { + return b.tagPath +} + func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) { m.bp.VisitAllModuleVariants(func(module blueprint.Module) { visit(module.(Module)) diff --git a/apex/apex.go b/apex/apex.go index eb87ecf2..a40a7539 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -18,6 +18,7 @@ import ( "fmt" "path" "path/filepath" + "regexp" "sort" "strings" "sync" @@ -1807,6 +1808,24 @@ func (a *apexBundle) minSdkVersion(ctx android.BaseModuleContext) int { return intVer } +// A regexp for removing boilerplate from BaseDependencyTag from the string representation of +// a dependency tag. +var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:blueprint.BaseDependencyTag{}\E(, )?`) + +func PrettyPrintTag(tag blueprint.DependencyTag) string { + // Use tag's custom String() method if available. + if stringer, ok := tag.(fmt.Stringer); ok { + return stringer.String() + } + + // Otherwise, get a default string representation of the tag's struct. + tagString := fmt.Sprintf("%#v", tag) + + // Remove the boilerplate from BaseDependencyTag as it adds no value. + tagString = tagCleaner.ReplaceAllString(tagString, "") + return tagString +} + // Ensures that the dependencies are marked as available for this APEX func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { // Let's be practical. Availability for test, host, and the VNDK apex isn't important @@ -1834,8 +1853,11 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { return true } message := "" - for _, m := range ctx.GetWalkPath()[1:] { - message = fmt.Sprintf("%s\n -> %s", message, m.String()) + tagPath := ctx.GetTagPath() + // Skip the first module as that will be added at the start of the error message by ctx.ModuleErrorf(). + walkPath := ctx.GetWalkPath()[1:] + for i, m := range walkPath { + message = fmt.Sprintf("%s\n via tag %s\n -> %s", message, PrettyPrintTag(tagPath[i]), m.String()) } 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. diff --git a/apex/apex_test.go b/apex/apex_test.go index e24a4435..a76f50d7 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -3516,11 +3516,17 @@ func TestApexAvailable_DirectDep(t *testing.T) { func TestApexAvailable_IndirectDep(t *testing.T) { // libbbaz is an indirect dep testApexError(t, `requires "libbaz" that is not available for the APEX. Dependency path: +.*via tag apex\.dependencyTag.*"sharedLib".* .*-> libfoo.*link:shared.* +.*via tag cc\.DependencyTag.*"reuse objects".* .*-> libfoo.*link:static.* +.*via tag cc\.DependencyTag.*"shared from static".* .*-> libbar.*link:shared.* +.*via tag cc\.DependencyTag.*"reuse objects".* .*-> libbar.*link:static.* +.*via tag cc\.DependencyTag.*"shared from static".* .*-> libbaz.*link:shared.* +.*via tag cc\.DependencyTag.*"reuse objects".* .*-> libbaz.*link:static.*`, ` apex { name: "myapex", |