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/config.go",
|
||||||
"common/defs.go",
|
"common/defs.go",
|
||||||
"common/env.go",
|
"common/env.go",
|
||||||
"common/extend.go",
|
|
||||||
"common/glob.go",
|
"common/glob.go",
|
||||||
"common/module.go",
|
"common/module.go",
|
||||||
"common/paths.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"
|
||||||
"github.com/google/blueprint/pathtools"
|
"github.com/google/blueprint/pathtools"
|
||||||
|
"github.com/google/blueprint/proptools"
|
||||||
|
|
||||||
"android/soong"
|
"android/soong"
|
||||||
"android/soong/common"
|
"android/soong/common"
|
||||||
@@ -270,24 +271,24 @@ type CCBaseProperties struct {
|
|||||||
// modules cannot contain undefined symbols that are not satisified by their immediate
|
// 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.
|
// 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.
|
// 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
|
// don't link in crt_begin and crt_end. This flag should only be necessary for
|
||||||
// compiling crt or libc.
|
// compiling crt or libc.
|
||||||
Nocrt bool `android:"arch_variant"`
|
Nocrt *bool `android:"arch_variant"`
|
||||||
|
|
||||||
// don't link in libgcc.a
|
// don't link in libgcc.a
|
||||||
No_libgcc bool
|
No_libgcc *bool
|
||||||
|
|
||||||
// don't insert default compiler flags into asflags, cflags,
|
// don't insert default compiler flags into asflags, cflags,
|
||||||
// cppflags, conlyflags, ldflags, or include_dirs
|
// cppflags, conlyflags, ldflags, or include_dirs
|
||||||
No_default_compiler_flags bool
|
No_default_compiler_flags *bool
|
||||||
|
|
||||||
// compile module with clang instead of gcc
|
// compile module with clang instead of gcc
|
||||||
Clang bool `android:"arch_variant"`
|
Clang *bool `android:"arch_variant"`
|
||||||
|
|
||||||
// pass -frtti instead of -fno-rtti
|
// pass -frtti instead of -fno-rtti
|
||||||
Rtti bool
|
Rtti *bool
|
||||||
|
|
||||||
// -l arguments to pass to linker for host-provided shared libraries
|
// -l arguments to pass to linker for host-provided shared libraries
|
||||||
Host_ldlibs []string `android:"arch_variant"`
|
Host_ldlibs []string `android:"arch_variant"`
|
||||||
@@ -323,7 +324,7 @@ type CCBase struct {
|
|||||||
Properties CCBaseProperties
|
Properties CCBaseProperties
|
||||||
|
|
||||||
unused struct {
|
unused struct {
|
||||||
Native_coverage bool
|
Native_coverage *bool
|
||||||
Required []string
|
Required []string
|
||||||
Sanitize []string `android:"arch_variant"`
|
Sanitize []string `android:"arch_variant"`
|
||||||
Sanitize_recover []string
|
Sanitize_recover []string
|
||||||
@@ -451,9 +452,9 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
|
|||||||
LdFlags: c.Properties.Ldflags,
|
LdFlags: c.Properties.Ldflags,
|
||||||
AsFlags: c.Properties.Asflags,
|
AsFlags: c.Properties.Asflags,
|
||||||
YaccFlags: c.Properties.Yaccflags,
|
YaccFlags: c.Properties.Yaccflags,
|
||||||
Nocrt: c.Properties.Nocrt,
|
Nocrt: Bool(c.Properties.Nocrt),
|
||||||
Toolchain: toolchain,
|
Toolchain: toolchain,
|
||||||
Clang: c.Properties.Clang,
|
Clang: Bool(c.Properties.Clang),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include dir cflags
|
// Include dir cflags
|
||||||
@@ -473,7 +474,7 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
|
|||||||
includeFilesToFlags(rootIncludeFiles),
|
includeFilesToFlags(rootIncludeFiles),
|
||||||
includeFilesToFlags(localIncludeFiles))
|
includeFilesToFlags(localIncludeFiles))
|
||||||
|
|
||||||
if !c.Properties.No_default_compiler_flags {
|
if !Bool(c.Properties.No_default_compiler_flags) {
|
||||||
if c.Properties.Sdk_version == "" || ctx.Host() {
|
if c.Properties.Sdk_version == "" || ctx.Host() {
|
||||||
flags.GlobalFlags = append(flags.GlobalFlags,
|
flags.GlobalFlags = append(flags.GlobalFlags,
|
||||||
"${commonGlobalIncludes}",
|
"${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() {
|
if ctx.Host() {
|
||||||
flags.Clang = true
|
flags.Clang = true
|
||||||
}
|
}
|
||||||
@@ -532,8 +533,8 @@ func (c *CCBase) collectFlags(ctx common.AndroidModuleContext, toolchain Toolcha
|
|||||||
flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
|
flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !c.Properties.No_default_compiler_flags {
|
if !Bool(c.Properties.No_default_compiler_flags) {
|
||||||
if ctx.Device() && !c.Properties.Allow_undefined_symbols {
|
if ctx.Device() && !Bool(c.Properties.Allow_undefined_symbols) {
|
||||||
flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
|
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 ctx.Device() {
|
||||||
if c.Properties.Rtti {
|
if Bool(c.Properties.Rtti) {
|
||||||
flags.CppFlags = append(flags.CppFlags, "-frtti")
|
flags.CppFlags = append(flags.CppFlags, "-frtti")
|
||||||
} else {
|
} else {
|
||||||
flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
|
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 {
|
if obj, ok := m.(ccObjectProvider); ok {
|
||||||
otherName := ctx.OtherModuleName(m)
|
otherName := ctx.OtherModuleName(m)
|
||||||
if otherName == depNames.CrtBegin {
|
if otherName == depNames.CrtBegin {
|
||||||
if !c.Properties.Nocrt {
|
if !Bool(c.Properties.Nocrt) {
|
||||||
depPaths.CrtBegin = obj.object().outputFile()
|
depPaths.CrtBegin = obj.object().outputFile()
|
||||||
}
|
}
|
||||||
} else if otherName == depNames.CrtEnd {
|
} else if otherName == depNames.CrtEnd {
|
||||||
if !c.Properties.Nocrt {
|
if !Bool(c.Properties.Nocrt) {
|
||||||
depPaths.CrtEnd = obj.object().outputFile()
|
depPaths.CrtEnd = obj.object().outputFile()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -780,7 +781,7 @@ func newCCDynamic(dynamic *CCLinked, module CCModuleType, hod common.HostOrDevic
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CCLinked) systemSharedLibs(ctx common.AndroidBaseContext) []string {
|
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
|
return c.Properties.System_shared_libs
|
||||||
} else if ctx.Device() && c.Properties.Sdk_version == "" {
|
} else if ctx.Device() && c.Properties.Sdk_version == "" {
|
||||||
return []string{"libc", "libm"}
|
return []string{"libc", "libm"}
|
||||||
@@ -941,7 +942,7 @@ func (c *CCLinked) depNames(ctx common.AndroidBaseContext, depNames CCDeps) CCDe
|
|||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
// libgcc and libatomic have to be last on the command line
|
// libgcc and libatomic have to be last on the command line
|
||||||
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcov", "libatomic")
|
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcov", "libatomic")
|
||||||
if !c.Properties.No_libgcc {
|
if !Bool(c.Properties.No_libgcc) {
|
||||||
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcc")
|
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcc")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1328,7 +1329,7 @@ var _ ccObjectProvider = (*ccObject)(nil)
|
|||||||
|
|
||||||
type CCBinaryProperties struct {
|
type CCBinaryProperties struct {
|
||||||
// compile executable with -static
|
// compile executable with -static
|
||||||
Static_executable bool
|
Static_executable *bool
|
||||||
|
|
||||||
// set the name of the output
|
// set the name of the output
|
||||||
Stem string `android:"arch_variant"`
|
Stem string `android:"arch_variant"`
|
||||||
@@ -1341,7 +1342,7 @@ type CCBinaryProperties struct {
|
|||||||
|
|
||||||
// Create a separate binary for each source file. Useful when there is
|
// 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.
|
// 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 {
|
type CCBinary struct {
|
||||||
@@ -1352,11 +1353,11 @@ type CCBinary struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CCBinary) buildStatic() bool {
|
func (c *CCBinary) buildStatic() bool {
|
||||||
return c.BinaryProperties.Static_executable
|
return Bool(c.BinaryProperties.Static_executable)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CCBinary) buildShared() bool {
|
func (c *CCBinary) buildShared() bool {
|
||||||
return !c.BinaryProperties.Static_executable
|
return !Bool(c.BinaryProperties.Static_executable)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
|
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)
|
depNames = c.CCLinked.depNames(ctx, depNames)
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
if c.Properties.Sdk_version == "" {
|
if c.Properties.Sdk_version == "" {
|
||||||
if c.BinaryProperties.Static_executable {
|
if Bool(c.BinaryProperties.Static_executable) {
|
||||||
depNames.CrtBegin = "crtbegin_static"
|
depNames.CrtBegin = "crtbegin_static"
|
||||||
} else {
|
} else {
|
||||||
depNames.CrtBegin = "crtbegin_dynamic"
|
depNames.CrtBegin = "crtbegin_dynamic"
|
||||||
}
|
}
|
||||||
depNames.CrtEnd = "crtend_android"
|
depNames.CrtEnd = "crtend_android"
|
||||||
} else {
|
} else {
|
||||||
if c.BinaryProperties.Static_executable {
|
if Bool(c.BinaryProperties.Static_executable) {
|
||||||
depNames.CrtBegin = "ndk_crtbegin_static." + c.Properties.Sdk_version
|
depNames.CrtBegin = "ndk_crtbegin_static." + c.Properties.Sdk_version
|
||||||
} else {
|
} else {
|
||||||
depNames.CrtBegin = "ndk_crtbegin_dynamic." + c.Properties.Sdk_version
|
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
|
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" {
|
if c.stl(ctx) == "libc++_static" {
|
||||||
depNames.StaticLibs = append(depNames.StaticLibs, "libm", "libc", "libdl")
|
depNames.StaticLibs = append(depNames.StaticLibs, "libm", "libc", "libdl")
|
||||||
}
|
}
|
||||||
@@ -1419,9 +1420,9 @@ func CCBinaryFactory() (blueprint.Module, []interface{}) {
|
|||||||
|
|
||||||
func (c *CCBinary) ModifyProperties(ctx common.AndroidBaseContext) {
|
func (c *CCBinary) ModifyProperties(ctx common.AndroidBaseContext) {
|
||||||
if ctx.Darwin() {
|
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
|
c.dynamicProperties.VariantIsStaticBinary = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1432,7 +1433,7 @@ func (c *CCBinary) flags(ctx common.AndroidModuleContext, flags CCFlags) CCFlags
|
|||||||
flags.CFlags = append(flags.CFlags, "-fpie")
|
flags.CFlags = append(flags.CFlags, "-fpie")
|
||||||
|
|
||||||
if ctx.Device() {
|
if ctx.Device() {
|
||||||
if c.BinaryProperties.Static_executable {
|
if Bool(c.BinaryProperties.Static_executable) {
|
||||||
// Clang driver needs -static to create static executable.
|
// Clang driver needs -static to create static executable.
|
||||||
// However, bionic/linker uses -shared to overwrite.
|
// However, bionic/linker uses -shared to overwrite.
|
||||||
// Linker for x86 targets does not allow coexistance of -static and -shared,
|
// 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,
|
func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
|
||||||
flags CCFlags, deps CCDeps, objFiles []string) {
|
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" +
|
ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
|
||||||
"from static libs or set static_executable: true")
|
"from static libs or set static_executable: true")
|
||||||
}
|
}
|
||||||
@@ -1504,7 +1505,7 @@ func (c *CCBinary) HostToolPath() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CCBinary) testPerSrc() bool {
|
func (c *CCBinary) testPerSrc() bool {
|
||||||
return c.BinaryProperties.Test_per_src
|
return Bool(c.BinaryProperties.Test_per_src)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *CCBinary) binary() *CCBinary {
|
func (c *CCBinary) binary() *CCBinary {
|
||||||
@@ -1938,3 +1939,5 @@ func lastUniqueElements(list []string) []string {
|
|||||||
}
|
}
|
||||||
return list[totalSkip:]
|
return list[totalSkip:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var Bool = proptools.Bool
|
||||||
|
@@ -426,6 +426,38 @@ func InitArchModule(m AndroidModule, defaultMultilib Multilib,
|
|||||||
|
|
||||||
var dashToUnderscoreReplacer = strings.NewReplacer("-", "_")
|
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.
|
// Rewrite the module's properties structs to contain arch-specific values.
|
||||||
func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext) {
|
func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext) {
|
||||||
arch := a.commonProperties.CompileArch
|
arch := a.commonProperties.CompileArch
|
||||||
@@ -435,13 +467,9 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
callback := func(srcPropertyName, dstPropertyName string) {
|
|
||||||
a.extendedProperties[dstPropertyName] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := range a.generalProperties {
|
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:
|
// Handle arch-specific properties in the form:
|
||||||
// arch: {
|
// arch: {
|
||||||
// arm64: {
|
// arm64: {
|
||||||
@@ -449,9 +477,10 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
|
|||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
t := arch.ArchType
|
t := arch.ArchType
|
||||||
|
|
||||||
field := proptools.FieldNameForProperty(t.Name)
|
field := proptools.FieldNameForProperty(t.Name)
|
||||||
extendProperties(ctx, "arch_variant", "arch."+t.Name, generalPropsValue,
|
prefix := "arch." + t.Name
|
||||||
reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
|
a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
|
||||||
|
|
||||||
// Handle arch-variant-specific properties in the form:
|
// Handle arch-variant-specific properties in the form:
|
||||||
// arch: {
|
// arch: {
|
||||||
@@ -462,8 +491,8 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
|
|||||||
v := dashToUnderscoreReplacer.Replace(arch.ArchVariant)
|
v := dashToUnderscoreReplacer.Replace(arch.ArchVariant)
|
||||||
if v != "" {
|
if v != "" {
|
||||||
field := proptools.FieldNameForProperty(v)
|
field := proptools.FieldNameForProperty(v)
|
||||||
extendProperties(ctx, "arch_variant", "arch."+v, generalPropsValue,
|
prefix := "arch." + v
|
||||||
reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
|
a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle cpu-variant-specific properties in the form:
|
// Handle cpu-variant-specific properties in the form:
|
||||||
@@ -475,8 +504,8 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
|
|||||||
c := dashToUnderscoreReplacer.Replace(arch.CpuVariant)
|
c := dashToUnderscoreReplacer.Replace(arch.CpuVariant)
|
||||||
if c != "" {
|
if c != "" {
|
||||||
field := proptools.FieldNameForProperty(c)
|
field := proptools.FieldNameForProperty(c)
|
||||||
extendProperties(ctx, "arch_variant", "arch."+c, generalPropsValue,
|
prefix := "arch." + c
|
||||||
reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
|
a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle multilib-specific properties in the form:
|
// Handle multilib-specific properties in the form:
|
||||||
@@ -485,9 +514,9 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
|
|||||||
// key: value,
|
// key: value,
|
||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
multilibField := proptools.FieldNameForProperty(t.Multilib)
|
field = proptools.FieldNameForProperty(t.Multilib)
|
||||||
extendProperties(ctx, "arch_variant", "multilib."+t.Multilib, generalPropsValue,
|
prefix = "multilib." + t.Multilib
|
||||||
reflect.ValueOf(a.archProperties[i].Multilib).FieldByName(multilibField).Elem().Elem(), callback)
|
a.appendProperties(ctx, genProps, archProps.Multilib, field, prefix)
|
||||||
|
|
||||||
// Handle host-or-device-specific properties in the form:
|
// Handle host-or-device-specific properties in the form:
|
||||||
// target: {
|
// target: {
|
||||||
@@ -496,9 +525,9 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
|
|||||||
// },
|
// },
|
||||||
// },
|
// },
|
||||||
hodProperty := hod.Property()
|
hodProperty := hod.Property()
|
||||||
hodField := proptools.FieldNameForProperty(hodProperty)
|
field = proptools.FieldNameForProperty(hodProperty)
|
||||||
extendProperties(ctx, "arch_variant", "target."+hodProperty, generalPropsValue,
|
prefix = "target." + hodProperty
|
||||||
reflect.ValueOf(a.archProperties[i].Target).FieldByName(hodField).Elem().Elem(), callback)
|
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
|
||||||
|
|
||||||
// Handle host target properties in the form:
|
// Handle host target properties in the form:
|
||||||
// target: {
|
// target: {
|
||||||
@@ -527,15 +556,18 @@ func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext)
|
|||||||
if hod.Host() {
|
if hod.Host() {
|
||||||
for _, v := range osList {
|
for _, v := range osList {
|
||||||
if v.goos == runtime.GOOS {
|
if v.goos == runtime.GOOS {
|
||||||
extendProperties(ctx, "arch_variant", "target."+v.goos, generalPropsValue,
|
field := v.field
|
||||||
reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field).Elem().Elem(), callback)
|
prefix := "target." + v.goos
|
||||||
|
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
|
||||||
t := arch.ArchType
|
t := arch.ArchType
|
||||||
extendProperties(ctx, "arch_variant", "target."+v.goos+"_"+t.Name, generalPropsValue,
|
field = v.field + "_" + t.Name
|
||||||
reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field+"_"+t.Name).Elem().Elem(), callback)
|
prefix = "target." + v.goos + "_" + t.Name
|
||||||
|
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extendProperties(ctx, "arch_variant", "target.not_windows", generalPropsValue,
|
field := "Not_windows"
|
||||||
reflect.ValueOf(a.archProperties[i].Target).FieldByName("Not_windows").Elem().Elem(), callback)
|
prefix := "target.not_windows"
|
||||||
|
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle 64-bit device properties in the form:
|
// 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
|
// debuggerd that need to know when they are a 32-bit process running on a 64-bit device
|
||||||
if hod.Device() {
|
if hod.Device() {
|
||||||
if true /* && target_is_64_bit */ {
|
if true /* && target_is_64_bit */ {
|
||||||
extendProperties(ctx, "arch_variant", "target.android64", generalPropsValue,
|
field := "Android64"
|
||||||
reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android64").Elem().Elem(), callback)
|
prefix := "target.android64"
|
||||||
|
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
|
||||||
} else {
|
} else {
|
||||||
extendProperties(ctx, "arch_variant", "target.android32", generalPropsValue,
|
field := "Android32"
|
||||||
reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android32").Elem().Elem(), callback)
|
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() {
|
if hod.Device() {
|
||||||
t := arch.ArchType
|
t := arch.ArchType
|
||||||
extendProperties(ctx, "arch_variant", "target.android_"+t.Name, generalPropsValue,
|
field := "Android_" + t.Name
|
||||||
reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android_"+t.Name).Elem().Elem(), callback)
|
prefix := "target.android_" + t.Name
|
||||||
|
a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Failed() {
|
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 := m.base()
|
||||||
base.module = m
|
base.module = m
|
||||||
base.extendedProperties = make(map[string]struct{})
|
|
||||||
|
|
||||||
propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
|
propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
|
||||||
|
|
||||||
@@ -198,7 +197,6 @@ type AndroidModuleBase struct {
|
|||||||
hostAndDeviceProperties hostAndDeviceProperties
|
hostAndDeviceProperties hostAndDeviceProperties
|
||||||
generalProperties []interface{}
|
generalProperties []interface{}
|
||||||
archProperties []*archProperties
|
archProperties []*archProperties
|
||||||
extendedProperties map[string]struct{}
|
|
||||||
|
|
||||||
noAddressSanitizer bool
|
noAddressSanitizer bool
|
||||||
installFiles []string
|
installFiles []string
|
||||||
@@ -340,9 +338,8 @@ func (a *AndroidModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
|
|||||||
hod: a.commonProperties.CompileHostOrDevice,
|
hod: a.commonProperties.CompileHostOrDevice,
|
||||||
config: ctx.Config().(Config),
|
config: ctx.Config().(Config),
|
||||||
},
|
},
|
||||||
installDeps: a.computeInstallDeps(ctx),
|
installDeps: a.computeInstallDeps(ctx),
|
||||||
installFiles: a.installFiles,
|
installFiles: a.installFiles,
|
||||||
extendedProperties: a.extendedProperties,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.commonProperties.Disabled {
|
if a.commonProperties.Disabled {
|
||||||
@@ -373,10 +370,9 @@ type androidBaseContextImpl struct {
|
|||||||
type androidModuleContext struct {
|
type androidModuleContext struct {
|
||||||
blueprint.ModuleContext
|
blueprint.ModuleContext
|
||||||
androidBaseContextImpl
|
androidBaseContextImpl
|
||||||
installDeps []string
|
installDeps []string
|
||||||
installFiles []string
|
installFiles []string
|
||||||
checkbuildFiles []string
|
checkbuildFiles []string
|
||||||
extendedProperties map[string]struct{}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
|
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)
|
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 {
|
func (a *androidBaseContextImpl) Arch() Arch {
|
||||||
return a.arch
|
return a.arch
|
||||||
}
|
}
|
||||||
|
@@ -113,7 +113,7 @@ func VariableMutator(mctx blueprint.EarlyMutatorContext) {
|
|||||||
|
|
||||||
// TODO: depend on config variable, create variants, propagate variants up tree
|
// TODO: depend on config variable, create variants, propagate variants up tree
|
||||||
a := module.base()
|
a := module.base()
|
||||||
variableValues := reflect.ValueOf(a.variableProperties.Product_variables)
|
variableValues := reflect.ValueOf(&a.variableProperties.Product_variables).Elem()
|
||||||
zeroValues := reflect.ValueOf(zeroProductVariables.Product_variables)
|
zeroValues := reflect.ValueOf(zeroProductVariables.Product_variables)
|
||||||
|
|
||||||
for i := 0; i < variableValues.NumField(); i++ {
|
for i := 0; i < variableValues.NumField(); i++ {
|
||||||
@@ -147,16 +147,19 @@ func VariableMutator(mctx blueprint.EarlyMutatorContext) {
|
|||||||
func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext,
|
func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext,
|
||||||
prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
|
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 {
|
if variableValue != nil {
|
||||||
printfIntoProperties(productVariablePropertyValue, variableValue)
|
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{}) {
|
func printfIntoProperties(productVariablePropertyValue reflect.Value, variableValue interface{}) {
|
||||||
|
Reference in New Issue
Block a user