Merge "Move the android_platform next to it's entrypoint product config file" into main

This commit is contained in:
Cole Faust
2023-09-19 20:42:52 +00:00
committed by Gerrit Code Review
4 changed files with 200 additions and 108 deletions

View File

@@ -484,6 +484,12 @@ type ProductVariables struct {
KeepVndk *bool `json:",omitempty"` KeepVndk *bool `json:",omitempty"`
CheckVendorSeappViolations *bool `json:",omitempty"` CheckVendorSeappViolations *bool `json:",omitempty"`
// PartitionsVars are extra variables that are used to define the partition images. They should
// not be read from soong modules.
PartitionVars struct {
ProductDirectory string `json:",omitempty"`
} `json:",omitempty"`
} }
func boolPtr(v bool) *bool { func boolPtr(v bool) *bool {

View File

@@ -53,9 +53,10 @@ func createProductConfigFiles(
return res, err return res, err
} }
// TODO(b/249685973): the name is product_config_platforms because product_config currentProductFolder := fmt.Sprintf("build/bazel/products/%s-%s", targetProduct, targetBuildVariant)
// was already used for other files. Deduplicate them. if len(productVariables.PartitionVars.ProductDirectory) > 0 {
currentProductFolder := fmt.Sprintf("product_config_platforms/products/%s-%s", targetProduct, targetBuildVariant) currentProductFolder = fmt.Sprintf("%s%s-%s", productVariables.PartitionVars.ProductDirectory, targetProduct, targetBuildVariant)
}
productReplacer := strings.NewReplacer( productReplacer := strings.NewReplacer(
"{PRODUCT}", targetProduct, "{PRODUCT}", targetProduct,
@@ -72,7 +73,7 @@ func createProductConfigFiles(
} }
productLabelsToVariables := make(map[string]*android.ProductVariables) productLabelsToVariables := make(map[string]*android.ProductVariables)
productLabelsToVariables[productReplacer.Replace("@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}")] = &productVariables productLabelsToVariables[productReplacer.Replace("@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}")] = &productVariables
for product, productVariablesStarlark := range productsForTestingMap { for product, productVariablesStarlark := range productsForTestingMap {
productVariables, err := starlarkMapToProductVariables(productVariablesStarlark) productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
if err != nil { if err != nil {
@@ -81,7 +82,30 @@ func createProductConfigFiles(
productLabelsToVariables["@//build/bazel/tests/products:"+product] = &productVariables productLabelsToVariables["@//build/bazel/tests/products:"+product] = &productVariables
} }
res.bp2buildTargets = createTargets(productLabelsToVariables) res.bp2buildTargets = make(map[string]BazelTargets)
res.bp2buildTargets[currentProductFolder] = append(res.bp2buildTargets[currentProductFolder], BazelTarget{
name: productReplacer.Replace("{PRODUCT}-{VARIANT}"),
packageName: currentProductFolder,
content: productReplacer.Replace(`android_product(
name = "{PRODUCT}-{VARIANT}",
soong_variables = _soong_variables,
)`),
ruleClass: "android_product",
loads: []BazelLoad{
{
file: ":soong.variables.bzl",
symbols: []BazelLoadSymbol{{
symbol: "variables",
alias: "_soong_variables",
}},
},
{
file: "//build/bazel/product_config:android_product.bzl",
symbols: []BazelLoadSymbol{{symbol: "android_product"}},
},
},
})
createTargets(productLabelsToVariables, res.bp2buildTargets)
platformMappingContent, err := platformMappingContent( platformMappingContent, err := platformMappingContent(
productLabelsToVariables, productLabelsToVariables,
@@ -92,26 +116,6 @@ func createProductConfigFiles(
} }
res.injectionFiles = []BazelFile{ res.injectionFiles = []BazelFile{
newFile(
currentProductFolder,
"soong.variables.bzl",
`variables = json.decode("""`+strings.ReplaceAll(string(productVariablesBytes), "\\", "\\\\")+`""")`),
newFile(
currentProductFolder,
"BUILD",
productReplacer.Replace(`
package(default_visibility=[
"@soong_injection//product_config_platforms:__subpackages__",
"@//build/bazel/product_config:__subpackages__",
])
load(":soong.variables.bzl", _soong_variables = "variables")
load("@//build/bazel/product_config:android_product.bzl", "android_product")
android_product(
name = "{PRODUCT}-{VARIANT}",
soong_variables = _soong_variables,
)
`)),
newFile( newFile(
"product_config_platforms", "product_config_platforms",
"BUILD.bazel", "BUILD.bazel",
@@ -121,7 +125,7 @@ package(default_visibility = [
"@soong_injection//product_config_platforms:__subpackages__", "@soong_injection//product_config_platforms:__subpackages__",
]) ])
load("//{PRODUCT_FOLDER}:soong.variables.bzl", _soong_variables = "variables") load("@//{PRODUCT_FOLDER}:soong.variables.bzl", _soong_variables = "variables")
load("@//build/bazel/product_config:android_product.bzl", "android_product") load("@//build/bazel/product_config:android_product.bzl", "android_product")
# Bazel will qualify its outputs by the platform name. When switching between products, this # Bazel will qualify its outputs by the platform name. When switching between products, this
@@ -145,33 +149,33 @@ android_product(
# currently lunched product, they should all be listed here # currently lunched product, they should all be listed here
product_labels = [ product_labels = [
"@soong_injection//product_config_platforms:mixed_builds_product-{VARIANT}", "@soong_injection//product_config_platforms:mixed_builds_product-{VARIANT}",
"@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}", "@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}",
`)+strings.Join(productsForTesting, "\n")+"\n]\n"), `)+strings.Join(productsForTesting, "\n")+"\n]\n"),
newFile( newFile(
"product_config_platforms", "product_config_platforms",
"common.bazelrc", "common.bazelrc",
productReplacer.Replace(` productReplacer.Replace(`
build --platform_mappings=platform_mappings build --platform_mappings=platform_mappings
build --platforms @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64 build --platforms @//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
build:android --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT} build:android --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}
build:linux_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86 build:linux_x86 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86
build:linux_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64 build:linux_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
build:linux_bionic_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_bionic_x86_64 build:linux_bionic_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_bionic_x86_64
build:linux_musl_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86 build:linux_musl_x86 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86
build:linux_musl_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86_64 build:linux_musl_x86_64 --platforms=@//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86_64
`)), `)),
newFile( newFile(
"product_config_platforms", "product_config_platforms",
"linux.bazelrc", "linux.bazelrc",
productReplacer.Replace(` productReplacer.Replace(`
build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64 build --host_platform @//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64
`)), `)),
newFile( newFile(
"product_config_platforms", "product_config_platforms",
"darwin.bazelrc", "darwin.bazelrc",
productReplacer.Replace(` productReplacer.Replace(`
build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64 build --host_platform @//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64
`)), `)),
} }
res.bp2buildFiles = []BazelFile{ res.bp2buildFiles = []BazelFile{
@@ -179,6 +183,10 @@ build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_dar
"", "",
"platform_mappings", "platform_mappings",
platformMappingContent), platformMappingContent),
newFile(
currentProductFolder,
"soong.variables.bzl",
`variables = json.decode("""`+strings.ReplaceAll(string(productVariablesBytes), "\\", "\\\\")+`""")`),
} }
return res, nil return res, nil
@@ -421,8 +429,11 @@ func starlarkMapToProductVariables(in map[string]starlark.Value) (android.Produc
return result, nil return result, nil
} }
func createTargets(productLabelsToVariables map[string]*android.ProductVariables) map[string]BazelTargets { func createTargets(productLabelsToVariables map[string]*android.ProductVariables, res map[string]BazelTargets) {
res := make(map[string]BazelTargets) createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res)
}
func createGeneratedAndroidCertificateDirectories(productLabelsToVariables map[string]*android.ProductVariables, targets map[string]BazelTargets) {
var allDefaultAppCertificateDirs []string var allDefaultAppCertificateDirs []string
for _, productVariables := range productLabelsToVariables { for _, productVariables := range productLabelsToVariables {
if proptools.String(productVariables.DefaultAppCertificate) != "" { if proptools.String(productVariables.DefaultAppCertificate) != "" {
@@ -433,20 +444,20 @@ func createTargets(productLabelsToVariables map[string]*android.ProductVariables
} }
} }
for _, dir := range allDefaultAppCertificateDirs { for _, dir := range allDefaultAppCertificateDirs {
content := fmt.Sprintf(ruleTargetTemplate, "filegroup", "generated_android_certificate_directory", propsToAttributes(map[string]string{ content := `filegroup(
"srcs": `glob([ name = "generated_android_certificate_directory",
srcs = glob([
"*.pk8", "*.pk8",
"*.pem", "*.pem",
"*.avbpubkey", "*.avbpubkey",
])`, ]),
"visibility": `["//visibility:public"]`, visibility = ["//visibility:public"],
})) )`
res[dir] = append(res[dir], BazelTarget{ targets[dir] = append(targets[dir], BazelTarget{
name: "generated_android_certificate_directory", name: "generated_android_certificate_directory",
packageName: dir, packageName: dir,
content: content, content: content,
ruleClass: "filegroup", ruleClass: "filegroup",
}) })
} }
return res
} }

View File

@@ -39,18 +39,24 @@ type BazelAttributes struct {
Attrs map[string]string Attrs map[string]string
} }
type BazelLoadSymbol struct {
// The name of the symbol in the file being loaded
symbol string
// The name the symbol wil have in this file. Can be left blank to use the same name as symbol.
alias string
}
type BazelLoad struct {
file string
symbols []BazelLoadSymbol
}
type BazelTarget struct { type BazelTarget struct {
name string name string
packageName string packageName string
content string content string
ruleClass string ruleClass string
bzlLoadLocation string loads []BazelLoad
}
// IsLoadedFromStarlark determines if the BazelTarget's rule class is loaded from a .bzl file,
// as opposed to a native rule built into Bazel.
func (t BazelTarget) IsLoadedFromStarlark() bool {
return t.bzlLoadLocation != ""
} }
// Label is the fully qualified Bazel label constructed from the BazelTarget's // Label is the fully qualified Bazel label constructed from the BazelTarget's
@@ -110,30 +116,62 @@ func (targets BazelTargets) String() string {
// LoadStatements return the string representation of the sorted and deduplicated // LoadStatements return the string representation of the sorted and deduplicated
// Starlark rule load statements needed by a group of BazelTargets. // Starlark rule load statements needed by a group of BazelTargets.
func (targets BazelTargets) LoadStatements() string { func (targets BazelTargets) LoadStatements() string {
bzlToLoadedSymbols := map[string][]string{} // First, merge all the load statements from all the targets onto one list
bzlToLoadedSymbols := map[string][]BazelLoadSymbol{}
for _, target := range targets { for _, target := range targets {
if target.IsLoadedFromStarlark() { for _, load := range target.loads {
bzlToLoadedSymbols[target.bzlLoadLocation] = outer:
append(bzlToLoadedSymbols[target.bzlLoadLocation], target.ruleClass) for _, symbol := range load.symbols {
alias := symbol.alias
if alias == "" {
alias = symbol.symbol
}
for _, otherSymbol := range bzlToLoadedSymbols[load.file] {
otherAlias := otherSymbol.alias
if otherAlias == "" {
otherAlias = otherSymbol.symbol
}
if symbol.symbol == otherSymbol.symbol && alias == otherAlias {
continue outer
} else if alias == otherAlias {
panic(fmt.Sprintf("Conflicting destination (%s) for loads of %s and %s", alias, symbol.symbol, otherSymbol.symbol))
}
}
bzlToLoadedSymbols[load.file] = append(bzlToLoadedSymbols[load.file], symbol)
}
} }
} }
var loadStatements []string var loadStatements strings.Builder
for bzl, ruleClasses := range bzlToLoadedSymbols { for i, bzl := range android.SortedKeys(bzlToLoadedSymbols) {
loadStatement := "load(\"" symbols := bzlToLoadedSymbols[bzl]
loadStatement += bzl loadStatements.WriteString("load(\"")
loadStatement += "\", " loadStatements.WriteString(bzl)
ruleClasses = android.SortedUniqueStrings(ruleClasses) loadStatements.WriteString("\", ")
for i, ruleClass := range ruleClasses { sort.Slice(symbols, func(i, j int) bool {
loadStatement += "\"" + ruleClass + "\"" if symbols[i].symbol < symbols[j].symbol {
if i != len(ruleClasses)-1 { return true
loadStatement += ", " }
return symbols[i].alias < symbols[j].alias
})
for j, symbol := range symbols {
if symbol.alias != "" && symbol.alias != symbol.symbol {
loadStatements.WriteString(symbol.alias)
loadStatements.WriteString(" = ")
}
loadStatements.WriteString("\"")
loadStatements.WriteString(symbol.symbol)
loadStatements.WriteString("\"")
if j != len(symbols)-1 {
loadStatements.WriteString(", ")
} }
} }
loadStatement += ")" loadStatements.WriteString(")")
loadStatements = append(loadStatements, loadStatement) if i != len(bzlToLoadedSymbols)-1 {
loadStatements.WriteString("\n")
} }
return strings.Join(android.SortedUniqueStrings(loadStatements), "\n") }
return loadStatements.String()
} }
type bpToBuildContext interface { type bpToBuildContext interface {
@@ -857,11 +895,18 @@ func generateBazelTarget(ctx bpToBuildContext, m bp2buildModule) (BazelTarget, e
} else { } else {
content = fmt.Sprintf(unnamedRuleTargetTemplate, ruleClass, attributes) content = fmt.Sprintf(unnamedRuleTargetTemplate, ruleClass, attributes)
} }
var loads []BazelLoad
if bzlLoadLocation != "" {
loads = append(loads, BazelLoad{
file: bzlLoadLocation,
symbols: []BazelLoadSymbol{{symbol: ruleClass}},
})
}
return BazelTarget{ return BazelTarget{
name: targetName, name: targetName,
packageName: m.TargetPackage(), packageName: m.TargetPackage(),
ruleClass: ruleClass, ruleClass: ruleClass,
bzlLoadLocation: bzlLoadLocation, loads: loads,
content: content, content: content,
}, nil }, nil
} }

View File

@@ -775,7 +775,10 @@ func TestLoadStatements(t *testing.T) {
BazelTarget{ BazelTarget{
name: "foo", name: "foo",
ruleClass: "cc_library", ruleClass: "cc_library",
bzlLoadLocation: "//build/bazel/rules:cc.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:cc.bzl",
symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
}},
}, },
}, },
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`, expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`,
@@ -785,12 +788,18 @@ func TestLoadStatements(t *testing.T) {
BazelTarget{ BazelTarget{
name: "foo", name: "foo",
ruleClass: "cc_library", ruleClass: "cc_library",
bzlLoadLocation: "//build/bazel/rules:cc.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:cc.bzl",
symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
}},
}, },
BazelTarget{ BazelTarget{
name: "bar", name: "bar",
ruleClass: "cc_library", ruleClass: "cc_library",
bzlLoadLocation: "//build/bazel/rules:cc.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:cc.bzl",
symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
}},
}, },
}, },
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`, expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_library")`,
@@ -800,12 +809,18 @@ func TestLoadStatements(t *testing.T) {
BazelTarget{ BazelTarget{
name: "foo", name: "foo",
ruleClass: "cc_library", ruleClass: "cc_library",
bzlLoadLocation: "//build/bazel/rules:cc.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:cc.bzl",
symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
}},
}, },
BazelTarget{ BazelTarget{
name: "bar", name: "bar",
ruleClass: "cc_binary", ruleClass: "cc_binary",
bzlLoadLocation: "//build/bazel/rules:cc.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:cc.bzl",
symbols: []BazelLoadSymbol{{symbol: "cc_binary"}},
}},
}, },
}, },
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")`, expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")`,
@@ -815,17 +830,26 @@ func TestLoadStatements(t *testing.T) {
BazelTarget{ BazelTarget{
name: "foo", name: "foo",
ruleClass: "cc_library", ruleClass: "cc_library",
bzlLoadLocation: "//build/bazel/rules:cc.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:cc.bzl",
symbols: []BazelLoadSymbol{{symbol: "cc_library"}},
}},
}, },
BazelTarget{ BazelTarget{
name: "bar", name: "bar",
ruleClass: "cc_binary", ruleClass: "cc_binary",
bzlLoadLocation: "//build/bazel/rules:cc.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:cc.bzl",
symbols: []BazelLoadSymbol{{symbol: "cc_binary"}},
}},
}, },
BazelTarget{ BazelTarget{
name: "baz", name: "baz",
ruleClass: "java_binary", ruleClass: "java_binary",
bzlLoadLocation: "//build/bazel/rules:java.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:java.bzl",
symbols: []BazelLoadSymbol{{symbol: "java_binary"}},
}},
}, },
}, },
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library") expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary", "cc_library")
@@ -836,17 +860,23 @@ load("//build/bazel/rules:java.bzl", "java_binary")`,
BazelTarget{ BazelTarget{
name: "foo", name: "foo",
ruleClass: "cc_binary", ruleClass: "cc_binary",
bzlLoadLocation: "//build/bazel/rules:cc.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:cc.bzl",
symbols: []BazelLoadSymbol{{symbol: "cc_binary"}},
}},
}, },
BazelTarget{ BazelTarget{
name: "bar", name: "bar",
ruleClass: "java_binary", ruleClass: "java_binary",
bzlLoadLocation: "//build/bazel/rules:java.bzl", loads: []BazelLoad{{
file: "//build/bazel/rules:java.bzl",
symbols: []BazelLoadSymbol{{symbol: "java_binary"}},
}},
}, },
BazelTarget{ BazelTarget{
name: "baz", name: "baz",
ruleClass: "genrule", ruleClass: "genrule",
// Note: no bzlLoadLocation for native rules // Note: no loads for native rules
}, },
}, },
expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary") expectedLoadStatements: `load("//build/bazel/rules:cc.bzl", "cc_binary")