diff --git a/sdk/sdk.go b/sdk/sdk.go index 1c6002a31..95a49306d 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -101,6 +101,9 @@ type sdkMemberListProperty struct { // getter for the list of member names getter func(properties interface{}) []string + // setter for the list of member names + setter func(properties interface{}, list []string) + // the type of member referenced in the list memberType android.SdkMemberType @@ -127,6 +130,8 @@ type dynamicSdkMemberTypes struct { // Information about each of the member type specific list properties. memberListProperties []*sdkMemberListProperty + + memberTypeToProperty map[android.SdkMemberType]*sdkMemberListProperty } func (d *dynamicSdkMemberTypes) createMemberListProperties() interface{} { @@ -160,6 +165,7 @@ func getDynamicSdkMemberTypes(registry *android.SdkMemberTypesRegistry) *dynamic func createDynamicSdkMemberTypes(sdkMemberTypes []android.SdkMemberType) *dynamicSdkMemberTypes { var listProperties []*sdkMemberListProperty + memberTypeToProperty := map[android.SdkMemberType]*sdkMemberListProperty{} var fields []reflect.StructField // Iterate over the member types creating StructField and sdkMemberListProperty objects. @@ -191,12 +197,24 @@ func createDynamicSdkMemberTypes(sdkMemberTypes []android.SdkMemberType) *dynami return list }, + setter: func(properties interface{}, list []string) { + // The properties is expected to be of the following form (where + // is the name of an SdkMemberType.SdkPropertyName(). + // properties *struct { []string, ....} + // + // Although it accesses the field by index the following reflection code is equivalent to: + // *properties. = list + // + reflect.ValueOf(properties).Elem().Field(fieldIndex).Set(reflect.ValueOf(list)) + }, + memberType: memberType, // Dependencies added directly from member properties are always exported. dependencyTag: android.DependencyTagForSdkMemberType(memberType, true), } + memberTypeToProperty[memberType] = memberListProperty listProperties = append(listProperties, memberListProperty) } @@ -205,6 +223,7 @@ func createDynamicSdkMemberTypes(sdkMemberTypes []android.SdkMemberType) *dynami return &dynamicSdkMemberTypes{ memberListProperties: listProperties, + memberTypeToProperty: memberTypeToProperty, propertiesStructType: propertiesStructType, } } @@ -256,6 +275,10 @@ func (s *sdk) memberListProperties() []*sdkMemberListProperty { return s.dynamicSdkMemberTypes.memberListProperties } +func (s *sdk) memberListProperty(memberType android.SdkMemberType) *sdkMemberListProperty { + return s.dynamicSdkMemberTypes.memberTypeToProperty[memberType] +} + func (s *sdk) snapshot() bool { return s.properties.Snapshot } diff --git a/sdk/update.go b/sdk/update.go index 43ec92662..3668b461f 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -131,7 +131,7 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) { s.multilibUsages = s.multilibUsages.addArchType(child.Target().Arch.ArchType) export := memberTag.ExportMember() - s.memberVariantDeps = append(s.memberVariantDeps, sdkMemberVariantDep{memberType, child.(android.SdkAware), export}) + s.memberVariantDeps = append(s.memberVariantDeps, sdkMemberVariantDep{s, memberType, child.(android.SdkAware), export}) // If the member type supports transitive sdk members then recurse down into // its dependencies, otherwise exit traversal. @@ -368,7 +368,7 @@ func (s *sdk) addSnapshotModule(ctx android.ModuleContext, builder *snapshotBuil addHostDeviceSupportedProperties(s.ModuleBase.DeviceSupported(), s.ModuleBase.HostSupported(), snapshotModule) - combinedPropertiesList := s.collateSnapshotModuleInfo(sdkVariants) + combinedPropertiesList := s.collateSnapshotModuleInfo(ctx, sdkVariants, memberVariantDeps) commonCombinedProperties := s.optimizeSnapshotModuleProperties(ctx, combinedPropertiesList) s.addSnapshotPropertiesToPropertySet(builder, snapshotModule, commonCombinedProperties) @@ -476,20 +476,44 @@ type combinedSnapshotModuleProperties struct { } // collateSnapshotModuleInfo collates all the snapshot module info from supplied sdk variants. -func (s *sdk) collateSnapshotModuleInfo(sdkVariants []*sdk) []*combinedSnapshotModuleProperties { +func (s *sdk) collateSnapshotModuleInfo(ctx android.BaseModuleContext, sdkVariants []*sdk, memberVariantDeps []sdkMemberVariantDep) []*combinedSnapshotModuleProperties { + sdkVariantToCombinedProperties := map[*sdk]*combinedSnapshotModuleProperties{} var list []*combinedSnapshotModuleProperties for _, sdkVariant := range sdkVariants { staticProperties := &snapshotModuleStaticProperties{ Compile_multilib: sdkVariant.multilibUsages.String(), } - dynamicProperties := sdkVariant.dynamicMemberTypeListProperties + dynamicProperties := s.dynamicSdkMemberTypes.createMemberListProperties() - list = append(list, &combinedSnapshotModuleProperties{ + combinedProperties := &combinedSnapshotModuleProperties{ sdkVariant: sdkVariant, staticProperties: staticProperties, dynamicProperties: dynamicProperties, - }) + } + sdkVariantToCombinedProperties[sdkVariant] = combinedProperties + + list = append(list, combinedProperties) } + + for _, memberVariantDep := range memberVariantDeps { + // If the member dependency is internal then do not add the dependency to the snapshot member + // list properties. + if !memberVariantDep.export { + continue + } + + combined := sdkVariantToCombinedProperties[memberVariantDep.sdkVariant] + memberTypeProperty := s.memberListProperty(memberVariantDep.memberType) + memberName := ctx.OtherModuleName(memberVariantDep.variant) + + // Append the member to the appropriate list, if it is not already present in the list. + memberList := memberTypeProperty.getter(combined.dynamicProperties) + if !android.InList(memberName, memberList) { + memberList = append(memberList, memberName) + } + memberTypeProperty.setter(combined.dynamicProperties, memberList) + } + return list } @@ -943,6 +967,8 @@ func addSdkMemberPropertiesToSet(ctx *memberContext, memberProperties android.Sd // sdkMemberVariantDep represents a dependency from an sdk variant onto a member variant. type sdkMemberVariantDep struct { + // The sdk variant that depends (possibly indirectly) on the member variant. + sdkVariant *sdk memberType android.SdkMemberType variant android.SdkAware export bool