Merge "Remove more unused code" into main

This commit is contained in:
Colin Cross
2024-04-22 18:50:08 +00:00
committed by Gerrit Code Review
2 changed files with 0 additions and 812 deletions

View File

@@ -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()),
)
}