Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 57769e46 authored by satayev's avatar satayev Committed by Gerrit Code Review
Browse files

Merge "Export depsInfo into android package."

parents 0a805249 872a144d
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ import (
	"fmt"
	"sort"
	"strconv"
	"strings"
	"sync"

	"github.com/google/blueprint"
@@ -403,3 +404,52 @@ func InitApexModule(m ApexModule) {

	m.AddProperties(&base.ApexProperties)
}

// A dependency info for a single ApexModule, either direct or transitive.
type ApexModuleDepInfo struct {
	// Name of the dependency
	To string
	// List of dependencies To belongs to. Includes APEX itself, if a direct dependency.
	From []string
	// Whether the dependency belongs to the final compiled APEX.
	IsExternal bool
}

// A map of a dependency name to its ApexModuleDepInfo
type DepNameToDepInfoMap map[string]ApexModuleDepInfo

type ApexBundleDepsInfo struct {
	fullListPath OutputPath
}

type ApexDepsInfoIntf interface {
	FullListPath() Path
}

func (d *ApexBundleDepsInfo) FullListPath() Path {
	return d.fullListPath
}

var _ ApexDepsInfoIntf = (*ApexBundleDepsInfo)(nil)

func (d *ApexBundleDepsInfo) BuildDepsInfoLists(ctx ModuleContext, depInfos DepNameToDepInfoMap) {
	var content strings.Builder
	for _, key := range FirstUniqueStrings(SortedStringKeys(depInfos)) {
		info := depInfos[key]
		toName := info.To
		if info.IsExternal {
			toName = toName + " (external)"
		}
		fmt.Fprintf(&content, "%s <- %s\\n", toName, strings.Join(SortedUniqueStrings(info.From), ", "))
	}

	d.fullListPath = PathForModuleOut(ctx, "depsinfo", "fulllist.txt").OutputPath
	ctx.Build(pctx, BuildParams{
		Rule:        WriteFile,
		Description: "Full Dependency Info",
		Output:      d.fullListPath,
		Args: map[string]string{
			"content": content.String(),
		},
	})
}
+1 −37
Original line number Diff line number Diff line
@@ -1276,12 +1276,6 @@ func (af *apexFile) AvailableToPlatform() bool {
	return false
}

type depInfo struct {
	to         string
	from       []string
	isExternal bool
}

type apexBundle struct {
	android.ModuleBase
	android.DefaultableModuleBase
@@ -1316,7 +1310,7 @@ type apexBundle struct {
	requiredDeps []string

	// list of module names that this APEX is including (to be shown via *-deps-info target)
	depInfos map[string]depInfo
	android.ApexBundleDepsInfo

	testApex        bool
	vndkApex        bool
@@ -1890,35 +1884,6 @@ func (a *apexBundle) checkUpdatable(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) bool {
		if from.Name() == to.Name() {
			// This can happen for cc.reuseObjTag. We are not interested in tracking this.
			// As soon as the dependency graph crosses the APEX boundary, don't go further.
			return !externalDep
		}

		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,
			}
		}

		// As soon as the dependency graph crosses the APEX boundary, don't go further.
		return !externalDep
	})
}

func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	buildFlattenedAsDefault := ctx.Config().FlattenApex() && !ctx.Config().UnbundledBuild()
	switch a.properties.ApexType {
@@ -1956,7 +1921,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {

	a.checkApexAvailability(ctx)
	a.checkUpdatable(ctx)
	a.collectDepsInfo(ctx)

	handleSpecialLibs := !android.Bool(a.properties.Ignore_system_library_special_case)

+2 −2
Original line number Diff line number Diff line
@@ -504,7 +504,7 @@ func TestBasicApex(t *testing.T) {
	ensureListContains(t, noticeInputs, "custom_notice")
	ensureListContains(t, noticeInputs, "custom_notice_for_static_lib")

	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("depsinfo/fulllist.txt").Args["content"], "\\n")
	ensureListContains(t, depsInfo, "myjar <- myapex")
	ensureListContains(t, depsInfo, "mylib <- myapex")
	ensureListContains(t, depsInfo, "mylib2 <- mylib")
@@ -818,7 +818,7 @@ func TestApexWithExplicitStubsDependency(t *testing.T) {
	// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
	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("depsinfo/fulllist.txt").Args["content"], "\\n")

	ensureListContains(t, depsInfo, "mylib <- myapex2")
	ensureListContains(t, depsInfo, "libbaz <- mylib")
+25 −17
Original line number Diff line number Diff line
@@ -688,29 +688,37 @@ func (a *apexBundle) buildApexDependencyInfo(ctx android.ModuleContext) {
		return
	}

	var content strings.Builder
	for _, key := range android.SortedStringKeys(a.depInfos) {
		info := a.depInfos[key]
		toName := info.to
		if info.isExternal {
			toName = toName + " (external)"
	depInfos := android.DepNameToDepInfoMap{}
	a.walkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool {
		if from.Name() == to.Name() {
			// This can happen for cc.reuseObjTag. We are not interested in tracking this.
			// As soon as the dependency graph crosses the APEX boundary, don't go further.
			return !externalDep
		}

		if info, exists := depInfos[to.Name()]; exists {
			if !android.InList(from.Name(), info.From) {
				info.From = append(info.From, from.Name())
			}
			info.IsExternal = info.IsExternal && externalDep
			depInfos[to.Name()] = info
		} else {
			depInfos[to.Name()] = android.ApexModuleDepInfo{
				To:         to.Name(),
				From:       []string{from.Name()},
				IsExternal: externalDep,
			}
		fmt.Fprintf(&content, "%s <- %s\\n", toName, strings.Join(android.SortedUniqueStrings(info.from), ", "))
		}

	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(),
		},
		// As soon as the dependency graph crosses the APEX boundary, don't go further.
		return !externalDep
	})

	a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, depInfos)

	ctx.Build(pctx, android.BuildParams{
		Rule:   android.Phony,
		Output: android.PathForPhony(ctx, a.Name()+"-deps-info"),
		Inputs: []android.Path{depsInfoFile},
		Inputs: []android.Path{a.ApexBundleDepsInfo.FullListPath()},
	})
}