Merge "<apex_name>-deps-info correctly tracks dependencies" am: 2bb26d3fad
am: 39b51a899f
am: 5a14677e31
Change-Id: I54d0ececcb8e0a6c92ce13666f922a42cc80efbd
This commit is contained in:
47
apex/apex.go
47
apex/apex.go
@@ -1466,6 +1466,12 @@ func (af *apexFile) AvailableToPlatform() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type depInfo struct {
|
||||||
|
to string
|
||||||
|
from []string
|
||||||
|
isExternal bool
|
||||||
|
}
|
||||||
|
|
||||||
type apexBundle struct {
|
type apexBundle struct {
|
||||||
android.ModuleBase
|
android.ModuleBase
|
||||||
android.DefaultableModuleBase
|
android.DefaultableModuleBase
|
||||||
@@ -1499,10 +1505,8 @@ type apexBundle struct {
|
|||||||
// list of module names that should be installed along with this APEX
|
// list of module names that should be installed along with this APEX
|
||||||
requiredDeps []string
|
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)
|
// list of module names that this APEX is including (to be shown via *-deps-info target)
|
||||||
internalDeps []string
|
depInfos map[string]depInfo
|
||||||
|
|
||||||
testApex bool
|
testApex bool
|
||||||
vndkApex 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) {
|
func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild()
|
buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild()
|
||||||
switch a.properties.ApexType {
|
switch a.properties.ApexType {
|
||||||
@@ -2020,6 +2049,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
a.checkApexAvailability(ctx)
|
a.checkApexAvailability(ctx)
|
||||||
|
|
||||||
|
a.collectDepsInfo(ctx)
|
||||||
|
|
||||||
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
|
handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)
|
||||||
|
|
||||||
// native lib dependencies
|
// native lib dependencies
|
||||||
@@ -2051,13 +2082,11 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
var filesInfo []apexFile
|
var filesInfo []apexFile
|
||||||
|
// TODO(jiyong) do this using walkPayloadDeps
|
||||||
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
|
ctx.WalkDepsBlueprint(func(child, parent blueprint.Module) bool {
|
||||||
depTag := ctx.OtherModuleDependencyTag(child)
|
depTag := ctx.OtherModuleDependencyTag(child)
|
||||||
depName := ctx.OtherModuleName(child)
|
depName := ctx.OtherModuleName(child)
|
||||||
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
|
if _, isDirectDep := parent.(*apexBundle); isDirectDep {
|
||||||
if depTag != keyTag && depTag != certificateTag {
|
|
||||||
a.internalDeps = append(a.internalDeps, depName)
|
|
||||||
}
|
|
||||||
switch depTag {
|
switch depTag {
|
||||||
case sharedLibTag:
|
case sharedLibTag:
|
||||||
if c, ok := child.(*cc.Module); ok {
|
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) {
|
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.requiredDeps) {
|
||||||
a.requiredDeps = append(a.requiredDeps, cc.Name())
|
a.requiredDeps = append(a.requiredDeps, cc.Name())
|
||||||
}
|
}
|
||||||
a.externalDeps = append(a.externalDeps, depName)
|
|
||||||
requireNativeLibs = append(requireNativeLibs, cc.OutputFile().Path().Base())
|
requireNativeLibs = append(requireNativeLibs, cc.OutputFile().Path().Base())
|
||||||
// Don't track further
|
// Don't track further
|
||||||
return false
|
return false
|
||||||
@@ -2202,8 +2230,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
|
af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
|
||||||
af.transitiveDep = true
|
af.transitiveDep = true
|
||||||
filesInfo = append(filesInfo, af)
|
filesInfo = append(filesInfo, af)
|
||||||
a.internalDeps = append(a.internalDeps, depName)
|
|
||||||
a.internalDeps = append(a.internalDeps, cc.AllStaticDeps()...)
|
|
||||||
return true // track transitive dependencies
|
return true // track transitive dependencies
|
||||||
}
|
}
|
||||||
} else if cc.IsTestPerSrcDepTag(depTag) {
|
} else if cc.IsTestPerSrcDepTag(depTag) {
|
||||||
@@ -2220,10 +2246,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
return true // track transitive dependencies
|
return true // track transitive dependencies
|
||||||
}
|
}
|
||||||
} else if java.IsJniDepTag(depTag) {
|
} else if java.IsJniDepTag(depTag) {
|
||||||
a.externalDeps = append(a.externalDeps, depName)
|
|
||||||
return true
|
return true
|
||||||
} else if java.IsStaticLibDepTag(depTag) {
|
|
||||||
a.internalDeps = append(a.internalDeps, depName)
|
|
||||||
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
|
} else if am.CanHaveApexVariants() && am.IsInstallableToApex() {
|
||||||
ctx.ModuleErrorf("unexpected tag %q for indirect dependency %q", depTag, depName)
|
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")
|
ensureListContains(t, noticeInputs, "custom_notice")
|
||||||
|
|
||||||
depsInfo := strings.Split(ctx.ModuleForTests("myapex", "android_common_myapex_image").Output("myapex-deps-info.txt").Args["content"], "\\n")
|
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, "myjar <- myapex")
|
||||||
ensureListContains(t, depsInfo, "internal mylib")
|
ensureListContains(t, depsInfo, "mylib <- myapex")
|
||||||
ensureListContains(t, depsInfo, "internal mylib2")
|
ensureListContains(t, depsInfo, "mylib2 <- mylib")
|
||||||
ensureListContains(t, depsInfo, "internal myotherjar")
|
ensureListContains(t, depsInfo, "myotherjar <- myjar")
|
||||||
|
ensureListContains(t, depsInfo, "mysharedjar (external) <- myjar")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaults(t *testing.T) {
|
func TestDefaults(t *testing.T) {
|
||||||
@@ -796,6 +797,7 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||||||
name: "mylib",
|
name: "mylib",
|
||||||
srcs: ["mylib.cpp"],
|
srcs: ["mylib.cpp"],
|
||||||
shared_libs: ["libfoo#10"],
|
shared_libs: ["libfoo#10"],
|
||||||
|
static_libs: ["libbaz"],
|
||||||
system_shared_libs: [],
|
system_shared_libs: [],
|
||||||
stl: "none",
|
stl: "none",
|
||||||
apex_available: [ "myapex2" ],
|
apex_available: [ "myapex2" ],
|
||||||
@@ -819,6 +821,14 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||||||
stl: "none",
|
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")
|
apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Rule("apexRule")
|
||||||
@@ -846,10 +856,10 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||||||
ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
|
ensureNotContains(t, libFooStubsLdFlags, "libbar.so")
|
||||||
|
|
||||||
depsInfo := strings.Split(ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Output("myapex2-deps-info.txt").Args["content"], "\\n")
|
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")
|
ensureListContains(t, depsInfo, "mylib <- myapex2")
|
||||||
ensureListNotContains(t, depsInfo, "internal libfoo")
|
ensureListContains(t, depsInfo, "libbaz <- mylib")
|
||||||
ensureListNotContains(t, depsInfo, "external mylib")
|
ensureListContains(t, depsInfo, "libfoo (external) <- mylib")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexWithRuntimeLibsDependency(t *testing.T) {
|
func TestApexWithRuntimeLibsDependency(t *testing.T) {
|
||||||
|
@@ -596,19 +596,14 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
internalDeps := a.internalDeps
|
|
||||||
externalDeps := a.externalDeps
|
|
||||||
|
|
||||||
internalDeps = android.SortedUniqueStrings(internalDeps)
|
|
||||||
externalDeps = android.SortedUniqueStrings(externalDeps)
|
|
||||||
externalDeps = android.RemoveListFromList(externalDeps, internalDeps)
|
|
||||||
|
|
||||||
var content strings.Builder
|
var content strings.Builder
|
||||||
for _, name := range internalDeps {
|
for _, key := range android.SortedStringKeys(a.depInfos) {
|
||||||
fmt.Fprintf(&content, "internal %s\\n", name)
|
info := a.depInfos[key]
|
||||||
}
|
toName := info.to
|
||||||
for _, name := range externalDeps {
|
if info.isExternal {
|
||||||
fmt.Fprintf(&content, "external %s\\n", name)
|
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")
|
depsInfoFile := android.PathForOutput(ctx, a.Name()+"-deps-info.txt")
|
||||||
|
25
cc/cc.go
25
cc/cc.go
@@ -407,13 +407,6 @@ func IsSharedDepTag(depTag blueprint.DependencyTag) bool {
|
|||||||
return ok && ccDepTag.Shared
|
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 {
|
func IsRuntimeDepTag(depTag blueprint.DependencyTag) bool {
|
||||||
ccDepTag, ok := depTag.(DependencyTag)
|
ccDepTag, ok := depTag.(DependencyTag)
|
||||||
return ok && ccDepTag == runtimeDepTag
|
return ok && ccDepTag == runtimeDepTag
|
||||||
@@ -477,9 +470,6 @@ type Module struct {
|
|||||||
makeLinkType string
|
makeLinkType string
|
||||||
// Kythe (source file indexer) paths for this compilation module
|
// Kythe (source file indexer) paths for this compilation module
|
||||||
kytheFiles android.Paths
|
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 {
|
func (c *Module) Toc() android.OptionalPath {
|
||||||
@@ -1295,15 +1285,6 @@ func orderStaticModuleDeps(module LinkableInterface, staticDeps []LinkableInterf
|
|||||||
return results
|
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 {
|
func (c *Module) IsTestPerSrcAllTestsVariation() bool {
|
||||||
test, ok := c.linker.(testPerSrc)
|
test, ok := c.linker.(testPerSrc)
|
||||||
return ok && test.isAllTestsVariation()
|
return ok && test.isAllTestsVariation()
|
||||||
@@ -2389,8 +2370,6 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
|
|||||||
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
|
c.sabi.Properties.ReexportedIncludes = android.FirstUniqueStrings(c.sabi.Properties.ReexportedIncludes)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.allStaticDeps = gatherTransitiveStaticDeps(directStaticDeps)
|
|
||||||
|
|
||||||
return depPaths
|
return depPaths
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2550,10 +2529,6 @@ func (c *Module) installable() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Module) AllStaticDeps() []string {
|
|
||||||
return c.allStaticDeps
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
|
func (c *Module) AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
|
||||||
if c.linker != nil {
|
if c.linker != nil {
|
||||||
if library, ok := c.linker.(*libraryDecorator); ok {
|
if library, ok := c.linker.(*libraryDecorator); ok {
|
||||||
|
@@ -54,8 +54,6 @@ type LinkableInterface interface {
|
|||||||
ToolchainLibrary() bool
|
ToolchainLibrary() bool
|
||||||
NdkPrebuiltStl() bool
|
NdkPrebuiltStl() bool
|
||||||
StubDecorator() bool
|
StubDecorator() bool
|
||||||
|
|
||||||
AllStaticDeps() []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type DependencyTag struct {
|
type DependencyTag struct {
|
||||||
|
@@ -354,11 +354,6 @@ func (mod *Module) GetStaticVariant() cc.LinkableInterface {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mod *Module) AllStaticDeps() []string {
|
|
||||||
// TODO(jiyong): do this for rust?
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mod *Module) Module() android.Module {
|
func (mod *Module) Module() android.Module {
|
||||||
return mod
|
return mod
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user