Add bazel-built modules as deps on the system image

These bazel-built modules will be installed into the system image
as part of the bazel rule, rather than going through the make staging
directory.

Bug: 297269187
Test: m bazel_sandwich
Change-Id: I96c6e58f8e0898b2ad92cb7069745ca2059a39f8
This commit is contained in:
Cole Faust
2023-10-13 11:32:14 -07:00
parent 03787bea6d
commit 11edf557b6
11 changed files with 300 additions and 123 deletions

View File

@@ -81,6 +81,11 @@ type BazelConversionStatus struct {
// If non-nil, indicates that the module could not be converted successfully // If non-nil, indicates that the module could not be converted successfully
// with bp2build. This will describe the reason the module could not be converted. // with bp2build. This will describe the reason the module could not be converted.
UnconvertedReason *UnconvertedReason UnconvertedReason *UnconvertedReason
// The Partition this module will be installed on.
// TODO(b/306200980) Investigate how to handle modules that are installed in multiple
// partitions.
Partition string `blueprint:"mutated"`
} }
// The reason a module could not be converted to a BUILD target via bp2build. // The reason a module could not be converted to a BUILD target via bp2build.
@@ -674,6 +679,9 @@ func bp2buildConversionMutator(ctx BottomUpMutatorContext) {
bModule.ConvertWithBp2build(ctx) bModule.ConvertWithBp2build(ctx)
installCtx := &baseModuleContextToModuleInstallPathContext{ctx}
ctx.Module().base().setPartitionForBp2build(modulePartition(installCtx, true))
if len(ctx.Module().base().Bp2buildTargets()) == 0 && ctx.Module().base().GetUnconvertedReason() == nil { if len(ctx.Module().base().Bp2buildTargets()) == 0 && ctx.Module().base().GetUnconvertedReason() == nil {
panic(fmt.Errorf("illegal bp2build invariant: module '%s' was neither converted nor marked unconvertible", ctx.ModuleName())) panic(fmt.Errorf("illegal bp2build invariant: module '%s' was neither converted nor marked unconvertible", ctx.ModuleName()))
} }

View File

@@ -245,6 +245,55 @@ type noopBazelContext struct{}
var _ BazelContext = noopBazelContext{} var _ BazelContext = noopBazelContext{}
func (n noopBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) {
panic("unimplemented")
}
func (n noopBazelContext) QueueBazelSandwichCqueryRequests(config Config) error {
panic("unimplemented")
}
func (n noopBazelContext) GetOutputFiles(_ string, _ configKey) ([]string, error) {
panic("unimplemented")
}
func (n noopBazelContext) GetCcInfo(_ string, _ configKey) (cquery.CcInfo, error) {
panic("unimplemented")
}
func (n noopBazelContext) GetApexInfo(_ string, _ configKey) (cquery.ApexInfo, error) {
panic("unimplemented")
}
func (n noopBazelContext) GetCcUnstrippedInfo(_ string, _ configKey) (cquery.CcUnstrippedInfo, error) {
//TODO implement me
panic("implement me")
}
func (n noopBazelContext) GetPrebuiltFileInfo(_ string, _ configKey) (cquery.PrebuiltFileInfo, error) {
panic("implement me")
}
func (n noopBazelContext) InvokeBazel(_ Config, _ invokeBazelContext) error {
panic("unimplemented")
}
func (m noopBazelContext) OutputBase() string {
return ""
}
func (n noopBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
return false
}
func (m noopBazelContext) BuildStatementsToRegister() []*bazel.BuildStatement {
return []*bazel.BuildStatement{}
}
func (m noopBazelContext) AqueryDepsets() []bazel.AqueryDepset {
return []bazel.AqueryDepset{}
}
// A bazel context to use for tests. // A bazel context to use for tests.
type MockBazelContext struct { type MockBazelContext struct {
OutputBaseDir string OutputBaseDir string
@@ -427,55 +476,6 @@ func (bazelCtx *mixedBuildBazelContext) GetPrebuiltFileInfo(label string, cfgKey
return cquery.PrebuiltFileInfo{}, fmt.Errorf("no bazel response for %s", key) return cquery.PrebuiltFileInfo{}, fmt.Errorf("no bazel response for %s", key)
} }
func (n noopBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) {
panic("unimplemented")
}
func (n noopBazelContext) QueueBazelSandwichCqueryRequests(config Config) error {
panic("unimplemented")
}
func (n noopBazelContext) GetOutputFiles(_ string, _ configKey) ([]string, error) {
panic("unimplemented")
}
func (n noopBazelContext) GetCcInfo(_ string, _ configKey) (cquery.CcInfo, error) {
panic("unimplemented")
}
func (n noopBazelContext) GetApexInfo(_ string, _ configKey) (cquery.ApexInfo, error) {
panic("unimplemented")
}
func (n noopBazelContext) GetCcUnstrippedInfo(_ string, _ configKey) (cquery.CcUnstrippedInfo, error) {
//TODO implement me
panic("implement me")
}
func (n noopBazelContext) GetPrebuiltFileInfo(_ string, _ configKey) (cquery.PrebuiltFileInfo, error) {
panic("implement me")
}
func (n noopBazelContext) InvokeBazel(_ Config, _ invokeBazelContext) error {
panic("unimplemented")
}
func (m noopBazelContext) OutputBase() string {
return ""
}
func (n noopBazelContext) IsModuleNameAllowed(_ string, _ bool) bool {
return false
}
func (m noopBazelContext) BuildStatementsToRegister() []*bazel.BuildStatement {
return []*bazel.BuildStatement{}
}
func (m noopBazelContext) AqueryDepsets() []bazel.AqueryDepset {
return []bazel.AqueryDepset{}
}
func AddToStringSet(set map[string]bool, items []string) { func AddToStringSet(set map[string]bool, items []string) {
for _, item := range items { for _, item := range items {
set[item] = true set[item] = true

View File

@@ -900,6 +900,10 @@ func (c *config) KatiEnabled() bool {
return c.katiEnabled return c.katiEnabled
} }
func (c *config) ProductVariables() ProductVariables {
return c.productVariables
}
func (c *config) BuildId() string { func (c *config) BuildId() string {
return String(c.productVariables.BuildId) return String(c.productVariables.BuildId)
} }

View File

@@ -572,6 +572,7 @@ type Module interface {
Bp2buildTargets() []bp2buildInfo Bp2buildTargets() []bp2buildInfo
GetUnconvertedBp2buildDeps() []string GetUnconvertedBp2buildDeps() []string
GetMissingBp2buildDeps() []string GetMissingBp2buildDeps() []string
GetPartitionForBp2build() string
BuildParamsForTests() []BuildParams BuildParamsForTests() []BuildParams
RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams RuleParamsForTests() map[blueprint.Rule]blueprint.RuleParams
@@ -1651,6 +1652,10 @@ func (m *ModuleBase) addBp2buildInfo(info bp2buildInfo) {
m.commonProperties.BazelConversionStatus.Bp2buildInfo = append(m.commonProperties.BazelConversionStatus.Bp2buildInfo, info) m.commonProperties.BazelConversionStatus.Bp2buildInfo = append(m.commonProperties.BazelConversionStatus.Bp2buildInfo, info)
} }
func (m *ModuleBase) setPartitionForBp2build(partition string) {
m.commonProperties.BazelConversionStatus.Partition = partition
}
func (m *ModuleBase) setBp2buildUnconvertible(reasonType bp2build_metrics_proto.UnconvertedReasonType, detail string) { func (m *ModuleBase) setBp2buildUnconvertible(reasonType bp2build_metrics_proto.UnconvertedReasonType, detail string) {
m.commonProperties.BazelConversionStatus.UnconvertedReason = &UnconvertedReason{ m.commonProperties.BazelConversionStatus.UnconvertedReason = &UnconvertedReason{
ReasonType: int(reasonType), ReasonType: int(reasonType),
@@ -1667,6 +1672,11 @@ func (m *ModuleBase) Bp2buildTargets() []bp2buildInfo {
return m.commonProperties.BazelConversionStatus.Bp2buildInfo return m.commonProperties.BazelConversionStatus.Bp2buildInfo
} }
// Bp2buildTargets returns the Bazel targets bp2build generated for this module.
func (m *ModuleBase) GetPartitionForBp2build() string {
return m.commonProperties.BazelConversionStatus.Partition
}
// AddUnconvertedBp2buildDep stores module name of a dependency that was not converted to Bazel. // AddUnconvertedBp2buildDep stores module name of a dependency that was not converted to Bazel.
func (b *baseModuleContext) AddUnconvertedBp2buildDep(dep string) { func (b *baseModuleContext) AddUnconvertedBp2buildDep(dep string) {
unconvertedDeps := &b.Module().base().commonProperties.BazelConversionStatus.UnconvertedDeps unconvertedDeps := &b.Module().base().commonProperties.BazelConversionStatus.UnconvertedDeps

View File

@@ -116,6 +116,48 @@ type ModuleInstallPathContext interface {
var _ ModuleInstallPathContext = ModuleContext(nil) var _ ModuleInstallPathContext = ModuleContext(nil)
type baseModuleContextToModuleInstallPathContext struct {
BaseModuleContext
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallInData() bool {
return ctx.Module().InstallInData()
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallInTestcases() bool {
return ctx.Module().InstallInTestcases()
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallInSanitizerDir() bool {
return ctx.Module().InstallInSanitizerDir()
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallInRamdisk() bool {
return ctx.Module().InstallInRamdisk()
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallInVendorRamdisk() bool {
return ctx.Module().InstallInVendorRamdisk()
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallInDebugRamdisk() bool {
return ctx.Module().InstallInDebugRamdisk()
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallInRecovery() bool {
return ctx.Module().InstallInRecovery()
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallInRoot() bool {
return ctx.Module().InstallInRoot()
}
func (ctx *baseModuleContextToModuleInstallPathContext) InstallForceOS() (*OsType, *ArchType) {
return ctx.Module().InstallForceOS()
}
var _ ModuleInstallPathContext = (*baseModuleContextToModuleInstallPathContext)(nil)
// errorfContext is the interface containing the Errorf method matching the // errorfContext is the interface containing the Errorf method matching the
// Errorf method in blueprint.SingletonContext. // Errorf method in blueprint.SingletonContext.
type errorfContext interface { type errorfContext interface {
@@ -1683,7 +1725,7 @@ func (p InstallPath) ToMakePath() InstallPath {
// module appended with paths... // module appended with paths...
func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string) InstallPath { func PathForModuleInstall(ctx ModuleInstallPathContext, pathComponents ...string) InstallPath {
os, arch := osAndArch(ctx) os, arch := osAndArch(ctx)
partition := modulePartition(ctx, os) partition := modulePartition(ctx, os.Class == Device)
return pathForInstall(ctx, os, arch, partition, pathComponents...) return pathForInstall(ctx, os, arch, partition, pathComponents...)
} }
@@ -1785,12 +1827,12 @@ func InstallPathToOnDevicePath(ctx PathContext, path InstallPath) string {
return "/" + rel return "/" + rel
} }
func modulePartition(ctx ModuleInstallPathContext, os OsType) string { func modulePartition(ctx ModuleInstallPathContext, device bool) string {
var partition string var partition string
if ctx.InstallInTestcases() { if ctx.InstallInTestcases() {
// "testcases" install directory can be used for host or device modules. // "testcases" install directory can be used for host or device modules.
partition = "testcases" partition = "testcases"
} else if os.Class == Device { } else if device {
if ctx.InstallInData() { if ctx.InstallInData() {
partition = "data" partition = "data"
} else if ctx.InstallInRamdisk() { } else if ctx.InstallInRamdisk() {

View File

@@ -494,9 +494,7 @@ type ProductVariables struct {
Release_expose_flagged_api *bool `json:",omitempty"` Release_expose_flagged_api *bool `json:",omitempty"`
} }
type PartitionVariables struct { type PartitionQualifiedVariablesType struct {
ProductDirectory string `json:",omitempty"`
PartitionQualifiedVariables map[string]struct {
BuildingImage bool `json:",omitempty"` BuildingImage bool `json:",omitempty"`
BoardErofsCompressor string `json:",omitempty"` BoardErofsCompressor string `json:",omitempty"`
BoardErofsCompressHints string `json:",omitempty"` BoardErofsCompressHints string `json:",omitempty"`
@@ -523,6 +521,10 @@ type PartitionVariables struct {
BoardAvbRollbackIndex string `json:",omitempty"` BoardAvbRollbackIndex string `json:",omitempty"`
BoardAvbRollbackIndexLocation string `json:",omitempty"` BoardAvbRollbackIndexLocation string `json:",omitempty"`
} }
type PartitionVariables struct {
ProductDirectory string `json:",omitempty"`
PartitionQualifiedVariables map[string]PartitionQualifiedVariablesType
TargetUserimagesUseExt2 bool `json:",omitempty"` TargetUserimagesUseExt2 bool `json:",omitempty"`
TargetUserimagesUseExt3 bool `json:",omitempty"` TargetUserimagesUseExt3 bool `json:",omitempty"`
TargetUserimagesUseExt4 bool `json:",omitempty"` TargetUserimagesUseExt4 bool `json:",omitempty"`
@@ -546,6 +548,8 @@ type PartitionVariables struct {
CopyImagesForTargetFilesZip bool `json:",omitempty"` CopyImagesForTargetFilesZip bool `json:",omitempty"`
BoardAvbEnable bool `json:",omitempty"` BoardAvbEnable bool `json:",omitempty"`
ProductPackages []string `json:",omitempty"`
} }
func boolPtr(v bool) *bool { func boolPtr(v bool) *bool {

View File

@@ -82,7 +82,7 @@ func Codegen(ctx *CodegenContext) *CodegenMetrics {
os.Exit(1) os.Exit(1)
} }
var bp2buildFiles []BazelFile var bp2buildFiles []BazelFile
productConfig, err := createProductConfigFiles(ctx, res.metrics) productConfig, err := createProductConfigFiles(ctx, res.moduleNameToPartition, res.metrics.convertedModulePathMap)
ctx.Context().EventHandler.Do("CreateBazelFile", func() { ctx.Context().EventHandler.Do("CreateBazelFile", func() {
allTargets := make(map[string]BazelTargets) allTargets := make(map[string]BazelTargets)
for k, v := range res.buildFileToTargets { for k, v := range res.buildFileToTargets {

View File

@@ -3,7 +3,6 @@ package bp2build
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"sort" "sort"
@@ -53,7 +52,8 @@ func (l *bazelLabel) String() string {
func createProductConfigFiles( func createProductConfigFiles(
ctx *CodegenContext, ctx *CodegenContext,
metrics CodegenMetrics) (createProductConfigFilesResult, error) { moduleNameToPartition map[string]string,
convertedModulePathMap map[string]string) (createProductConfigFilesResult, error) {
cfg := &ctx.config cfg := &ctx.config
targetProduct := "unknown" targetProduct := "unknown"
if cfg.HasDeviceProduct() { if cfg.HasDeviceProduct() {
@@ -68,16 +68,11 @@ func createProductConfigFiles(
var res createProductConfigFilesResult var res createProductConfigFilesResult
productVariablesFileName := cfg.ProductVariablesFileName productVariables := ctx.Config().ProductVariables()
if !strings.HasPrefix(productVariablesFileName, "/") { // TODO(b/306243251): For some reason, using the real value of native_coverage makes some select
productVariablesFileName = filepath.Join(ctx.topDir, productVariablesFileName) // statements ambiguous
} productVariables.Native_coverage = nil
productVariablesBytes, err := os.ReadFile(productVariablesFileName) productVariablesBytes, err := json.Marshal(productVariables)
if err != nil {
return res, err
}
productVariables := android.ProductVariables{}
err = json.Unmarshal(productVariablesBytes, &productVariables)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -142,12 +137,12 @@ func createProductConfigFiles(
}, },
}, },
}) })
createTargets(productLabelsToVariables, res.bp2buildTargets) createTargets(ctx, productLabelsToVariables, moduleNameToPartition, convertedModulePathMap, res.bp2buildTargets)
platformMappingContent, err := platformMappingContent( platformMappingContent, err := platformMappingContent(
productLabelsToVariables, productLabelsToVariables,
ctx.Config().Bp2buildSoongConfigDefinitions, ctx.Config().Bp2buildSoongConfigDefinitions,
metrics.convertedModulePathMap) convertedModulePathMap)
if err != nil { if err != nil {
return res, err return res, err
} }
@@ -481,12 +476,17 @@ func starlarkMapToProductVariables(in map[string]starlark.Value) (android.Produc
return result, nil return result, nil
} }
func createTargets(productLabelsToVariables map[bazelLabel]*android.ProductVariables, res map[string]BazelTargets) { func createTargets(
ctx *CodegenContext,
productLabelsToVariables map[bazelLabel]*android.ProductVariables,
moduleNameToPartition map[string]string,
convertedModulePathMap map[string]string,
res map[string]BazelTargets) {
createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res) createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res)
createAvbKeyFilegroups(productLabelsToVariables, res) createAvbKeyFilegroups(productLabelsToVariables, res)
createReleaseAconfigValueSetsFilegroup(productLabelsToVariables, res) createReleaseAconfigValueSetsFilegroup(productLabelsToVariables, res)
for label, variables := range productLabelsToVariables { for label, variables := range productLabelsToVariables {
createSystemPartition(label, &variables.PartitionVarsForBazelMigrationOnlyDoNotUse, res) createSystemPartition(ctx, label, &variables.PartitionVarsForBazelMigrationOnlyDoNotUse, moduleNameToPartition, convertedModulePathMap, res)
} }
} }
@@ -581,7 +581,13 @@ func createAvbKeyFilegroups(productLabelsToVariables map[bazelLabel]*android.Pro
} }
} }
func createSystemPartition(platformLabel bazelLabel, variables *android.PartitionVariables, targets map[string]BazelTargets) { func createSystemPartition(
ctx *CodegenContext,
platformLabel bazelLabel,
variables *android.PartitionVariables,
moduleNameToPartition map[string]string,
convertedModulePathMap map[string]string,
targets map[string]BazelTargets) {
if !variables.PartitionQualifiedVariables["system"].BuildingImage { if !variables.PartitionQualifiedVariables["system"].BuildingImage {
return return
} }
@@ -611,6 +617,26 @@ func createSystemPartition(platformLabel bazelLabel, variables *android.Partitio
} }
} }
var deps []string
for _, mod := range variables.ProductPackages {
if path, ok := convertedModulePathMap[mod]; ok && ctx.Config().BazelContext.IsModuleNameAllowed(mod, false) {
if partition, ok := moduleNameToPartition[mod]; ok && partition == "system" {
if path == "//." {
path = "//"
}
deps = append(deps, fmt.Sprintf(" \"%s:%s\",\n", path, mod))
}
}
}
if len(deps) > 0 {
sort.Strings(deps)
extraProperties.WriteString(" deps = [\n")
for _, dep := range deps {
extraProperties.WriteString(dep)
}
extraProperties.WriteString(" ],\n")
}
targets[platformLabel.pkg] = append(targets[platformLabel.pkg], BazelTarget{ targets[platformLabel.pkg] = append(targets[platformLabel.pkg], BazelTarget{
name: "system_image", name: "system_image",
packageName: platformLabel.pkg, packageName: platformLabel.pkg,

View File

@@ -2,6 +2,7 @@ package bp2build
import ( import (
"android/soong/android" "android/soong/android"
"android/soong/cc"
"android/soong/starlark_import" "android/soong/starlark_import"
"encoding/json" "encoding/json"
"reflect" "reflect"
@@ -87,3 +88,67 @@ func TestStarlarkMapToProductVariables(t *testing.T) {
} }
} }
} }
func TestSystemPartitionDeps(t *testing.T) {
RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
}, Bp2buildTestCase{
ExtraFixturePreparer: android.GroupFixturePreparers(
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
deviceProduct := "aosp_arm64"
variables.DeviceProduct = &deviceProduct
partitionVars := &variables.PartitionVarsForBazelMigrationOnlyDoNotUse
partitionVars.ProductDirectory = "build/make/target/product/"
partitionVars.ProductPackages = []string{"foo"}
var systemVars android.PartitionQualifiedVariablesType
systemVars.BuildingImage = true
partitionVars.PartitionQualifiedVariables = map[string]android.PartitionQualifiedVariablesType{
"system": systemVars,
}
}),
android.FixtureModifyConfig(func(config android.Config) {
// MockBazelContext will pretend everything is mixed-builds allowlisted.
// The default is noopBazelContext, which does the opposite.
config.BazelContext = android.MockBazelContext{}
}),
),
Blueprint: `
cc_library {
name: "foo",
}`,
ExpectedBazelTargets: []string{`android_product(
name = "aosp_arm64",
soong_variables = _soong_variables,
)`, `partition(
name = "system_image",
base_staging_dir = "//build/bazel/bazel_sandwich:system_staging_dir",
base_staging_dir_file_list = "//build/bazel/bazel_sandwich:system_staging_dir_file_list",
root_dir = "//build/bazel/bazel_sandwich:root_staging_dir",
selinux_file_contexts = "//build/bazel/bazel_sandwich:selinux_file_contexts",
image_properties = """
building_system_image=true
erofs_sparse_flag=-s
extfs_sparse_flag=-s
f2fs_sparse_flag=-S
skip_fsck=true
squashfs_sparse_flag=-s
system_disable_sparse=true
""",
deps = [
"//:foo",
],
type = "system",
)`, `partition_diff_test(
name = "system_image_test",
partition1 = "//build/bazel/bazel_sandwich:make_system_image",
partition2 = ":system_image",
)`, `run_test_in_build(
name = "run_system_image_test",
test = ":system_image_test",
)`},
Dir: "build/make/target/product/aosp_arm64",
RunBp2buildProductConfig: true,
})
}

View File

@@ -280,6 +280,7 @@ func propsToAttributes(props map[string]string) string {
type conversionResults struct { type conversionResults struct {
buildFileToTargets map[string]BazelTargets buildFileToTargets map[string]BazelTargets
moduleNameToPartition map[string]string
metrics CodegenMetrics metrics CodegenMetrics
} }
@@ -707,6 +708,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
metrics := CreateCodegenMetrics() metrics := CreateCodegenMetrics()
dirs := make(map[string]bool) dirs := make(map[string]bool)
moduleNameToPartition := make(map[string]string)
var errs []error var errs []error
@@ -754,6 +756,9 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
metrics.IncrementRuleClassCount(t.ruleClass) metrics.IncrementRuleClassCount(t.ruleClass)
} }
// record the partition
moduleNameToPartition[android.RemoveOptionalPrebuiltPrefix(aModule.Name())] = aModule.GetPartitionForBp2build()
// Log the module. // Log the module.
metrics.AddConvertedModule(aModule, moduleType, dir) metrics.AddConvertedModule(aModule, moduleType, dir)
@@ -877,6 +882,7 @@ func GenerateBazelTargets(ctx *CodegenContext, generateFilegroups bool) (convers
return conversionResults{ return conversionResults{
buildFileToTargets: buildFileToTargets, buildFileToTargets: buildFileToTargets,
moduleNameToPartition: moduleNameToPartition,
metrics: metrics, metrics: metrics,
}, errs }, errs
} }

View File

@@ -28,6 +28,7 @@ import (
"testing" "testing"
"android/soong/ui/metrics/bp2build_metrics_proto" "android/soong/ui/metrics/bp2build_metrics_proto"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
"android/soong/android" "android/soong/android"
@@ -124,26 +125,28 @@ type Bp2buildTestCase struct {
// be merged with the generated BUILD file. This allows custom BUILD targets // be merged with the generated BUILD file. This allows custom BUILD targets
// to be used in tests, or use BUILD files to draw package boundaries. // to be used in tests, or use BUILD files to draw package boundaries.
KeepBuildFileForDirs []string KeepBuildFileForDirs []string
}
func RunBp2BuildTestCaseExtraContext(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), modifyContext func(ctx *android.TestContext), tc Bp2buildTestCase) { // An extra FixturePreparer to use when running the test. If you need multiple extra
t.Helper() // FixturePreparers, use android.GroupFixturePreparers()
preparers := []android.FixturePreparer{ ExtraFixturePreparer android.FixturePreparer
android.FixtureRegisterWithContext(registerModuleTypes),
} // If bp2build_product_config.go should run as part of the test.
if modifyContext != nil { RunBp2buildProductConfig bool
preparers = append(preparers, android.FixtureModifyContext(modifyContext))
}
preparers = append(preparers, SetBp2BuildTestRunner)
bp2buildSetup := android.GroupFixturePreparers(
preparers...,
)
runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
} }
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) { func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
t.Helper() t.Helper()
RunBp2BuildTestCaseExtraContext(t, registerModuleTypes, nil, tc) preparers := []android.FixturePreparer{
android.FixtureRegisterWithContext(registerModuleTypes),
}
if tc.ExtraFixturePreparer != nil {
preparers = append(preparers, tc.ExtraFixturePreparer)
}
preparers = append(preparers, android.FixtureSetTestRunner(&bazelTestRunner{generateProductConfigTargets: tc.RunBp2buildProductConfig}))
bp2buildSetup := android.GroupFixturePreparers(
preparers...,
)
runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
} }
func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) { func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
@@ -247,11 +250,10 @@ func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePre
result.CompareAllBazelTargets(t, tc, expectedTargets, true) result.CompareAllBazelTargets(t, tc, expectedTargets, true)
} }
// SetBp2BuildTestRunner customizes the test fixture mechanism to run tests in Bp2Build mode.
var SetBp2BuildTestRunner = android.FixtureSetTestRunner(&bazelTestRunner{})
// bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build build mode. // bazelTestRunner customizes the test fixture mechanism to run tests of the bp2build build mode.
type bazelTestRunner struct{} type bazelTestRunner struct {
generateProductConfigTargets bool
}
func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult { func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult {
ctx := result.TestContext ctx := result.TestContext
@@ -274,6 +276,16 @@ func (b *bazelTestRunner) PostParseProcessor(result android.CustomTestResult) {
if bazelResult.CollateErrs(errs) { if bazelResult.CollateErrs(errs) {
return return
} }
if b.generateProductConfigTargets {
productConfig, err := createProductConfigFiles(codegenCtx, res.moduleNameToPartition, res.metrics.convertedModulePathMap)
if err != nil {
bazelResult.CollateErrs([]error{err})
return
}
for k, v := range productConfig.bp2buildTargets {
res.buildFileToTargets[k] = append(res.buildFileToTargets[k], v...)
}
}
// Store additional data for access by tests. // Store additional data for access by tests.
bazelResult.conversionResults = res bazelResult.conversionResults = res