Replace extendProperties with pathtools.AppendProperties

Blueprint has a generic AppendProperties/AppendMatchingProperties now,
use it, and replace all bool properties that might be modified by a
mutator with *bool, which provides the correct replace-if-set semantics
for append.

Also remove uses of ContainsProperty except when explicitly checking if
a property was set in a blueprints file.

Change-Id: If523af61d6b4630e79504d7fc2840f36e98571cc
This commit is contained in:
Colin Cross
2015-10-28 17:23:31 -07:00
parent 7449857325
commit 06a931bdb6
6 changed files with 113 additions and 237 deletions

View File

@@ -93,7 +93,6 @@ bootstrap_go_package {
"common/config.go",
"common/defs.go",
"common/env.go",
"common/extend.go",
"common/glob.go",
"common/module.go",
"common/paths.go",

View File

@@ -26,6 +26,7 @@ import (
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
"github.com/google/blueprint/proptools"
"android/soong"
"android/soong/common"
@@ -270,24 +271,24 @@ type CCBaseProperties struct {
// modules cannot contain undefined symbols that are not satisified by their immediate
// dependencies. Set this flag to true to remove --no-undefined from the linker flags.
// This flag should only be necessary for compiling low-level libraries like libc.
Allow_undefined_symbols bool
Allow_undefined_symbols *bool
// don't link in crt_begin and crt_end. This flag should only be necessary for
// compiling crt or libc.
Nocrt bool `android:"arch_variant"`
Nocrt *bool `android:"arch_variant"`
// don't link in libgcc.a
No_libgcc bool
No_libgcc *bool
// don't insert default compiler flags into asflags, cflags,
// cppflags, conlyflags, ldflags, or include_dirs
No_default_compiler_flags bool
No_default_compiler_flags *bool
// compile module with clang instead of gcc
Clang bool `android:"arch_variant"`
Clang *bool `android:"arch_variant"`
// pass -frtti instead of -fno-rtti
Rtti bool
Rtti *bool
// -l arguments to pass to linker for host-provided shared libraries
Host_ldlibs []string `android:"arch_variant"`
@@ -323,7 +324,7 @@ type CCBase struct {
Properties CCBaseProperties
unused struct {
Native_coverage bool
Native_coverage *bool
Required []string
Sanitize []string `android:"arch_variant"`
Sanitize_recover []string
@@ -451,9 +452,9 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
LdFlags: c.Properties.Ldflags,
AsFlags: c.Properties.Asflags,
YaccFlags: c.Properties.Yaccflags,
Nocrt: c.Properties.Nocrt,
Nocrt: Bool(c.Properties.Nocrt),
Toolchain: toolchain,
Clang: c.Properties.Clang,
Clang: Bool(c.Properties.Clang),
}
// Include dir cflags
@@ -473,7 +474,7 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
includeFilesToFlags(rootIncludeFiles),
includeFilesToFlags(localIncludeFiles))
if !c.Properties.No_default_compiler_flags {
if !Bool(c.Properties.No_default_compiler_flags) {
if c.Properties.Sdk_version == "" || ctx.Host() {
flags.GlobalFlags = append(flags.GlobalFlags,
"${commonGlobalIncludes}",
@@ -488,7 +489,7 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
}...)
}
if !ctx.ContainsProperty("clang") {
if c.Properties.Clang == nil {
if ctx.Host() {
flags.Clang = true
}
@@ -532,8 +533,8 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
}
if !c.Properties.No_default_compiler_flags {
if ctx.Device() && !c.Properties.Allow_undefined_symbols {
if !Bool(c.Properties.No_default_compiler_flags) {
if ctx.Device() && !Bool(c.Properties.Allow_undefined_symbols) {
flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
}
@@ -554,7 +555,7 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
}
if ctx.Device() {
if c.Properties.Rtti {
if Bool(c.Properties.Rtti) {
flags.CppFlags = append(flags.CppFlags, "-frtti")
} else {
flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
@@ -743,11 +744,11 @@ func (c *CCBase) depsToPaths(ctx common.AndroidModuleContext, depNames CCDeps) C
if obj, ok := m.(ccObjectProvider); ok {
otherName := ctx.OtherModuleName(m)
if otherName == depNames.CrtBegin {
if !c.Properties.Nocrt {
if !Bool(c.Properties.Nocrt) {
depPaths.CrtBegin = obj.object().outputFile()
}
} else if otherName == depNames.CrtEnd {
if !c.Properties.Nocrt {
if !Bool(c.Properties.Nocrt) {
depPaths.CrtEnd = obj.object().outputFile()
}
} else {
@@ -780,7 +781,7 @@ func newCCDynamic(dynamic *CCLinked, module CCModuleType, hod common.HostOrDevic
}
func (c *CCLinked) systemSharedLibs(ctx common.AndroidBaseContext) []string {
if ctx.ContainsProperty("system_shared_libs") {
if c.Properties.System_shared_libs != nil {
return c.Properties.System_shared_libs
} else if ctx.Device() && c.Properties.Sdk_version == "" {
return []string{"libc", "libm"}
@@ -941,7 +942,7 @@ func (c *CCLinked) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDe
if ctx.Device() {
// libgcc and libatomic have to be last on the command line
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcov", "libatomic")
if !c.Properties.No_libgcc {
if !Bool(c.Properties.No_libgcc) {
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcc")
}
@@ -1328,7 +1329,7 @@ var _ ccObjectProvider = (*ccObject)(nil)
type CCBinaryProperties struct {
// compile executable with -static
Static_executable bool
Static_executable *bool
// set the name of the output
Stem string `android:"arch_variant"`
@@ -1341,7 +1342,7 @@ type CCBinaryProperties struct {
// Create a separate binary for each source file. Useful when there is
// global state that can not be torn down and reset between each test suite.
Test_per_src bool
Test_per_src *bool
}
type CCBinary struct {
@@ -1352,11 +1353,11 @@ type CCBinary struct {
}
func (c *CCBinary) buildStatic() bool {
return c.BinaryProperties.Static_executable
return Bool(c.BinaryProperties.Static_executable)
}
func (c *CCBinary) buildShared() bool {
return !c.BinaryProperties.Static_executable
return !Bool(c.BinaryProperties.Static_executable)
}
func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
@@ -1372,14 +1373,14 @@ func (c *CCBinary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDe
depNames = c.CCLinked.depNames(ctx, depNames)
if ctx.Device() {
if c.Properties.Sdk_version == "" {
if c.BinaryProperties.Static_executable {
if Bool(c.BinaryProperties.Static_executable) {
depNames.CrtBegin = "crtbegin_static"
} else {
depNames.CrtBegin = "crtbegin_dynamic"
}
depNames.CrtEnd = "crtend_android"
} else {
if c.BinaryProperties.Static_executable {
if Bool(c.BinaryProperties.Static_executable) {
depNames.CrtBegin = "ndk_crtbegin_static." + c.Properties.Sdk_version
} else {
depNames.CrtBegin = "ndk_crtbegin_dynamic." + c.Properties.Sdk_version
@@ -1387,7 +1388,7 @@ func (c *CCBinary) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDe
depNames.CrtEnd = "ndk_crtend_android." + c.Properties.Sdk_version
}
if c.BinaryProperties.Static_executable {
if Bool(c.BinaryProperties.Static_executable) {
if c.stl(ctx) == "libc++_static" {
depNames.StaticLibs = append(depNames.StaticLibs, "libm", "libc", "libdl")
}
@@ -1419,9 +1420,9 @@ func CCBinaryFactory() (blueprint.Module, []interface{}) {
func (c *CCBinary) ModifyProperties(ctx common.AndroidBaseContext) {
if ctx.Darwin() {
c.BinaryProperties.Static_executable = false
c.BinaryProperties.Static_executable = proptools.BoolPtr(false)
}
if c.BinaryProperties.Static_executable {
if Bool(c.BinaryProperties.Static_executable) {
c.dynamicProperties.VariantIsStaticBinary = true
}
}
@@ -1432,7 +1433,7 @@ func (c *CCBinary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags
flags.CFlags = append(flags.CFlags, "-fpie")
if ctx.Device() {
if c.BinaryProperties.Static_executable {
if Bool(c.BinaryProperties.Static_executable) {
// Clang driver needs -static to create static executable.
// However, bionic/linker uses -shared to overwrite.
// Linker for x86 targets does not allow coexistance of -static and -shared,
@@ -1471,7 +1472,7 @@ func (c *CCBinary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags
func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
flags CCFlags, deps CCDeps, objFiles []string) {
if !c.BinaryProperties.Static_executable && inList("libc", c.Properties.Static_libs) {
if !Bool(c.BinaryProperties.Static_executable) && inList("libc", c.Properties.Static_libs) {
ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
"from static libs or set static_executable: true")
}
@@ -1504,7 +1505,7 @@ func (c *CCBinary) HostToolPath() string {
}
func (c *CCBinary) testPerSrc() bool {
return c.BinaryProperties.Test_per_src
return Bool(c.BinaryProperties.Test_per_src)
}
func (c *CCBinary) binary() *CCBinary {
@@ -1938,3 +1939,5 @@ func lastUniqueElements(list []string) []string {
}
return list[totalSkip:]
}
var Bool = proptools.Bool

View File

@@ -426,6 +426,38 @@ func InitArchModule(m AndroidModule, defaultMultilib Multilib,
var dashToUnderscoreReplacer = strings.NewReplacer("-", "_")
func (a *AndroidModuleBase) appendProperties(ctx blueprint.EarlyMutatorContext,
dst, src interface{}, field, srcPrefix string) {
src = reflect.ValueOf(src).FieldByName(field).Elem().Interface()
filter := func(property string,
dstField, srcField reflect.StructField,
dstValue, srcValue interface{}) (bool, error) {
srcProperty := srcPrefix + "." + property
if !proptools.HasTag(dstField, "android", "arch_variant") {
if ctx.ContainsProperty(srcProperty) {
return false, fmt.Errorf("can't be specific to a build variant")
} else {
return false, nil
}
}
return true, nil
}
err := proptools.AppendProperties(dst, src, filter)
if err != nil {
if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
} else {
panic(err)
}
}
}
// Rewrite the module's properties structs to contain arch-specific values.
func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext) {
arch := a.commonProperties.CompileArch
@@ -435,13 +467,9 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
return
}
callback := func(srcPropertyName, dstPropertyName string) {
a.extendedProperties[dstPropertyName] = struct{}{}
}
for i := range a.generalProperties {
generalPropsValue := []reflect.Value{reflect.ValueOf(a.generalProperties[i]).Elem()}
genProps := a.generalProperties[i]
archProps := a.archProperties[i]
// Handle arch-specific properties in the form:
// arch: {
// arm64: {
@@ -449,9 +477,10 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
// },
// },
t := arch.ArchType
field := proptools.FieldNameForProperty(t.Name)
extendProperties(ctx, "arch_variant", "arch."+t.Name, generalPropsValue,
reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
prefix := "arch." + t.Name
a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
// Handle arch-variant-specific properties in the form:
// arch: {
@@ -462,8 +491,8 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
v := dashToUnderscoreReplacer.Replace(arch.ArchVariant)
if v != "" {
field := proptools.FieldNameForProperty(v)
extendProperties(ctx, "arch_variant", "arch."+v, generalPropsValue,
reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
prefix := "arch." + v
a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
}
// Handle cpu-variant-specific properties in the form:
@@ -475,8 +504,8 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
c := dashToUnderscoreReplacer.Replace(arch.CpuVariant)
if c != "" {
field := proptools.FieldNameForProperty(c)
extendProperties(ctx, "arch_variant", "arch."+c, generalPropsValue,
reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
prefix := "arch." + c
a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
}
// Handle multilib-specific properties in the form:
@@ -485,9 +514,9 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
// key: value,
// },
// },
multilibField := proptools.FieldNameForProperty(t.Multilib)
extendProperties(ctx, "arch_variant", "multilib."+t.Multilib, generalPropsValue,
reflect.ValueOf(a.archProperties[i].Multilib).FieldByName(multilibField).Elem().Elem(), callback)
field = proptools.FieldNameForProperty(t.Multilib)
prefix = "multilib." + t.Multilib
a.appendProperties(ctx, genProps, archProps.Multilib, field, prefix)
// Handle host-or-device-specific properties in the form:
// target: {
@@ -496,9 +525,9 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
// },
// },
hodProperty := hod.Property()
hodField := proptools.FieldNameForProperty(hodProperty)
extendProperties(ctx, "arch_variant", "target."+hodProperty, generalPropsValue,
reflect.ValueOf(a.archProperties[i].Target).FieldByName(hodField).Elem().Elem(), callback)
field = proptools.FieldNameForProperty(hodProperty)
prefix = "target." + hodProperty
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
// Handle host target properties in the form:
// target: {
@@ -527,15 +556,18 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
if hod.Host() {
for _, v := range osList {
if v.goos == runtime.GOOS {
extendProperties(ctx, "arch_variant", "target."+v.goos, generalPropsValue,
reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field).Elem().Elem(), callback)
field := v.field
prefix := "target." + v.goos
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
t := arch.ArchType
extendProperties(ctx, "arch_variant", "target."+v.goos+"_"+t.Name, generalPropsValue,
reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field+"_"+t.Name).Elem().Elem(), callback)
field = v.field + "_" + t.Name
prefix = "target." + v.goos + "_" + t.Name
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
}
}
extendProperties(ctx, "arch_variant", "target.not_windows", generalPropsValue,
reflect.ValueOf(a.archProperties[i].Target).FieldByName("Not_windows").Elem().Elem(), callback)
field := "Not_windows"
prefix := "target.not_windows"
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
}
// Handle 64-bit device properties in the form:
@@ -553,11 +585,13 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
// debuggerd that need to know when they are a 32-bit process running on a 64-bit device
if hod.Device() {
if true /* && target_is_64_bit */ {
extendProperties(ctx, "arch_variant", "target.android64", generalPropsValue,
reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android64").Elem().Elem(), callback)
field := "Android64"
prefix := "target.android64"
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
} else {
extendProperties(ctx, "arch_variant", "target.android32", generalPropsValue,
reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android32").Elem().Elem(), callback)
field := "Android32"
prefix := "target.android32"
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
}
}
@@ -572,8 +606,9 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
// },
if hod.Device() {
t := arch.ArchType
extendProperties(ctx, "arch_variant", "target.android_"+t.Name, generalPropsValue,
reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android_"+t.Name).Elem().Elem(), callback)
field := "Android_" + t.Name
prefix := "target.android_" + t.Name
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
}
if ctx.Failed() {

View File

@@ -1,152 +0,0 @@
// Copyright 2015 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package common
import (
"fmt"
"reflect"
"strings"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
// TODO: move this to proptools
func extendProperties(ctx blueprint.EarlyMutatorContext,
requiredTag, srcPrefix string, dstValues []reflect.Value, srcValue reflect.Value,
callback func(string, string)) {
if srcPrefix != "" {
srcPrefix += "."
}
extendPropertiesRecursive(ctx, requiredTag, srcValue, dstValues, srcPrefix, "", callback)
}
func extendPropertiesRecursive(ctx blueprint.EarlyMutatorContext, requiredTag string,
srcValue reflect.Value, dstValues []reflect.Value, srcPrefix, dstPrefix string,
callback func(string, string)) {
typ := srcValue.Type()
for i := 0; i < srcValue.NumField(); i++ {
srcField := typ.Field(i)
if srcField.PkgPath != "" {
// The field is not exported so just skip it.
continue
}
localPropertyName := proptools.PropertyNameForField(srcField.Name)
srcPropertyName := srcPrefix + localPropertyName
srcFieldValue := srcValue.Field(i)
if !ctx.ContainsProperty(srcPropertyName) {
continue
}
found := false
for _, dstValue := range dstValues {
dstField, ok := dstValue.Type().FieldByName(srcField.Name)
if !ok {
continue
}
dstFieldValue := dstValue.FieldByIndex(dstField.Index)
if srcFieldValue.Type() != dstFieldValue.Type() {
panic(fmt.Errorf("can't extend mismatching types for %q (%s <- %s)",
srcPropertyName, dstFieldValue.Type(), srcFieldValue.Type()))
}
dstPropertyName := dstPrefix + localPropertyName
if requiredTag != "" {
tag := dstField.Tag.Get("android")
tags := map[string]bool{}
for _, entry := range strings.Split(tag, ",") {
if entry != "" {
tags[entry] = true
}
}
if !tags[requiredTag] {
ctx.PropertyErrorf(srcPropertyName, "property can't be specific to a build variant")
continue
}
}
if callback != nil {
callback(srcPropertyName, dstPropertyName)
}
found = true
switch srcFieldValue.Kind() {
case reflect.Bool:
// Replace the original value.
dstFieldValue.Set(srcFieldValue)
case reflect.String:
// Append the extension string.
dstFieldValue.SetString(dstFieldValue.String() +
srcFieldValue.String())
case reflect.Slice:
dstFieldValue.Set(reflect.AppendSlice(dstFieldValue, srcFieldValue))
case reflect.Interface:
if dstFieldValue.IsNil() != srcFieldValue.IsNil() {
panic(fmt.Errorf("can't extend field %q: nilitude mismatch", srcPropertyName))
}
if dstFieldValue.IsNil() {
continue
}
dstFieldValue = dstFieldValue.Elem()
srcFieldValue = srcFieldValue.Elem()
if dstFieldValue.Type() != srcFieldValue.Type() {
panic(fmt.Errorf("can't extend field %q: type mismatch", srcPropertyName))
}
if srcFieldValue.Kind() != reflect.Ptr {
panic(fmt.Errorf("can't extend field %q: interface not a pointer", srcPropertyName))
}
fallthrough
case reflect.Ptr:
if dstFieldValue.IsNil() != srcFieldValue.IsNil() {
panic(fmt.Errorf("can't extend field %q: nilitude mismatch", srcPropertyName))
}
if dstFieldValue.IsNil() {
continue
}
dstFieldValue = dstFieldValue.Elem()
srcFieldValue = srcFieldValue.Elem()
if dstFieldValue.Type() != srcFieldValue.Type() {
panic(fmt.Errorf("can't extend field %q: type mismatch", srcPropertyName))
}
if srcFieldValue.Kind() != reflect.Struct {
panic(fmt.Errorf("can't extend field %q: pointer not to a struct", srcPropertyName))
}
fallthrough
case reflect.Struct:
// Recursively extend the struct's fields.
extendPropertiesRecursive(ctx, requiredTag, srcFieldValue, []reflect.Value{dstFieldValue},
srcPropertyName+".", srcPropertyName+".", callback)
default:
panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
srcPropertyName, srcFieldValue.Kind()))
}
}
if !found {
ctx.PropertyErrorf(srcPropertyName, "failed to find property to extend")
}
}
}

View File

@@ -123,7 +123,6 @@ func InitAndroidModule(m AndroidModule,
base := m.base()
base.module = m
base.extendedProperties = make(map[string]struct{})
propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
@@ -198,7 +197,6 @@ type AndroidModuleBase struct {
hostAndDeviceProperties hostAndDeviceProperties
generalProperties []interface{}
archProperties []*archProperties
extendedProperties map[string]struct{}
noAddressSanitizer bool
installFiles []string
@@ -342,7 +340,6 @@ func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
},
installDeps: a.computeInstallDeps(ctx),
installFiles: a.installFiles,
extendedProperties: a.extendedProperties,
}
if a.commonProperties.Disabled {
@@ -376,7 +373,6 @@ type androidModuleContext struct {
installDeps []string
installFiles []string
checkbuildFiles []string
extendedProperties map[string]struct{}
}
func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
@@ -384,14 +380,6 @@ func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blue
a.ModuleContext.Build(pctx, params)
}
func (a *androidModuleContext) ContainsProperty(property string) bool {
if a.ModuleContext.ContainsProperty(property) {
return true
}
_, ok := a.extendedProperties[property]
return ok
}
func (a *androidBaseContextImpl) Arch() Arch {
return a.arch
}

View File

@@ -113,7 +113,7 @@ func VariableMutator(mctx blueprint.EarlyMutatorContext) {
// TODO: depend on config variable, create variants, propagate variants up tree
a := module.base()
variableValues := reflect.ValueOf(a.variableProperties.Product_variables)
variableValues := reflect.ValueOf(&a.variableProperties.Product_variables).Elem()
zeroValues := reflect.ValueOf(zeroProductVariables.Product_variables)
for i := 0; i < variableValues.NumField(); i++ {
@@ -147,16 +147,19 @@ func VariableMutator(mctx blueprint.EarlyMutatorContext) {
func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext,
prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
generalPropertyValues := make([]reflect.Value, len(a.generalProperties))
for i := range a.generalProperties {
generalPropertyValues[i] = reflect.ValueOf(a.generalProperties[i]).Elem()
}
if variableValue != nil {
printfIntoProperties(productVariablePropertyValue, variableValue)
}
extendProperties(ctx, "", prefix, generalPropertyValues, productVariablePropertyValue, nil)
err := proptools.AppendMatchingProperties(a.generalProperties,
productVariablePropertyValue.Addr().Interface(), nil)
if err != nil {
if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
} else {
panic(err)
}
}
}
func printfIntoProperties(productVariablePropertyValue reflect.Value, variableValue interface{}) {