<apex_name>-deps-info correctly tracks dependencies
The APEX dependency is more correctly tracked. Previously, the
dependency was tracked while we gather modules that will be installed to
an APEX. This actually was incorrect because we skipped many dependency
types that we don't need to follow to gather the modules list, such as
the headers dependency.
Now, the dependency is tracked directly when a module is mutated for an
APEX. In other words, if a module is mutated for an apex X, then the
module will appear in the X-deps-into.txt file.
This change also changes the format of the txt file. It now clearly
shows why a module is included in the APEX by showing the list of
modules that depend on the module.
Bug: 146323213
Test: m
Change-Id: I0a70cf9cce56e36565f9d55683fdaace8748a081
diff --git a/apex/apex.go b/apex/apex.go
index 1adeb7d..825a0ad 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -1466,6 +1466,12 @@
return false
}
+type depInfo struct {
+ to string
+ from []string
+ isExternal bool
+}
+
type apexBundle struct {
android.ModuleBase
android.DefaultableModuleBase
@@ -1499,10 +1505,8 @@
// list of module names that should be installed along with this APEX
requiredDeps []string
- // list of module names that this APEX is depending on (to be shown via *-deps-info target)
- externalDeps []string
// list of module names that this APEX is including (to be shown via *-deps-info target)
- internalDeps []string
+ depInfos map[string]depInfo
testApex bool
vndkApex bool
@@ -1983,6 +1987,31 @@
})
}
+// Collects the list of module names that directly or indirectly contributes to the payload of this APEX
+func (a *apexBundle) collectDepsInfo(ctx android.ModuleContext) {
+ a.depInfos = make(map[string]depInfo)
+ a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) {
+ if from.Name() == to.Name() {
+ // This can happen for cc.reuseObjTag. We are not interested in tracking this.
+ return
+ }
+
+ if info, exists := a.depInfos[to.Name()]; exists {
+ if !android.InList(from.Name(), info.from) {
+ info.from = append(info.from, from.Name())
+ }
+ info.isExternal = info.isExternal && externalDep
+ a.depInfos[to.Name()] = info
+ } else {
+ a.depInfos[to.Name()] = depInfo{
+ to: to.Name(),
+ from: []string{from.Name()},
+ isExternal: externalDep,
+ }
+ }
+ })
+}
+
func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild()
switch a.properties.ApexType {
@@ -2020,6 +2049,8 @@
a.checkApexAvailability(ctx)
+ a.collectDepsInfo(ctx)
+
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
// native lib dependencies
@@ -2051,13 +2082,11 @@
})
var filesInfo []apexFile
+ // TODO(jiyong) do this using walkPayloadDeps
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
depTag := ctx.OtherModuleDependencyTag(child)
depName := ctx.OtherModuleName(child)
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
- if depTag != keyTag && depTag != certificateTag {
- a.internalDeps = append(a.internalDeps, depName)
- }
switch depTag {
case sharedLibTag:
if c, ok := child.(*cc.Module); ok {
@@ -2194,7 +2223,6 @@
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.requiredDeps) {
a.requiredDeps = append(a.requiredDeps, cc.Name())
}
- a.externalDeps = append(a.externalDeps, depName)
requireNativeLibs = append(requireNativeLibs, cc.OutputFile().Path().Base())
// Don't track further
return false
@@ -2202,8 +2230,6 @@
af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
af.transitiveDep = true
filesInfo = append(filesInfo, af)
- a.internalDeps = append(a.internalDeps, depName)
- a.internalDeps = append(a.internalDeps, cc.AllStaticDeps()...)
return true // track transitive dependencies
}
} else if cc.IsTestPerSrcDepTag(depTag) {
@@ -2220,10 +2246,7 @@
return true // track transitive dependencies
}
} else if java.IsJniDepTag(depTag) {
- a.externalDeps = append(a.externalDeps, depName)
return true
- } else if java.IsStaticLibDepTag(depTag) {
- a.internalDeps = append(a.internalDeps, depName)
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index c5b89e6..207ca05 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -549,10 +549,11 @@
ensureListContains(t, noticeInputs, "custom_notice")
depsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("myapex-deps-info.txt").Args["content"], "\\n")
- ensureListContains(t, depsInfo, "internal myjar")
- ensureListContains(t, depsInfo, "internal mylib")
- ensureListContains(t, depsInfo, "internal mylib2")
- ensureListContains(t, depsInfo, "internal myotherjar")
+ ensureListContains(t, depsInfo, "myjar <- myapex")
+ ensureListContains(t, depsInfo, "mylib <- myapex")
+ ensureListContains(t, depsInfo, "mylib2 <- mylib")
+ ensureListContains(t, depsInfo, "myotherjar <- myjar")
+ ensureListContains(t, depsInfo, "mysharedjar (external) <- myjar")
}
func TestDefaults(t *testing.T) {
@@ -796,6 +797,7 @@
name: "mylib",
srcs: ["mylib.cpp"],
shared_libs: ["libfoo#10"],
+ static_libs: ["libbaz"],
system_shared_libs: [],
stl: "none",
apex_available: [ "myapex2" ],
@@ -819,6 +821,14 @@
stl: "none",
}
+ cc_library_static {
+ name: "libbaz",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex2" ],
+ }
+
`)
apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Rule("apexRule")
@@ -846,10 +856,10 @@
ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
depsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("myapex2-deps-info.txt").Args["content"], "\\n")
- ensureListContains(t, depsInfo, "internal mylib")
- ensureListContains(t, depsInfo, "external libfoo")
- ensureListNotContains(t, depsInfo, "internal libfoo")
- ensureListNotContains(t, depsInfo, "external mylib")
+
+ ensureListContains(t, depsInfo, "mylib <- myapex2")
+ ensureListContains(t, depsInfo, "libbaz <- mylib")
+ ensureListContains(t, depsInfo, "libfoo (external) <- mylib")
}
func TestApexWithRuntimeLibsDependency(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index 51818eb..8798fd3 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -596,19 +596,14 @@
return
}
- internalDeps := a.internalDeps
- externalDeps := a.externalDeps
-
- internalDeps = android.SortedUniqueStrings(internalDeps)
- externalDeps = android.SortedUniqueStrings(externalDeps)
- externalDeps = android.RemoveListFromList(externalDeps, internalDeps)
-
var content strings.Builder
- for _, name := range internalDeps {
- fmt.Fprintf(&content, "internal %s\\n", name)
- }
- for _, name := range externalDeps {
- fmt.Fprintf(&content, "external %s\\n", name)
+ for _, key := range android.SortedStringKeys(a.depInfos) {
+ info := a.depInfos[key]
+ toName := info.to
+ if info.isExternal {
+ toName = toName + " (external)"
+ }
+ fmt.Fprintf(&content, "%s <- %s\\n", toName, strings.Join(android.SortedUniqueStrings(info.from), ", "))
}
depsInfoFile := android.PathForOutput(ctx, a.Name()+"-deps-info.txt")
diff --git a/cc/cc.go b/cc/cc.go
index 2e55841..4a316cb 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -403,13 +403,6 @@
return ok && ccDepTag.Shared
}
-func IsStaticDepTag(depTag blueprint.DependencyTag) bool {
- ccDepTag, ok := depTag.(DependencyTag)
- return ok && (ccDepTag == staticExportDepTag ||
- ccDepTag == lateStaticDepTag ||
- ccDepTag == wholeStaticDepTag)
-}
-
func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
ccDepTag, ok := depTag.(DependencyTag)
return ok && ccDepTag == runtimeDepTag
@@ -475,9 +468,6 @@
makeLinkType string
// Kythe (source file indexer) paths for this compilation module
kytheFiles android.Paths
-
- // name of the modules that are direct or indirect static deps of this module
- allStaticDeps []string
}
func (c *Module) Toc() android.OptionalPath {
@@ -1288,15 +1278,6 @@
return results
}
-func gatherTransitiveStaticDeps(staticDeps []LinkableInterface) []string {
- var ret []string
- for _, dep := range staticDeps {
- ret = append(ret, dep.Module().Name())
- ret = append(ret, dep.AllStaticDeps()...)
- }
- return android.FirstUniqueStrings(ret)
-}
-
func (c *Module) IsTestPerSrcAllTestsVariation() bool {
test, ok := c.linker.(testPerSrc)
return ok && test.isAllTestsVariation()
@@ -2378,8 +2359,6 @@
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
}
- c.allStaticDeps = gatherTransitiveStaticDeps(directStaticDeps)
-
return depPaths
}
@@ -2539,10 +2518,6 @@
return false
}
-func (c *Module) AllStaticDeps() []string {
- return c.allStaticDeps
-}
-
func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
if c.linker != nil {
if library, ok := c.linker.(*libraryDecorator); ok {
diff --git a/cc/linkable.go b/cc/linkable.go
index 2abb112..e4f034c 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -54,8 +54,6 @@
ToolchainLibrary() bool
NdkPrebuiltStl() bool
StubDecorator() bool
-
- AllStaticDeps() []string
}
type DependencyTag struct {
diff --git a/rust/rust.go b/rust/rust.go
index e2af6f0..e31668d 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -354,11 +354,6 @@
return nil
}
-func (mod *Module) AllStaticDeps() []string {
- // TODO(jiyong): do this for rust?
- return nil
-}
-
func (mod *Module) Module() android.Module {
return mod
}