From a747d2ec486415f80c7b0724fad62f5575d08853 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Mon, 11 Mar 2024 21:37:25 +0000 Subject: [PATCH] Generate info about the selected apex variant in platform builds out/soong/prebuilt_info.json will contain information about whether source or prebuilt of an apex was used. If prebuilt is used, it will print the path to its prebuilt_info file. This file will be used to pick a matching set of MTS test prebuilts. Each apex will have an entry in this file with the following properties - Name, mandatory - Is_prebuilt, mandatory - Prebuilt_info_file_path, optional Implementation details - Introduce a new `prebuilt_info` prop to `apex_set` and `prebuilt_apex` - All apex module types will set a prebuiltInfoProvider in GenerateAndroidBuildActions, including the source apex module types - Create a `apex_prebuiltinfo_singleton` that visits all apex modules. It uses `IsHideFromMake` to filter out the unselected variants of a specific apex. This new singleton will create prebuilt_info.json - Dist prebuilt_info.json for droidcore Test: m nothing --no-skip-soong-tests Test: m out/soong/prebuilt_info.json Test: ls -l out/soong/prebuilt_info.json --human-readable -rw------- 1 spandandas primarygroup 25K Mar 11 23:46 out/soong/prebuilt_info.json Test: #modified trunk_staging.locally to select prebuilts of some mainline modules. Spot-checked that `is_prebuilt` and `prebuilt_info_file_path` get populated appropriately Bug: 327480225 Change-Id: I65c73010142b034ad1d2b3d05ef493be034e8d74 --- apex/apex.go | 27 +++++++++++++++++++++++++++ apex/apex_singleton.go | 42 ++++++++++++++++++++++++++++++++++++++++++ apex/prebuilt.go | 23 +++++++++++++++++++++++ 3 files changed, 92 insertions(+) diff --git a/apex/apex.go b/apex/apex.go index 9d7af189b..c6884387a 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2424,6 +2424,33 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Set a provider for dexpreopt of bootjars a.provideApexExportsInfo(ctx) + + a.providePrebuiltInfo(ctx) +} + +var prebuiltInfoProvider = blueprint.NewProvider[prebuiltInfo]() + +// contents of prebuilt_info.json +type prebuiltInfo struct { + // Name of the apex, without the prebuilt_ prefix + Name string + + Is_prebuilt bool + + // This is relative to root of the workspace. + // In case of mainline modules, this file contains the build_id that was used + // to generate the mainline module prebuilt. + Prebuilt_info_file_path string `json:",omitempty"` +} + +// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file +// with information about whether source or prebuilt of an apex was used during the build. +func (a *apexBundle) providePrebuiltInfo(ctx android.ModuleContext) { + info := prebuiltInfo{ + Name: a.Name(), + Is_prebuilt: false, + } + android.SetProvider(ctx, prebuiltInfoProvider, info) } // Set a provider containing information about the jars and .prof provided by the apex diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go index 25c0cc444..8aaddbe25 100644 --- a/apex/apex_singleton.go +++ b/apex/apex_singleton.go @@ -17,6 +17,8 @@ package apex import ( + "encoding/json" + "github.com/google/blueprint" "android/soong/android" @@ -129,3 +131,43 @@ func (s *apexDepsInfoSingleton) MakeVars(ctx android.MakeVarsContext) { // Export check result to Make. The path is added to droidcore. ctx.Strict("APEX_ALLOWED_DEPS_CHECK", s.allowedApexDepsInfoCheckResult.String()) } + +func init() { + registerApexPrebuiltInfoComponents(android.InitRegistrationContext) +} + +func registerApexPrebuiltInfoComponents(ctx android.RegistrationContext) { + ctx.RegisterParallelSingletonType("apex_prebuiltinfo_singleton", apexPrebuiltInfoFactory) +} + +func apexPrebuiltInfoFactory() android.Singleton { + return &apexPrebuiltInfo{} +} + +type apexPrebuiltInfo struct { + out android.WritablePath +} + +func (a *apexPrebuiltInfo) GenerateBuildActions(ctx android.SingletonContext) { + prebuiltInfos := []prebuiltInfo{} + + ctx.VisitAllModules(func(m android.Module) { + prebuiltInfo, exists := android.SingletonModuleProvider(ctx, m, prebuiltInfoProvider) + // Use prebuiltInfoProvider to filter out non apex soong modules. + // Use HideFromMake to filter out the unselected variants of a specific apex. + if exists && !m.IsHideFromMake() { + prebuiltInfos = append(prebuiltInfos, prebuiltInfo) + } + }) + + j, err := json.Marshal(prebuiltInfos) + if err != nil { + ctx.Errorf("Could not convert prebuilt info of apexes to json due to error: %v", err) + } + a.out = android.PathForOutput(ctx, "prebuilt_info.json") + android.WriteFileRule(ctx, a.out, string(j)) +} + +func (a *apexPrebuiltInfo) MakeVars(ctx android.MakeVarsContext) { + ctx.DistForGoal("droidcore", a.out) +} diff --git a/apex/prebuilt.go b/apex/prebuilt.go index cebbae9a6..34dfc467b 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -121,6 +121,11 @@ type PrebuiltCommonProperties struct { // List of systemserverclasspath fragments inside this prebuilt APEX bundle and for which this // APEX bundle will create an APEX variant. Exported_systemserverclasspath_fragments []string + + // Path to the .prebuilt_info file of the prebuilt apex. + // In case of mainline modules, the .prebuilt_info file contains the build_id that was used to + // generate the prebuilt. + Prebuilt_info *string `android:"path"` } // initPrebuiltCommon initializes the prebuiltCommon structure and performs initialization of the @@ -819,6 +824,20 @@ func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext) { } } +// Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file +// with information about whether source or prebuilt of an apex was used during the build. +func (p *prebuiltCommon) providePrebuiltInfo(ctx android.ModuleContext) { + info := prebuiltInfo{ + Name: p.BaseModuleName(), // BaseModuleName ensures that this will not contain the prebuilt_ prefix. + Is_prebuilt: true, + } + // If Prebuilt_info information is available in the soong module definition, add it to prebuilt_info.json. + if p.prebuiltCommonProperties.Prebuilt_info != nil { + info.Prebuilt_info_file_path = android.PathForModuleSrc(ctx, *p.prebuiltCommonProperties.Prebuilt_info).String() + } + android.SetProvider(ctx, prebuiltInfoProvider, info) +} + func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.apexKeysPath = writeApexKeys(ctx, p) // TODO(jungjw): Check the key validity. @@ -846,6 +865,8 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { // provide info used for generating the boot image p.provideApexExportsInfo(ctx) + p.providePrebuiltInfo(ctx) + // Save the files that need to be made available to Make. p.initApexFilesForAndroidMk(ctx) @@ -1068,6 +1089,8 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { // provide info used for generating the boot image a.provideApexExportsInfo(ctx) + a.providePrebuiltInfo(ctx) + // Save the files that need to be made available to Make. a.initApexFilesForAndroidMk(ctx)