Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acacbc11 authored by Liz Kammer's avatar Liz Kammer Committed by Gerrit Code Review
Browse files

Merge "Handle product_variable asflag for cc_object."

parents 7dfaa3a7 a060c452
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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()
}
+57 −0
Original line number Diff line number Diff line
@@ -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
+23 −0
Original line number Diff line number Diff line
@@ -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
}
+28 −0
Original line number Diff line number Diff line
@@ -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",
    ],
)`,
			},
		},
+20 −0
Original line number Diff line number Diff line
@@ -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,
	}