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:
@@ -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",
|
||||
|
63
cc/cc.go
63
cc/cc.go
@@ -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
|
||||
|
@@ -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() {
|
||||
|
152
common/extend.go
152
common/extend.go
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
@@ -340,9 +338,8 @@ func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
|
||||
hod: a.commonProperties.CompileHostOrDevice,
|
||||
config: ctx.Config().(Config),
|
||||
},
|
||||
installDeps: a.computeInstallDeps(ctx),
|
||||
installFiles: a.installFiles,
|
||||
extendedProperties: a.extendedProperties,
|
||||
installDeps: a.computeInstallDeps(ctx),
|
||||
installFiles: a.installFiles,
|
||||
}
|
||||
|
||||
if a.commonProperties.Disabled {
|
||||
@@ -373,10 +370,9 @@ type androidBaseContextImpl struct {
|
||||
type androidModuleContext struct {
|
||||
blueprint.ModuleContext
|
||||
androidBaseContextImpl
|
||||
installDeps []string
|
||||
installFiles []string
|
||||
checkbuildFiles []string
|
||||
extendedProperties map[string]struct{}
|
||||
installDeps []string
|
||||
installFiles []string
|
||||
checkbuildFiles []string
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
@@ -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{}) {
|
||||
|
Reference in New Issue
Block a user