Merge "Handle product_variable asflag for cc_object." am: acacbc1166

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1652787

Change-Id: If76000e28e7499243a87a5811852a62350dbe5a0
This commit is contained in:
Liz Kammer 2021-03-31 19:51:48 +00:00 committed by Automerger Merge Worker
commit 2cc845060d
5 changed files with 134 additions and 1 deletions

View File

@ -539,7 +539,7 @@ func (t *topDownMutatorContext) CreateBazelTargetModule(
Name: &name,
}
b := t.CreateModule(factory, &nameProp, attrs).(BazelTargetModule)
b := t.createModuleWithoutInheritance(factory, &nameProp, attrs).(BazelTargetModule)
b.SetBazelTargetModuleProperties(bazelProps)
return b
}
@ -608,6 +608,11 @@ func (t *topDownMutatorContext) CreateModule(factory ModuleFactory, props ...int
return module
}
func (t *topDownMutatorContext) createModuleWithoutInheritance(factory ModuleFactory, props ...interface{}) Module {
module := t.bp.CreateModule(ModuleFactoryAdaptor(factory), props...).(Module)
return module
}
func (b *bottomUpMutatorContext) MutatorName() string {
return b.bp.MutatorName()
}

View File

@ -448,6 +448,63 @@ func (v *productVariables) SetDefaultConfig() {
}
}
// ProductConfigContext requires the access to the Module to get product config properties.
type ProductConfigContext interface {
Module() Module
}
// ProductConfigProperty contains the information for a single property (may be a struct) paired
// with the appropriate ProductConfigVariable.
type ProductConfigProperty struct {
ProductConfigVariable string
Property interface{}
}
// ProductConfigProperties is a map of property name to a slice of ProductConfigProperty such that
// all it all product variable-specific versions of a property are easily accessed together
type ProductConfigProperties map[string][]ProductConfigProperty
// ProductVariableProperties returns a ProductConfigProperties containing only the properties which
// have been set for the module in the given context.
func ProductVariableProperties(ctx ProductConfigContext) ProductConfigProperties {
module := ctx.Module()
moduleBase := module.base()
productConfigProperties := ProductConfigProperties{}
if moduleBase.variableProperties == nil {
return productConfigProperties
}
variableValues := reflect.ValueOf(moduleBase.variableProperties).Elem().FieldByName("Product_variables")
for i := 0; i < variableValues.NumField(); i++ {
variableValue := variableValues.Field(i)
// Check if any properties were set for the module
if variableValue.IsZero() {
continue
}
// e.g. Platform_sdk_version, Unbundled_build, Malloc_not_svelte, etc.
productVariableName := variableValues.Type().Field(i).Name
for j := 0; j < variableValue.NumField(); j++ {
property := variableValue.Field(j)
// If the property wasn't set, no need to pass it along
if property.IsZero() {
continue
}
// e.g. Asflags, Cflags, Enabled, etc.
propertyName := variableValue.Type().Field(j).Name
productConfigProperties[propertyName] = append(productConfigProperties[propertyName],
ProductConfigProperty{
ProductConfigVariable: productVariableName,
Property: property.Interface(),
})
}
}
return productConfigProperties
}
func VariableMutator(mctx BottomUpMutatorContext) {
var module Module
var ok bool

View File

@ -16,6 +16,7 @@ package bazel
import (
"fmt"
"regexp"
"sort"
)
@ -31,6 +32,8 @@ type BazelTargetModuleProperties struct {
const BazelTargetModuleNamePrefix = "__bp2build__"
var productVariableSubstitutionPattern = regexp.MustCompile("%(d|s)")
// Label is used to represent a Bazel compatible Label. Also stores the original bp text to support
// string replacement.
type Label struct {
@ -225,3 +228,23 @@ func (attrs *StringListAttribute) SetValueForArch(arch string, value []string) {
panic(fmt.Errorf("Unknown arch: %s", arch))
}
}
// TryVariableSubstitution, replace string substitution formatting within each string in slice with
// Starlark string.format compatible tag for productVariable.
func TryVariableSubstitutions(slice []string, productVariable string) ([]string, bool) {
ret := make([]string, 0, len(slice))
changesMade := false
for _, s := range slice {
newS, changed := TryVariableSubstitution(s, productVariable)
ret = append(ret, newS)
changesMade = changesMade || changed
}
return ret, changesMade
}
// TryVariableSubstitution, replace string substitution formatting within s with Starlark
// string.format compatible tag for productVariable.
func TryVariableSubstitution(s string, productVariable string) (string, bool) {
sub := productVariableSubstitutionPattern.ReplaceAllString(s, "{"+productVariable+"}")
return sub, s != sub
}

View File

@ -206,6 +206,34 @@ cc_object {
srcs = [
"a/b/c.c",
],
)`,
},
},
{
description: "cc_object with product variable",
moduleTypeUnderTest: "cc_object",
moduleTypeUnderTestFactory: cc.ObjectFactory,
moduleTypeUnderTestBp2BuildMutator: cc.ObjectBp2Build,
blueprint: `cc_object {
name: "foo",
include_build_directory: false,
product_variables: {
platform_sdk_version: {
asflags: ["-DPLATFORM_SDK_VERSION=%d"],
},
},
bazel_module: { bp2build_available: true },
}
`,
expectedBazelTargets: []string{`cc_object(
name = "foo",
asflags = [
"-DPLATFORM_SDK_VERSION={Platform_sdk_version}",
],
copts = [
"-fno-addrsig",
],
)`,
},
},

View File

@ -115,6 +115,7 @@ type bazelObjectAttributes struct {
Srcs bazel.LabelListAttribute
Deps bazel.LabelListAttribute
Copts bazel.StringListAttribute
Asflags []string
Local_include_dirs []string
}
@ -158,6 +159,7 @@ func ObjectBp2Build(ctx android.TopDownMutatorContext) {
var copts bazel.StringListAttribute
var srcs bazel.LabelListAttribute
var localIncludeDirs []string
var asFlags []string
for _, props := range m.compiler.compilerProps() {
if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok {
copts.Value = baseCompilerProps.Cflags
@ -183,6 +185,23 @@ func ObjectBp2Build(ctx android.TopDownMutatorContext) {
}
}
productVariableProps := android.ProductVariableProperties(ctx)
if props, exists := productVariableProps["Asflags"]; exists {
// TODO(b/183595873): consider deduplicating handling of product variable properties
for _, prop := range props {
flags, ok := prop.Property.([]string)
if !ok {
ctx.ModuleErrorf("Could not convert product variable asflag property")
return
}
// TODO(b/183595873) handle other product variable usages -- as selects?
if newFlags, subbed := bazel.TryVariableSubstitutions(flags, prop.ProductConfigVariable); subbed {
asFlags = append(asFlags, newFlags...)
}
}
}
// TODO(b/183595872) warn/error if we're not handling product variables
for arch, p := range m.GetArchProperties(&BaseCompilerProperties{}) {
if cProps, ok := p.(*BaseCompilerProperties); ok {
srcs.SetValueForArch(arch.Name, android.BazelLabelForModuleSrcExcludes(ctx, cProps.Srcs, cProps.Exclude_srcs))
@ -194,6 +213,7 @@ func ObjectBp2Build(ctx android.TopDownMutatorContext) {
Srcs: srcs,
Deps: deps,
Copts: copts,
Asflags: asFlags,
Local_include_dirs: localIncludeDirs,
}