summaryrefslogtreecommitdiff
path: root/sdk/update.go
diff options
context:
space:
mode:
author Paul Duffin <paulduffin@google.com> 2020-05-07 21:58:14 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2020-05-07 21:58:14 +0000
commitaf6fbcbccacf5a2f4a7f683ca089f47d3ccb04fe (patch)
tree7f7d764226e5510c8e8cfce8956e25828774316e /sdk/update.go
parentcf23ab4cd80fd4448473126787fe1fce84c68a3b (diff)
parent2af52380be107029ac4d8fbc25c34669fbfce536 (diff)
Merge changes I167b47a1,I7ebd3330,Ifc8116e1
* changes: Fix snapshot of a host/device cc_library with stubs Adds support for 'ignored-on-host' Detect invalid arch specific properties in snapshot
Diffstat (limited to 'sdk/update.go')
-rw-r--r--sdk/update.go84
1 files changed, 81 insertions, 3 deletions
diff --git a/sdk/update.go b/sdk/update.go
index 03a5c0379..d43a42d6e 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -982,6 +982,13 @@ func (osInfo *osTypeSpecificInfo) addToPropertySet(ctx *memberContext, bpModule
}
}
+func (osInfo *osTypeSpecificInfo) isHostVariant() bool {
+ osClass := osInfo.osType.Class
+ return osClass == android.Host || osClass == android.HostCross
+}
+
+var _ isHostVariant = (*osTypeSpecificInfo)(nil)
+
func (osInfo *osTypeSpecificInfo) String() string {
return fmt.Sprintf("OsType{%s}", osInfo.osType)
}
@@ -1215,16 +1222,34 @@ func (s *sdk) getPossibleOsTypes() []android.OsType {
// struct (or one of its embedded structs).
type fieldAccessorFunc func(structValue reflect.Value) reflect.Value
+// Checks the metadata to determine whether the property should be ignored for the
+// purposes of common value extraction or not.
+type extractorMetadataPredicate func(metadata propertiesContainer) bool
+
+// Indicates whether optimizable properties are provided by a host variant or
+// not.
+type isHostVariant interface {
+ isHostVariant() bool
+}
+
// A property that can be optimized by the commonValueExtractor.
type extractorProperty struct {
// The name of the field for this property.
name string
+ // Filter that can use metadata associated with the properties being optimized
+ // to determine whether the field should be ignored during common value
+ // optimization.
+ filter extractorMetadataPredicate
+
// Retrieves the value on which common value optimization will be performed.
getter fieldAccessorFunc
// The empty value for the field.
emptyValue reflect.Value
+
+ // True if the property can support arch variants false otherwise.
+ archVariant bool
}
func (p extractorProperty) String() string {
@@ -1270,6 +1295,20 @@ func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingS
continue
}
+ var filter extractorMetadataPredicate
+
+ // Add a filter
+ if proptools.HasTag(field, "sdk", "ignored-on-host") {
+ filter = func(metadata propertiesContainer) bool {
+ if m, ok := metadata.(isHostVariant); ok {
+ if m.isHostVariant() {
+ return false
+ }
+ }
+ return true
+ }
+ }
+
// Save a copy of the field index for use in the function.
fieldIndex := f
@@ -1301,8 +1340,10 @@ func (e *commonValueExtractor) gatherFields(structType reflect.Type, containingS
} else {
property := extractorProperty{
name,
+ filter,
fieldGetter,
reflect.Zero(field.Type),
+ proptools.HasTag(field, "android", "arch_variant"),
}
e.properties = append(e.properties, property)
}
@@ -1368,17 +1409,38 @@ func (e *commonValueExtractor) extractCommonProperties(commonProperties interfac
for _, property := range e.properties {
fieldGetter := property.getter
+ filter := property.filter
+ if filter == nil {
+ filter = func(metadata propertiesContainer) bool {
+ return true
+ }
+ }
// Check to see if all the structures have the same value for the field. The commonValue
- // is nil on entry to the loop and if it is nil on exit then there is no common value,
- // otherwise it points to the common value.
+ // is nil on entry to the loop and if it is nil on exit then there is no common value or
+ // all the values have been filtered out, otherwise it points to the common value.
var commonValue *reflect.Value
+ // Assume that all the values will be the same.
+ //
+ // While similar to this is not quite the same as commonValue == nil. If all the values
+ // have been filtered out then this will be false but commonValue == nil will be true.
+ valuesDiffer := false
+
for i := 0; i < sliceValue.Len(); i++ {
container := sliceValue.Index(i).Interface().(propertiesContainer)
itemValue := reflect.ValueOf(container.optimizableProperties())
fieldValue := fieldGetter(itemValue)
+ if !filter(container) {
+ expectedValue := property.emptyValue.Interface()
+ actualValue := fieldValue.Interface()
+ if !reflect.DeepEqual(expectedValue, actualValue) {
+ return fmt.Errorf("field %q is supposed to be ignored for %q but is set to %#v instead of %#v", property, container, actualValue, expectedValue)
+ }
+ continue
+ }
+
if commonValue == nil {
// Use the first value as the commonProperties value.
commonValue = &fieldValue
@@ -1387,12 +1449,13 @@ func (e *commonValueExtractor) extractCommonProperties(commonProperties interfac
// no value in common so break out.
if !reflect.DeepEqual(fieldValue.Interface(), commonValue.Interface()) {
commonValue = nil
+ valuesDiffer = true
break
}
}
}
- // If the fields all have a common value then store it in the common struct field
+ // If the fields all have common value then store it in the common struct field
// and set the input struct's field to the empty value.
if commonValue != nil {
emptyValue := property.emptyValue
@@ -1404,6 +1467,21 @@ func (e *commonValueExtractor) extractCommonProperties(commonProperties interfac
fieldValue.Set(emptyValue)
}
}
+
+ if valuesDiffer && !property.archVariant {
+ // The values differ but the property does not support arch variants so it
+ // is an error.
+ var details strings.Builder
+ for i := 0; i < sliceValue.Len(); i++ {
+ container := sliceValue.Index(i).Interface().(propertiesContainer)
+ itemValue := reflect.ValueOf(container.optimizableProperties())
+ fieldValue := fieldGetter(itemValue)
+
+ _, _ = fmt.Fprintf(&details, "\n %q has value %q", container.String(), fieldValue.Interface())
+ }
+
+ return fmt.Errorf("field %q is not tagged as \"arch_variant\" but has arch specific properties:%s", property.String(), details.String())
+ }
}
return nil