Support generating module_info.json in Soong

Generate module_info.json for some Soong modules in Soong in order to
pass fewer properties to Kati, which can prevent Kati reanalysis when
some Android.bp changes are made.

Soong modules can export a ModuleInfoJSONProvider containing the
data that should be included in module-info.json.  During the androidmk
singleton the providers are collected and written to a single JSON
file.  Make then merges the Soong modules into its own modules.

For now, to keep the result as similar as possible to the
module-info.json currently being generated by Make, only modules that
are exported to Make are written to the Soong module-info.json.

Bug: 309006256
Test: Compare module-info.json
Change-Id: I996520eb48e04743d43ac11c9aba0f3ada7745de
This commit is contained in:
Colin Cross
2023-11-06 13:54:06 -08:00
parent d9bbf4b424
commit d6fd013394
8 changed files with 590 additions and 24 deletions

View File

@@ -23,6 +23,7 @@ import (
"net/url"
"path/filepath"
"reflect"
"slices"
"sort"
"strings"
@@ -876,6 +877,10 @@ type ModuleBase struct {
// The path to the generated license metadata file for the module.
licenseMetadataFile WritablePath
// moduleInfoJSON can be filled out by GenerateAndroidBuildActions to write a JSON file that will
// be included in the final module-info.json produced by Make.
moduleInfoJSON *ModuleInfoJSON
}
func (m *ModuleBase) AddJSONData(d *map[string]interface{}) {
@@ -1771,11 +1776,90 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext)
buildLicenseMetadata(ctx, m.licenseMetadataFile)
if m.moduleInfoJSON != nil {
var installed InstallPaths
installed = append(installed, m.katiInstalls.InstallPaths()...)
installed = append(installed, m.katiSymlinks.InstallPaths()...)
installed = append(installed, m.katiInitRcInstalls.InstallPaths()...)
installed = append(installed, m.katiVintfInstalls.InstallPaths()...)
installedStrings := installed.Strings()
var targetRequired, hostRequired []string
if ctx.Host() {
targetRequired = m.commonProperties.Target_required
} else {
hostRequired = m.commonProperties.Host_required
}
var data []string
for _, d := range m.testData {
data = append(data, d.ToRelativeInstallPath())
}
if m.moduleInfoJSON.Uninstallable {
installedStrings = nil
if len(m.moduleInfoJSON.CompatibilitySuites) == 1 && m.moduleInfoJSON.CompatibilitySuites[0] == "null-suite" {
m.moduleInfoJSON.CompatibilitySuites = nil
m.moduleInfoJSON.TestConfig = nil
m.moduleInfoJSON.AutoTestConfig = nil
data = nil
}
}
m.moduleInfoJSON.core = CoreModuleInfoJSON{
RegisterName: m.moduleInfoRegisterName(ctx, m.moduleInfoJSON.SubName),
Path: []string{ctx.ModuleDir()},
Installed: installedStrings,
ModuleName: m.BaseModuleName() + m.moduleInfoJSON.SubName,
SupportedVariants: []string{m.moduleInfoVariant(ctx)},
TargetDependencies: targetRequired,
HostDependencies: hostRequired,
Data: data,
}
SetProvider(ctx, ModuleInfoJSONProvider, m.moduleInfoJSON)
}
m.buildParams = ctx.buildParams
m.ruleParams = ctx.ruleParams
m.variables = ctx.variables
}
func (m *ModuleBase) moduleInfoRegisterName(ctx ModuleContext, subName string) string {
name := m.BaseModuleName()
prefix := ""
if ctx.Host() {
if ctx.Os() != ctx.Config().BuildOS {
prefix = "host_cross_"
}
}
suffix := ""
arches := slices.Clone(ctx.Config().Targets[ctx.Os()])
arches = slices.DeleteFunc(arches, func(target Target) bool {
return target.NativeBridge != ctx.Target().NativeBridge
})
if len(arches) > 0 && ctx.Arch().ArchType != arches[0].Arch.ArchType {
if ctx.Arch().ArchType.Multilib == "lib32" {
suffix = "_32"
} else {
suffix = "_64"
}
}
return prefix + name + subName + suffix
}
func (m *ModuleBase) moduleInfoVariant(ctx ModuleContext) string {
variant := "DEVICE"
if ctx.Host() {
if ctx.Os() != ctx.Config().BuildOS {
variant = "HOST_CROSS"
} else {
variant = "HOST"
}
}
return variant
}
// Check the supplied dist structure to make sure that it is valid.
//
// property - the base property, e.g. dist or dists[1], which is combined with the