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

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

View File

@@ -3,7 +3,6 @@ package bp2build
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
"sort"
@@ -53,7 +52,8 @@ func (l *bazelLabel) String() string {
func createProductConfigFiles(
ctx *CodegenContext,
metrics CodegenMetrics) (createProductConfigFilesResult, error) {
moduleNameToPartition map[string]string,
convertedModulePathMap map[string]string) (createProductConfigFilesResult, error) {
cfg := &ctx.config
targetProduct := "unknown"
if cfg.HasDeviceProduct() {
@@ -68,16 +68,11 @@ func createProductConfigFiles(
var res createProductConfigFilesResult
productVariablesFileName := cfg.ProductVariablesFileName
if !strings.HasPrefix(productVariablesFileName, "/") {
productVariablesFileName = filepath.Join(ctx.topDir, productVariablesFileName)
}
productVariablesBytes, err := os.ReadFile(productVariablesFileName)
if err != nil {
return res, err
}
productVariables := android.ProductVariables{}
err = json.Unmarshal(productVariablesBytes, &productVariables)
productVariables := ctx.Config().ProductVariables()
// TODO(b/306243251): For some reason, using the real value of native_coverage makes some select
// statements ambiguous
productVariables.Native_coverage = nil
productVariablesBytes, err := json.Marshal(productVariables)
if err != nil {
return res, err
}
@@ -142,12 +137,12 @@ func createProductConfigFiles(
},
},
})
createTargets(productLabelsToVariables, res.bp2buildTargets)
createTargets(ctx, productLabelsToVariables, moduleNameToPartition, convertedModulePathMap, res.bp2buildTargets)
platformMappingContent, err := platformMappingContent(
productLabelsToVariables,
ctx.Config().Bp2buildSoongConfigDefinitions,
metrics.convertedModulePathMap)
convertedModulePathMap)
if err != nil {
return res, err
}
@@ -481,12 +476,17 @@ func starlarkMapToProductVariables(in map[string]starlark.Value) (android.Produc
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)
createAvbKeyFilegroups(productLabelsToVariables, res)
createReleaseAconfigValueSetsFilegroup(productLabelsToVariables, res)
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 {
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{
name: "system_image",
packageName: platformLabel.pkg,

View File

@@ -2,6 +2,7 @@ package bp2build
import (
"android/soong/android"
"android/soong/cc"
"android/soong/starlark_import"
"encoding/json"
"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

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

View File

@@ -28,6 +28,7 @@ import (
"testing"
"android/soong/ui/metrics/bp2build_metrics_proto"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -124,26 +125,28 @@ type Bp2buildTestCase struct {
// 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.
KeepBuildFileForDirs []string
}
func RunBp2BuildTestCaseExtraContext(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), modifyContext func(ctx *android.TestContext), tc Bp2buildTestCase) {
t.Helper()
preparers := []android.FixturePreparer{
android.FixtureRegisterWithContext(registerModuleTypes),
}
if modifyContext != nil {
preparers = append(preparers, android.FixtureModifyContext(modifyContext))
}
preparers = append(preparers, SetBp2BuildTestRunner)
bp2buildSetup := android.GroupFixturePreparers(
preparers...,
)
runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
// An extra FixturePreparer to use when running the test. If you need multiple extra
// FixturePreparers, use android.GroupFixturePreparers()
ExtraFixturePreparer android.FixturePreparer
// If bp2build_product_config.go should run as part of the test.
RunBp2buildProductConfig bool
}
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
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) {
@@ -247,11 +250,10 @@ func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePre
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.
type bazelTestRunner struct{}
type bazelTestRunner struct {
generateProductConfigTargets bool
}
func (b *bazelTestRunner) FinalPreparer(result *android.TestResult) android.CustomTestResult {
ctx := result.TestContext
@@ -274,6 +276,16 @@ func (b *bazelTestRunner) PostParseProcessor(result android.CustomTestResult) {
if bazelResult.CollateErrs(errs) {
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.
bazelResult.conversionResults = res