<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
This commit is contained in:
parent
201cedd608
commit
678c881a4f
47
apex/apex.go
47
apex/apex.go
|
@ -1466,6 +1466,12 @@ func (af *apexFile) AvailableToPlatform() bool {
|
|||
return false
|
||||
}
|
||||
|
||||
type depInfo struct {
|
||||
to string
|
||||
from []string
|
||||
isExternal bool
|
||||
}
|
||||
|
||||
type apexBundle struct {
|
||||
android.ModuleBase
|
||||
android.DefaultableModuleBase
|
||||
|
@ -1499,10 +1505,8 @@ type apexBundle struct {
|
|||
// 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 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) {
|
|||
})
|
||||
}
|
||||
|
||||
// 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 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
|
||||
a.checkApexAvailability(ctx)
|
||||
|
||||
a.collectDepsInfo(ctx)
|
||||
|
||||
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
|
||||
|
||||
// native lib dependencies
|
||||
|
@ -2051,13 +2082,11 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
})
|
||||
|
||||
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 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
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 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
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 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||
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)
|
||||
}
|
||||
|
|
|
@ -549,10 +549,11 @@ func TestBasicApex(t *testing.T) {
|
|||
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 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||
name: "mylib",
|
||||
srcs: ["mylib.cpp"],
|
||||
shared_libs: ["libfoo#10"],
|
||||
static_libs: ["libbaz"],
|
||||
system_shared_libs: [],
|
||||
stl: "none",
|
||||
apex_available: [ "myapex2" ],
|
||||
|
@ -819,6 +821,14 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||
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 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||
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) {
|
||||
|
|
|
@ -596,19 +596,14 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
|
|||
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")
|
||||
|
|
25
cc/cc.go
25
cc/cc.go
|
@ -403,13 +403,6 @@ func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
|
|||
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 @@ type Module struct {
|
|||
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 @@ func orderStaticModuleDeps(module LinkableInterface, staticDeps []LinkableInterf
|
|||
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 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
|
||||
}
|
||||
|
||||
c.allStaticDeps = gatherTransitiveStaticDeps(directStaticDeps)
|
||||
|
||||
return depPaths
|
||||
}
|
||||
|
||||
|
@ -2539,10 +2518,6 @@ func (c *Module) installable() bool {
|
|||
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 {
|
||||
|
|
|
@ -54,8 +54,6 @@ type LinkableInterface interface {
|
|||
ToolchainLibrary() bool
|
||||
NdkPrebuiltStl() bool
|
||||
StubDecorator() bool
|
||||
|
||||
AllStaticDeps() []string
|
||||
}
|
||||
|
||||
type DependencyTag struct {
|
||||
|
|
|
@ -354,11 +354,6 @@ func (mod *Module) GetStaticVariant() cc.LinkableInterface {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (mod *Module) AllStaticDeps() []string {
|
||||
// TODO(jiyong): do this for rust?
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mod *Module) Module() android.Module {
|
||||
return mod
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue