m <apex_name>-deps-info prints the internal/external deps of the APEX
We need to have a way to see the list of modules that directly or indirectly contribute to an APEX. People find it difficult to determine whether a module is included in which APEXes because APEX tracks indirect dependencies as well as direct dependencies. Therefore, just looking at Android.bp for the APEX itself doesn't give the answer. This change adds a new make target <apex_name>-deps-info, which generates out/soong/<apex_name>-deps-info.txt file that shows the internal and external dependencies of the said APEX. Here, internal means the dependencies are actually part of the APEX, while external means the dependencies are still external to the APEX. Bug: 146323213 Test: m (apex_test amended) Change-Id: I33d1ccf5d1ca335d71cd6ced0f5f66b8c3886d13
This commit is contained in:
@@ -185,8 +185,8 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData {
|
|||||||
if len(moduleNames) > 0 {
|
if len(moduleNames) > 0 {
|
||||||
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(moduleNames, " "))
|
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(moduleNames, " "))
|
||||||
}
|
}
|
||||||
if len(a.externalDeps) > 0 {
|
if len(a.requiredDeps) > 0 {
|
||||||
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.externalDeps, " "))
|
fmt.Fprintln(w, "LOCAL_REQUIRED_MODULES +=", strings.Join(a.requiredDeps, " "))
|
||||||
}
|
}
|
||||||
var postInstallCommands []string
|
var postInstallCommands []string
|
||||||
if a.prebuiltFileToDelete != "" {
|
if a.prebuiltFileToDelete != "" {
|
||||||
|
24
apex/apex.go
24
apex/apex.go
@@ -511,8 +511,13 @@ type apexBundle struct {
|
|||||||
// list of files to be included in this apex
|
// list of files to be included in this apex
|
||||||
filesInfo []apexFile
|
filesInfo []apexFile
|
||||||
|
|
||||||
// list of module names that this APEX is depending on
|
// 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
|
externalDeps []string
|
||||||
|
// list of module names that this APEX is including (to be shown via *-deps-info target)
|
||||||
|
internalDeps []string
|
||||||
|
|
||||||
testApex bool
|
testApex bool
|
||||||
vndkApex bool
|
vndkApex bool
|
||||||
@@ -925,7 +930,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
a.primaryApexType = true
|
a.primaryApexType = true
|
||||||
|
|
||||||
if ctx.Config().InstallExtraFlattenedApexes() {
|
if ctx.Config().InstallExtraFlattenedApexes() {
|
||||||
a.externalDeps = append(a.externalDeps, a.Name()+flattenedSuffix)
|
a.requiredDeps = append(a.requiredDeps, a.Name()+flattenedSuffix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case zipApex:
|
case zipApex:
|
||||||
@@ -984,6 +989,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
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 cc, ok := child.(*cc.Module); ok {
|
if cc, ok := child.(*cc.Module); ok {
|
||||||
@@ -1114,9 +1122,10 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
//
|
//
|
||||||
// Always include if we are a host-apex however since those won't have any
|
// Always include if we are a host-apex however since those won't have any
|
||||||
// system libraries.
|
// system libraries.
|
||||||
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.externalDeps) {
|
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.Name(), a.requiredDeps) {
|
||||||
a.externalDeps = append(a.externalDeps, 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
|
||||||
@@ -1124,6 +1133,8 @@ 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) {
|
||||||
@@ -1139,8 +1150,10 @@ 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) {
|
||||||
// Do nothing for JNI dep. JNI libraries are always embedded in APK-in-APEX.
|
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)
|
||||||
}
|
}
|
||||||
@@ -1238,6 +1251,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
|
|
||||||
apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())
|
apexName := proptools.StringDefault(a.properties.Apex_name, a.Name())
|
||||||
a.compatSymlinks = makeCompatSymlinks(apexName, ctx)
|
a.compatSymlinks = makeCompatSymlinks(apexName, ctx)
|
||||||
|
a.buildApexDependencyInfo(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newApexBundle() *apexBundle {
|
func newApexBundle() *apexBundle {
|
||||||
|
@@ -219,6 +219,7 @@ func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*andr
|
|||||||
"apex_manifest.json": nil,
|
"apex_manifest.json": nil,
|
||||||
"AndroidManifest.xml": nil,
|
"AndroidManifest.xml": nil,
|
||||||
"system/sepolicy/apex/myapex-file_contexts": nil,
|
"system/sepolicy/apex/myapex-file_contexts": nil,
|
||||||
|
"system/sepolicy/apex/myapex2-file_contexts": nil,
|
||||||
"system/sepolicy/apex/otherapex-file_contexts": nil,
|
"system/sepolicy/apex/otherapex-file_contexts": nil,
|
||||||
"system/sepolicy/apex/commonapex-file_contexts": nil,
|
"system/sepolicy/apex/commonapex-file_contexts": nil,
|
||||||
"system/sepolicy/apex/com.android.vndk-file_contexts": nil,
|
"system/sepolicy/apex/com.android.vndk-file_contexts": nil,
|
||||||
@@ -520,6 +521,12 @@ func TestBasicApex(t *testing.T) {
|
|||||||
}
|
}
|
||||||
ensureListContains(t, noticeInputs, "NOTICE")
|
ensureListContains(t, noticeInputs, "NOTICE")
|
||||||
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")
|
||||||
|
ensureListContains(t, depsInfo, "internal myjar")
|
||||||
|
ensureListContains(t, depsInfo, "internal mylib")
|
||||||
|
ensureListContains(t, depsInfo, "internal mylib2")
|
||||||
|
ensureListContains(t, depsInfo, "internal myotherjar")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDefaults(t *testing.T) {
|
func TestDefaults(t *testing.T) {
|
||||||
@@ -740,13 +747,13 @@ func TestApexWithStubs(t *testing.T) {
|
|||||||
func TestApexWithExplicitStubsDependency(t *testing.T) {
|
func TestApexWithExplicitStubsDependency(t *testing.T) {
|
||||||
ctx, _ := testApex(t, `
|
ctx, _ := testApex(t, `
|
||||||
apex {
|
apex {
|
||||||
name: "myapex",
|
name: "myapex2",
|
||||||
key: "myapex.key",
|
key: "myapex2.key",
|
||||||
native_shared_libs: ["mylib"],
|
native_shared_libs: ["mylib"],
|
||||||
}
|
}
|
||||||
|
|
||||||
apex_key {
|
apex_key {
|
||||||
name: "myapex.key",
|
name: "myapex2.key",
|
||||||
public_key: "testkey.avbpubkey",
|
public_key: "testkey.avbpubkey",
|
||||||
private_key: "testkey.pem",
|
private_key: "testkey.pem",
|
||||||
}
|
}
|
||||||
@@ -779,7 +786,7 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||||||
|
|
||||||
`)
|
`)
|
||||||
|
|
||||||
apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
|
apexRule := ctx.ModuleForTests("myapex2", "android_common_myapex2_image").Rule("apexRule")
|
||||||
copyCmds := apexRule.Args["copy_commands"]
|
copyCmds := apexRule.Args["copy_commands"]
|
||||||
|
|
||||||
// Ensure that direct non-stubs dep is always included
|
// Ensure that direct non-stubs dep is always included
|
||||||
@@ -791,7 +798,7 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||||||
// Ensure that dependency of stubs is not included
|
// Ensure that dependency of stubs is not included
|
||||||
ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
|
ensureNotContains(t, copyCmds, "image.apex/lib64/libbar.so")
|
||||||
|
|
||||||
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex").Rule("ld").Args["libFlags"]
|
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_myapex2").Rule("ld").Args["libFlags"]
|
||||||
|
|
||||||
// Ensure that mylib is linking with version 10 of libfoo
|
// Ensure that mylib is linking with version 10 of libfoo
|
||||||
ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
|
ensureContains(t, mylibLdFlags, "libfoo/android_arm64_armv8-a_shared_10/libfoo.so")
|
||||||
@@ -802,6 +809,12 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
|
|||||||
|
|
||||||
// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
|
// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
|
||||||
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")
|
||||||
|
ensureListContains(t, depsInfo, "internal mylib")
|
||||||
|
ensureListContains(t, depsInfo, "external libfoo")
|
||||||
|
ensureListNotContains(t, depsInfo, "internal libfoo")
|
||||||
|
ensureListNotContains(t, depsInfo, "external mylib")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestApexWithRuntimeLibsDependency(t *testing.T) {
|
func TestApexWithRuntimeLibsDependency(t *testing.T) {
|
||||||
@@ -2652,7 +2665,7 @@ func TestInstallExtraFlattenedApexes(t *testing.T) {
|
|||||||
config.TestProductVariables.InstallExtraFlattenedApexes = proptools.BoolPtr(true)
|
config.TestProductVariables.InstallExtraFlattenedApexes = proptools.BoolPtr(true)
|
||||||
})
|
})
|
||||||
ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
|
ab := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
|
||||||
ensureListContains(t, ab.externalDeps, "myapex.flattened")
|
ensureListContains(t, ab.requiredDeps, "myapex.flattened")
|
||||||
mk := android.AndroidMkDataForTest(t, config, "", ab)
|
mk := android.AndroidMkDataForTest(t, config, "", ab)
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
mk.Custom(&builder, ab.Name(), "TARGET_", "", mk)
|
mk.Custom(&builder, ab.Name(), "TARGET_", "", mk)
|
||||||
|
@@ -553,3 +553,40 @@ func (a *apexBundle) getOverrideManifestPackageName(ctx android.ModuleContext) s
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
|
||||||
|
if !a.primaryApexType {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
depsInfoFile := android.PathForOutput(ctx, a.Name()+"-deps-info.txt")
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: android.WriteFile,
|
||||||
|
Description: "Dependency Info",
|
||||||
|
Output: depsInfoFile,
|
||||||
|
Args: map[string]string{
|
||||||
|
"content": content.String(),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
ctx.Build(pctx, android.BuildParams{
|
||||||
|
Rule: android.Phony,
|
||||||
|
Output: android.PathForPhony(ctx, a.Name()+"-deps-info"),
|
||||||
|
Inputs: []android.Path{depsInfoFile},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
25
cc/cc.go
25
cc/cc.go
@@ -398,6 +398,13 @@ 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
|
||||||
@@ -463,6 +470,9 @@ 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 {
|
||||||
@@ -1258,6 +1268,15 @@ 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()
|
||||||
@@ -2328,6 +2347,8 @@ 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
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2463,6 +2484,10 @@ func (c *Module) installable() bool {
|
|||||||
return c.installer != nil && !c.Properties.PreventInstall && c.IsForPlatform() && c.outputFile.Valid()
|
return c.installer != nil && !c.Properties.PreventInstall && c.IsForPlatform() && c.outputFile.Valid()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
@@ -51,6 +51,8 @@ type LinkableInterface interface {
|
|||||||
ToolchainLibrary() bool
|
ToolchainLibrary() bool
|
||||||
NdkPrebuiltStl() bool
|
NdkPrebuiltStl() bool
|
||||||
StubDecorator() bool
|
StubDecorator() bool
|
||||||
|
|
||||||
|
AllStaticDeps() []string
|
||||||
}
|
}
|
||||||
|
|
||||||
type DependencyTag struct {
|
type DependencyTag struct {
|
||||||
|
@@ -492,6 +492,14 @@ var (
|
|||||||
usesLibTag = dependencyTag{name: "uses-library"}
|
usesLibTag = dependencyTag{name: "uses-library"}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func IsLibDepTag(depTag blueprint.DependencyTag) bool {
|
||||||
|
return depTag == libTag
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsStaticLibDepTag(depTag blueprint.DependencyTag) bool {
|
||||||
|
return depTag == staticLibTag
|
||||||
|
}
|
||||||
|
|
||||||
type sdkDep struct {
|
type sdkDep struct {
|
||||||
useModule, useFiles, useDefaultLibs, invalidVersion bool
|
useModule, useFiles, useDefaultLibs, invalidVersion bool
|
||||||
|
|
||||||
|
@@ -346,6 +346,11 @@ 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