Platform mapping-based product config
This allows us to set product variables as build settings instead
of loading them from a target's provider, which further allows us
to read product config variables in transitions.
Bug: 287539062
Bug: 269577299
Test: Presubmits
Change-Id: I8497703f706162572ceb3486240e1eb02a37f5f6
diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go
index 7224496..8d5c99c 100644
--- a/bp2build/bp2build_product_config.go
+++ b/bp2build/bp2build_product_config.go
@@ -1,14 +1,20 @@
package bp2build
import (
+ "android/soong/android"
+ "android/soong/starlark_import"
+ "encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
+
+ "github.com/google/blueprint/proptools"
+ "go.starlark.net/starlark"
)
func CreateProductConfigFiles(
- ctx *CodegenContext) ([]BazelFile, error) {
+ ctx *CodegenContext) ([]BazelFile, []BazelFile, error) {
cfg := &ctx.config
targetProduct := "unknown"
if cfg.HasDeviceProduct() {
@@ -25,9 +31,14 @@
if !strings.HasPrefix(productVariablesFileName, "/") {
productVariablesFileName = filepath.Join(ctx.topDir, productVariablesFileName)
}
- bytes, err := os.ReadFile(productVariablesFileName)
+ productVariablesBytes, err := os.ReadFile(productVariablesFileName)
if err != nil {
- return nil, err
+ return nil, nil, err
+ }
+ productVariables := android.ProductVariables{}
+ err = json.Unmarshal(productVariablesBytes, &productVariables)
+ if err != nil {
+ return nil, nil, err
}
// TODO(b/249685973): the name is product_config_platforms because product_config
@@ -39,11 +50,16 @@
"{VARIANT}", targetBuildVariant,
"{PRODUCT_FOLDER}", currentProductFolder)
- result := []BazelFile{
+ platformMappingContent, err := platformMappingContent(productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}"), &productVariables)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ injectionDirFiles := []BazelFile{
newFile(
currentProductFolder,
"soong.variables.bzl",
- `variables = json.decode("""`+strings.ReplaceAll(string(bytes), "\\", "\\\\")+`""")`),
+ `variables = json.decode("""`+strings.ReplaceAll(string(productVariablesBytes), "\\", "\\\\")+`""")`),
newFile(
currentProductFolder,
"BUILD",
@@ -99,6 +115,7 @@
"product_config_platforms",
"common.bazelrc",
productReplacer.Replace(`
+build --platform_mappings=platform_mappings
build --platforms @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
build:android --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}
@@ -120,6 +137,48 @@
build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64
`)),
}
+ bp2buildDirFiles := []BazelFile{
+ newFile(
+ "",
+ "platform_mappings",
+ platformMappingContent),
+ }
+ return injectionDirFiles, bp2buildDirFiles, nil
+}
+func platformMappingContent(mainProductLabel string, mainProductVariables *android.ProductVariables) (string, error) {
+ productsForTesting, err := starlark_import.GetStarlarkValue[map[string]map[string]starlark.Value]("products_for_testing")
+ if err != nil {
+ return "", err
+ }
+ result := "platforms:\n"
+ result += platformMappingSingleProduct(mainProductLabel, mainProductVariables)
+ for product, productVariablesStarlark := range productsForTesting {
+ productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
+ if err != nil {
+ return "", err
+ }
+ result += platformMappingSingleProduct("@//build/bazel/tests/products:"+product, &productVariables)
+ }
+ return result, nil
+}
+
+func platformMappingSingleProduct(label string, productVariables *android.ProductVariables) string {
+ buildSettings := ""
+ buildSettings += fmt.Sprintf(" --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride))
+ result := ""
+ for _, extension := range []string{"", "_linux_x86_64", "_linux_bionic_x86_64", "_linux_musl_x86", "_linux_musl_x86_64"} {
+ result += " " + label + extension + "\n" + buildSettings
+ }
+ return result
+}
+
+func starlarkMapToProductVariables(in map[string]starlark.Value) (android.ProductVariables, error) {
+ var err error
+ result := android.ProductVariables{}
+ result.ApexGlobalMinSdkVersionOverride, err = starlark_import.NoneableString(in["ApexGlobalMinSdkVersionOverride"])
+ if err != nil {
+ return result, err
+ }
return result, nil
}