Add dependency tags to apex available errors
Having dependency tags in the dependency path that shows why a specific
module is considered part of an apex makes it easier to understand why
that is the case and detect possible issues.
Bug: 152762638
Test: m nothing
Change-Id: Iba2a8a5a6abe03dadee456e760aa4373cd00c07b
diff --git a/apex/apex.go b/apex/apex.go
index 8e9bd04..9142161 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -18,6 +18,7 @@
"fmt"
"path"
"path/filepath"
+ "regexp"
"sort"
"strconv"
"strings"
@@ -1808,6 +1809,24 @@
return android.FutureApiLevel
}
+// 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
@@ -1835,8 +1854,11 @@
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 b97e38d..0e8c9af 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -3540,11 +3540,17 @@
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",