Remove more unused code
Bug: 315353489 Test: builds Change-Id: I34cf772ba3c927bbbc141afb149cf0501ca6351f
This commit is contained in:
425
android/arch.go
425
android/arch.go
@@ -16,16 +16,11 @@ package android
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"android/soong/bazel"
|
||||
"android/soong/starlark_fmt"
|
||||
|
||||
"github.com/google/blueprint"
|
||||
"github.com/google/blueprint/bootstrap"
|
||||
"github.com/google/blueprint/proptools"
|
||||
@@ -1899,428 +1894,8 @@ func decodeMultilibTargets(multilib string, targets []Target, prefer32 bool) ([]
|
||||
return buildTargets, nil
|
||||
}
|
||||
|
||||
func (m *ModuleBase) getArchPropertySet(propertySet interface{}, archType ArchType) interface{} {
|
||||
archString := archType.Field
|
||||
for i := range m.archProperties {
|
||||
if m.archProperties[i] == nil {
|
||||
// Skip over nil properties
|
||||
continue
|
||||
}
|
||||
|
||||
// Not archProperties are usable; this function looks for properties of a very specific
|
||||
// form, and ignores the rest.
|
||||
for _, archProperty := range m.archProperties[i] {
|
||||
// archPropValue is a property struct, we are looking for the form:
|
||||
// `arch: { arm: { key: value, ... }}`
|
||||
archPropValue := reflect.ValueOf(archProperty).Elem()
|
||||
|
||||
// Unwrap src so that it should looks like a pointer to `arm: { key: value, ... }`
|
||||
src := archPropValue.FieldByName("Arch").Elem()
|
||||
|
||||
// Step into non-nil pointers to structs in the src value.
|
||||
if src.Kind() == reflect.Ptr {
|
||||
if src.IsNil() {
|
||||
continue
|
||||
}
|
||||
src = src.Elem()
|
||||
}
|
||||
|
||||
// Find the requested field (e.g. arm, x86) in the src struct.
|
||||
src = src.FieldByName(archString)
|
||||
|
||||
// We only care about structs.
|
||||
if !src.IsValid() || src.Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
// If the value of the field is a struct then step into the
|
||||
// BlueprintEmbed field. The special "BlueprintEmbed" name is
|
||||
// used by createArchPropTypeDesc to embed the arch properties
|
||||
// in the parent struct, so the src arch prop should be in this
|
||||
// field.
|
||||
//
|
||||
// See createArchPropTypeDesc for more details on how Arch-specific
|
||||
// module properties are processed from the nested props and written
|
||||
// into the module's archProperties.
|
||||
src = src.FieldByName("BlueprintEmbed")
|
||||
|
||||
// Clone the destination prop, since we want a unique prop struct per arch.
|
||||
propertySetClone := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
|
||||
|
||||
// Copy the located property struct into the cloned destination property struct.
|
||||
err := proptools.ExtendMatchingProperties([]interface{}{propertySetClone}, src.Interface(), nil, proptools.OrderReplace)
|
||||
if err != nil {
|
||||
// This is fine, it just means the src struct doesn't match the type of propertySet.
|
||||
continue
|
||||
}
|
||||
|
||||
return propertySetClone
|
||||
}
|
||||
}
|
||||
// No property set was found specific to the given arch, so return an empty
|
||||
// property set.
|
||||
return reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
|
||||
}
|
||||
|
||||
// getMultilibPropertySet returns a property set struct matching the type of
|
||||
// `propertySet`, containing multilib-specific module properties for the given architecture.
|
||||
// If no multilib-specific properties exist for the given architecture, returns an empty property
|
||||
// set matching `propertySet`'s type.
|
||||
func (m *ModuleBase) getMultilibPropertySet(propertySet interface{}, archType ArchType) interface{} {
|
||||
// archType.Multilib is lowercase (for example, lib32) but property struct field is
|
||||
// capitalized, such as Lib32, so use strings.Title to capitalize it.
|
||||
multiLibString := strings.Title(archType.Multilib)
|
||||
|
||||
for i := range m.archProperties {
|
||||
if m.archProperties[i] == nil {
|
||||
// Skip over nil properties
|
||||
continue
|
||||
}
|
||||
|
||||
// Not archProperties are usable; this function looks for properties of a very specific
|
||||
// form, and ignores the rest.
|
||||
for _, archProperties := range m.archProperties[i] {
|
||||
// archPropValue is a property struct, we are looking for the form:
|
||||
// `multilib: { lib32: { key: value, ... }}`
|
||||
archPropValue := reflect.ValueOf(archProperties).Elem()
|
||||
|
||||
// Unwrap src so that it should looks like a pointer to `lib32: { key: value, ... }`
|
||||
src := archPropValue.FieldByName("Multilib").Elem()
|
||||
|
||||
// Step into non-nil pointers to structs in the src value.
|
||||
if src.Kind() == reflect.Ptr {
|
||||
if src.IsNil() {
|
||||
// Ignore nil pointers.
|
||||
continue
|
||||
}
|
||||
src = src.Elem()
|
||||
}
|
||||
|
||||
// Find the requested field (e.g. lib32) in the src struct.
|
||||
src = src.FieldByName(multiLibString)
|
||||
|
||||
// We only care about valid struct pointers.
|
||||
if !src.IsValid() || src.Kind() != reflect.Ptr || src.Elem().Kind() != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
// Get the zero value for the requested property set.
|
||||
propertySetClone := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
|
||||
|
||||
// Copy the located property struct into the "zero" property set struct.
|
||||
err := proptools.ExtendMatchingProperties([]interface{}{propertySetClone}, src.Interface(), nil, proptools.OrderReplace)
|
||||
|
||||
if err != nil {
|
||||
// This is fine, it just means the src struct doesn't match.
|
||||
continue
|
||||
}
|
||||
|
||||
return propertySetClone
|
||||
}
|
||||
}
|
||||
|
||||
// There were no multilib properties specifically matching the given archtype.
|
||||
// Return zeroed value.
|
||||
return reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
|
||||
}
|
||||
|
||||
// ArchVariantContext defines the limited context necessary to retrieve arch_variant properties.
|
||||
type ArchVariantContext interface {
|
||||
ModuleErrorf(fmt string, args ...interface{})
|
||||
PropertyErrorf(property, fmt string, args ...interface{})
|
||||
}
|
||||
|
||||
// ArchVariantProperties represents a map of arch-variant config strings to a property interface{}.
|
||||
type ArchVariantProperties map[string]interface{}
|
||||
|
||||
// ConfigurationAxisToArchVariantProperties represents a map of bazel.ConfigurationAxis to
|
||||
// ArchVariantProperties, such that each independent arch-variant axis maps to the
|
||||
// configs/properties for that axis.
|
||||
type ConfigurationAxisToArchVariantProperties map[bazel.ConfigurationAxis]ArchVariantProperties
|
||||
|
||||
// GetArchVariantProperties returns a ConfigurationAxisToArchVariantProperties where the
|
||||
// arch-variant properties correspond to the values of the properties of the 'propertySet' struct
|
||||
// that are specific to that axis/configuration. Each axis is independent, containing
|
||||
// non-overlapping configs that correspond to the various "arch-variant" support, at this time:
|
||||
//
|
||||
// arches (including multilib)
|
||||
// oses
|
||||
// arch+os combinations
|
||||
//
|
||||
// For example, passing a struct { Foo bool, Bar string } will return an interface{} that can be
|
||||
// type asserted back into the same struct, containing the config-specific property value specified
|
||||
// by the module if defined.
|
||||
//
|
||||
// Arch-specific properties may come from an arch stanza or a multilib stanza; properties
|
||||
// in these stanzas are combined.
|
||||
// For example: `arch: { x86: { Foo: ["bar"] } }, multilib: { lib32: {` Foo: ["baz"] } }`
|
||||
// will result in `Foo: ["bar", "baz"]` being returned for architecture x86, if the given
|
||||
// propertyset contains `Foo []string`.
|
||||
func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySet interface{}) ConfigurationAxisToArchVariantProperties {
|
||||
// Return value of the arch types to the prop values for that arch.
|
||||
axisToProps := ConfigurationAxisToArchVariantProperties{}
|
||||
|
||||
// Nothing to do for non-arch-specific modules.
|
||||
if !m.ArchSpecific() {
|
||||
return axisToProps
|
||||
}
|
||||
|
||||
dstType := reflect.ValueOf(propertySet).Type()
|
||||
var archProperties []interface{}
|
||||
|
||||
// First find the property set in the module that corresponds to the requested
|
||||
// one. m.archProperties[i] corresponds to m.GetProperties()[i].
|
||||
for i, generalProp := range m.GetProperties() {
|
||||
srcType := reflect.ValueOf(generalProp).Type()
|
||||
if srcType == dstType {
|
||||
archProperties = m.archProperties[i]
|
||||
axisToProps[bazel.NoConfigAxis] = ArchVariantProperties{"": generalProp}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if archProperties == nil {
|
||||
// This module does not have the property set requested
|
||||
return axisToProps
|
||||
}
|
||||
|
||||
archToProp := ArchVariantProperties{}
|
||||
// For each arch type (x86, arm64, etc.)
|
||||
for _, arch := range ArchTypeList() {
|
||||
// Arch properties are sometimes sharded (see createArchPropTypeDesc() ).
|
||||
// Iterate over every shard and extract a struct with the same type as the
|
||||
// input one that contains the data specific to that arch.
|
||||
propertyStructs := make([]reflect.Value, 0)
|
||||
archFeaturePropertyStructs := make(map[string][]reflect.Value, 0)
|
||||
for _, archProperty := range archProperties {
|
||||
archTypeStruct, ok := getArchTypeStruct(ctx, archProperty, arch)
|
||||
if ok {
|
||||
propertyStructs = append(propertyStructs, archTypeStruct)
|
||||
|
||||
// For each feature this arch supports (arm: neon, x86: ssse3, sse4, ...)
|
||||
for _, feature := range archFeatures[arch] {
|
||||
prefix := "arch." + arch.Name + "." + feature
|
||||
if featureProperties, ok := getChildPropertyStruct(ctx, archTypeStruct, feature, prefix); ok {
|
||||
archFeaturePropertyStructs[feature] = append(archFeaturePropertyStructs[feature], featureProperties)
|
||||
}
|
||||
}
|
||||
}
|
||||
multilibStruct, ok := getMultilibStruct(ctx, archProperty, arch)
|
||||
if ok {
|
||||
propertyStructs = append(propertyStructs, multilibStruct)
|
||||
}
|
||||
}
|
||||
|
||||
archToProp[arch.Name] = mergeStructs(ctx, propertyStructs, propertySet)
|
||||
|
||||
// In soong, if multiple features match the current configuration, they're
|
||||
// all used. In bazel, we have to have unambiguous select() statements, so
|
||||
// we can't have two features that are both active in the same select().
|
||||
// One alternative is to split out each feature into a separate select(),
|
||||
// but then it's difficult to support exclude_srcs, which may need to
|
||||
// exclude things from the regular arch select() statement if a certain
|
||||
// feature is active. Instead, keep the features in the same select
|
||||
// statement as the arches, but emit the power set of all possible
|
||||
// combinations of features, so that bazel can match the most precise one.
|
||||
allFeatures := make([]string, 0, len(archFeaturePropertyStructs))
|
||||
for feature := range archFeaturePropertyStructs {
|
||||
allFeatures = append(allFeatures, feature)
|
||||
}
|
||||
for _, features := range bazel.PowerSetWithoutEmptySet(allFeatures) {
|
||||
sort.Strings(features)
|
||||
propsForCurrentFeatureSet := make([]reflect.Value, 0)
|
||||
propsForCurrentFeatureSet = append(propsForCurrentFeatureSet, propertyStructs...)
|
||||
for _, feature := range features {
|
||||
propsForCurrentFeatureSet = append(propsForCurrentFeatureSet, archFeaturePropertyStructs[feature]...)
|
||||
}
|
||||
archToProp[arch.Name+"-"+strings.Join(features, "-")] =
|
||||
mergeStructs(ctx, propsForCurrentFeatureSet, propertySet)
|
||||
}
|
||||
}
|
||||
axisToProps[bazel.ArchConfigurationAxis] = archToProp
|
||||
|
||||
osToProp := ArchVariantProperties{}
|
||||
archOsToProp := ArchVariantProperties{}
|
||||
|
||||
linuxStructs := getTargetStructs(ctx, archProperties, "Linux")
|
||||
bionicStructs := getTargetStructs(ctx, archProperties, "Bionic")
|
||||
hostStructs := getTargetStructs(ctx, archProperties, "Host")
|
||||
hostLinuxStructs := getTargetStructs(ctx, archProperties, "Host_linux")
|
||||
hostNotWindowsStructs := getTargetStructs(ctx, archProperties, "Not_windows")
|
||||
|
||||
// For android, linux, ...
|
||||
for _, os := range osTypeList {
|
||||
if os == CommonOS {
|
||||
// It looks like this OS value is not used in Blueprint files
|
||||
continue
|
||||
}
|
||||
osStructs := make([]reflect.Value, 0)
|
||||
|
||||
osSpecificStructs := getTargetStructs(ctx, archProperties, os.Field)
|
||||
if os.Class == Host {
|
||||
osStructs = append(osStructs, hostStructs...)
|
||||
}
|
||||
if os.Linux() {
|
||||
osStructs = append(osStructs, linuxStructs...)
|
||||
}
|
||||
if os.Bionic() {
|
||||
osStructs = append(osStructs, bionicStructs...)
|
||||
}
|
||||
if os.Linux() && os.Class == Host {
|
||||
osStructs = append(osStructs, hostLinuxStructs...)
|
||||
}
|
||||
|
||||
if os == LinuxMusl {
|
||||
osStructs = append(osStructs, getTargetStructs(ctx, archProperties, "Musl")...)
|
||||
}
|
||||
if os == Linux {
|
||||
osStructs = append(osStructs, getTargetStructs(ctx, archProperties, "Glibc")...)
|
||||
}
|
||||
|
||||
osStructs = append(osStructs, osSpecificStructs...)
|
||||
|
||||
if os.Class == Host && os != Windows {
|
||||
osStructs = append(osStructs, hostNotWindowsStructs...)
|
||||
}
|
||||
osToProp[os.Name] = mergeStructs(ctx, osStructs, propertySet)
|
||||
|
||||
// For arm, x86, ...
|
||||
for _, arch := range osArchTypeMap[os] {
|
||||
osArchStructs := make([]reflect.Value, 0)
|
||||
|
||||
// Auto-combine with Linux_ and Bionic_ targets. This potentially results in
|
||||
// repetition and select() bloat, but use of Linux_* and Bionic_* targets is rare.
|
||||
// TODO(b/201423152): Look into cleanup.
|
||||
if os.Linux() {
|
||||
targetField := "Linux_" + arch.Name
|
||||
targetStructs := getTargetStructs(ctx, archProperties, targetField)
|
||||
osArchStructs = append(osArchStructs, targetStructs...)
|
||||
}
|
||||
if os.Bionic() {
|
||||
targetField := "Bionic_" + arch.Name
|
||||
targetStructs := getTargetStructs(ctx, archProperties, targetField)
|
||||
osArchStructs = append(osArchStructs, targetStructs...)
|
||||
}
|
||||
if os == LinuxMusl {
|
||||
targetField := "Musl_" + arch.Name
|
||||
targetStructs := getTargetStructs(ctx, archProperties, targetField)
|
||||
osArchStructs = append(osArchStructs, targetStructs...)
|
||||
}
|
||||
if os == Linux {
|
||||
targetField := "Glibc_" + arch.Name
|
||||
targetStructs := getTargetStructs(ctx, archProperties, targetField)
|
||||
osArchStructs = append(osArchStructs, targetStructs...)
|
||||
}
|
||||
|
||||
targetField := GetCompoundTargetField(os, arch)
|
||||
targetName := fmt.Sprintf("%s_%s", os.Name, arch.Name)
|
||||
targetStructs := getTargetStructs(ctx, archProperties, targetField)
|
||||
osArchStructs = append(osArchStructs, targetStructs...)
|
||||
|
||||
archOsToProp[targetName] = mergeStructs(ctx, osArchStructs, propertySet)
|
||||
}
|
||||
}
|
||||
|
||||
axisToProps[bazel.OsConfigurationAxis] = osToProp
|
||||
axisToProps[bazel.OsArchConfigurationAxis] = archOsToProp
|
||||
return axisToProps
|
||||
}
|
||||
|
||||
// Returns a struct matching the propertySet interface, containing properties specific to the targetName
|
||||
// For example, given these arguments:
|
||||
//
|
||||
// propertySet = BaseCompilerProperties
|
||||
// targetName = "android_arm"
|
||||
//
|
||||
// And given this Android.bp fragment:
|
||||
//
|
||||
// target:
|
||||
// android_arm: {
|
||||
// srcs: ["foo.c"],
|
||||
// }
|
||||
// android_arm64: {
|
||||
// srcs: ["bar.c"],
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// This would return a BaseCompilerProperties with BaseCompilerProperties.Srcs = ["foo.c"]
|
||||
func getTargetStructs(ctx ArchVariantContext, archProperties []interface{}, targetName string) []reflect.Value {
|
||||
var propertyStructs []reflect.Value
|
||||
for _, archProperty := range archProperties {
|
||||
archPropValues := reflect.ValueOf(archProperty).Elem()
|
||||
targetProp := archPropValues.FieldByName("Target").Elem()
|
||||
targetStruct, ok := getChildPropertyStruct(ctx, targetProp, targetName, targetName)
|
||||
if ok {
|
||||
propertyStructs = append(propertyStructs, targetStruct)
|
||||
} else {
|
||||
return []reflect.Value{}
|
||||
}
|
||||
}
|
||||
|
||||
return propertyStructs
|
||||
}
|
||||
|
||||
func mergeStructs(ctx ArchVariantContext, propertyStructs []reflect.Value, propertySet interface{}) interface{} {
|
||||
// Create a new instance of the requested property set
|
||||
value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface()
|
||||
|
||||
// Merge all the structs together
|
||||
for _, propertyStruct := range propertyStructs {
|
||||
mergePropertyStruct(ctx, value, propertyStruct)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
func printArchTypeStarlarkDict(dict map[ArchType][]string) string {
|
||||
valDict := make(map[string]string, len(dict))
|
||||
for k, v := range dict {
|
||||
valDict[k.String()] = starlark_fmt.PrintStringList(v, 1)
|
||||
}
|
||||
return starlark_fmt.PrintDict(valDict, 0)
|
||||
}
|
||||
|
||||
func printArchTypeNestedStarlarkDict(dict map[ArchType]map[string][]string) string {
|
||||
valDict := make(map[string]string, len(dict))
|
||||
for k, v := range dict {
|
||||
valDict[k.String()] = starlark_fmt.PrintStringListDict(v, 1)
|
||||
}
|
||||
return starlark_fmt.PrintDict(valDict, 0)
|
||||
}
|
||||
|
||||
func printArchConfigList(arches []archConfig) string {
|
||||
jsonOut, err := json.MarshalIndent(arches, "", starlark_fmt.Indention(1))
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Error converting arch configs %#v to json: %q", arches, err))
|
||||
}
|
||||
return fmt.Sprintf("json.decode('''%s''')", string(jsonOut))
|
||||
}
|
||||
|
||||
func StarlarkArchConfigurations() string {
|
||||
return fmt.Sprintf(`
|
||||
_arch_to_variants = %s
|
||||
|
||||
_arch_to_cpu_variants = %s
|
||||
|
||||
_arch_to_features = %s
|
||||
|
||||
_android_arch_feature_for_arch_variant = %s
|
||||
|
||||
_aml_arches = %s
|
||||
|
||||
_ndk_arches = %s
|
||||
|
||||
arch_to_variants = _arch_to_variants
|
||||
arch_to_cpu_variants = _arch_to_cpu_variants
|
||||
arch_to_features = _arch_to_features
|
||||
android_arch_feature_for_arch_variants = _android_arch_feature_for_arch_variant
|
||||
aml_arches = _aml_arches
|
||||
ndk_arches = _ndk_arches
|
||||
`, printArchTypeStarlarkDict(archVariants),
|
||||
printArchTypeStarlarkDict(cpuVariants),
|
||||
printArchTypeStarlarkDict(archFeatures),
|
||||
printArchTypeNestedStarlarkDict(androidArchFeatureMap),
|
||||
printArchConfigList(getAmlAbisConfig()),
|
||||
printArchConfigList(getNdkAbisConfig()),
|
||||
)
|
||||
}
|
||||
|
Reference in New Issue
Block a user