Loading android/sdk.go +75 −5 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ package android import ( "sort" "strings" "github.com/google/blueprint" Loading Loading @@ -218,18 +219,24 @@ type SdkMember interface { // The basic implementation should look something like this, where ModuleType is // the name of the module type being supported. // // var ModuleTypeSdkMemberType = newModuleTypeSdkMemberType() // // func newModuleTypeSdkMemberType() android.SdkMemberType { // return &moduleTypeSdkMemberType{} // type moduleTypeSdkMemberType struct { // android.SdkMemberTypeBase // } // // type moduleTypeSdkMemberType struct { // func init() { // android.RegisterSdkMemberType(&moduleTypeSdkMemberType{ // SdkMemberTypeBase: android.SdkMemberTypeBase{ // PropertyName: "module_types", // }, // } // } // // ...methods... // type SdkMemberType interface { // The name of the member type property on an sdk module. SdkPropertyName() string // Add dependencies from the SDK module to all the variants the member // contributes to the SDK. The exact set of variants required is determined // by the SDK and its properties. The dependencies must be added with the Loading @@ -254,3 +261,66 @@ type SdkMemberType interface { // IsInstance(Module) method returned true. BuildSnapshot(sdkModuleContext ModuleContext, builder SnapshotBuilder, member SdkMember) } type SdkMemberTypeBase struct { PropertyName string } func (b *SdkMemberTypeBase) SdkPropertyName() string { return b.PropertyName } // Encapsulates the information about registered SdkMemberTypes. type SdkMemberTypesRegistry struct { // The list of types sorted by property name. list []SdkMemberType // The key that uniquely identifies this registry instance. key OnceKey } func (r *SdkMemberTypesRegistry) RegisteredTypes() []SdkMemberType { return r.list } func (r *SdkMemberTypesRegistry) UniqueOnceKey() OnceKey { // Use the pointer to the registry as the unique key. return NewCustomOnceKey(r) } // The set of registered SdkMemberTypes. var SdkMemberTypes = &SdkMemberTypesRegistry{} // Register an SdkMemberType object to allow them to be used in the sdk and sdk_snapshot module // types. func RegisterSdkMemberType(memberType SdkMemberType) { oldList := SdkMemberTypes.list // Copy the slice just in case this is being read while being modified, e.g. when testing. list := make([]SdkMemberType, 0, len(oldList)+1) list = append(list, oldList...) list = append(list, memberType) // Sort the member types by their property name to ensure that registry order has no effect // on behavior. sort.Slice(list, func(i1, i2 int) bool { t1 := list[i1] t2 := list[i2] return t1.SdkPropertyName() < t2.SdkPropertyName() }) // Generate a key that identifies the slice of SdkMemberTypes by joining the property names // from all the SdkMemberType . var properties []string for _, t := range list { properties = append(properties, t.SdkPropertyName()) } key := NewOnceKey(strings.Join(properties, "|")) // Create a new registry so the pointer uniquely identifies the set of registered types. SdkMemberTypes = &SdkMemberTypesRegistry{ list: list, key: key, } } cc/library_sdk_member.go +19 −8 Original line number Diff line number Diff line Loading @@ -24,17 +24,28 @@ import ( // This file contains support for using cc library modules within an sdk. var SharedLibrarySdkMemberType = &librarySdkMemberType{ func init() { // Register sdk member types. android.RegisterSdkMemberType(&librarySdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "native_shared_libs", }, prebuiltModuleType: "cc_prebuilt_library_shared", linkTypes: []string{"shared"}, } }) var StaticLibrarySdkMemberType = &librarySdkMemberType{ android.RegisterSdkMemberType(&librarySdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "native_static_libs", }, prebuiltModuleType: "cc_prebuilt_library_static", linkTypes: []string{"static"}, }) } type librarySdkMemberType struct { android.SdkMemberTypeBase prebuiltModuleType string // The set of link types supported, set of "static", "shared". Loading java/droiddoc.go +8 −2 Original line number Diff line number Diff line Loading @@ -40,6 +40,13 @@ func init() { android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory) android.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory) // Register sdk member type. android.RegisterSdkMemberType(&droidStubsSdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "stubs_sources", }, }) } var ( Loading Loading @@ -1974,9 +1981,8 @@ func PrebuiltStubsSourcesFactory() android.Module { return module } var DroidStubsSdkMemberType = &droidStubsSdkMemberType{} type droidStubsSdkMemberType struct { android.SdkMemberTypeBase } func (mt *droidStubsSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { Loading java/java.go +18 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,23 @@ func init() { android.RegisterSingletonType("logtags", LogtagsSingleton) android.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) // Register sdk member types. android.RegisterSdkMemberType(&headerLibrarySdkMemberType{ librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_header_libs", }, }, }) android.RegisterSdkMemberType(&implLibrarySdkMemberType{ librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_libs", }, }, }) } func (j *Module) checkSdkVersion(ctx android.ModuleContext) { Loading Loading @@ -1721,6 +1738,7 @@ func (j *Library) sdkSnapshotFilePathForJar() string { } type librarySdkMemberType struct { android.SdkMemberTypeBase } func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { Loading Loading @@ -1764,8 +1782,6 @@ func (mt *librarySdkMemberType) buildSnapshot( module.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) } var HeaderLibrarySdkMemberType = &headerLibrarySdkMemberType{} type headerLibrarySdkMemberType struct { librarySdkMemberType } Loading @@ -1781,8 +1797,6 @@ func (mt *headerLibrarySdkMemberType) BuildSnapshot(sdkModuleContext android.Mod }) } var ImplLibrarySdkMemberType = &implLibrarySdkMemberType{} type implLibrarySdkMemberType struct { librarySdkMemberType } Loading sdk/sdk.go +121 −74 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package sdk import ( "fmt" "io" "reflect" "strconv" "github.com/google/blueprint" Loading @@ -26,8 +27,6 @@ import ( // This package doesn't depend on the apex package, but import it to make its mutators to be // registered before mutators in this package. See RegisterPostDepsMutators for more details. _ "android/soong/apex" "android/soong/cc" "android/soong/java" ) func init() { Loading @@ -38,20 +37,19 @@ func init() { android.RegisterModuleType("sdk_snapshot", SnapshotModuleFactory) android.PreDepsMutators(RegisterPreDepsMutators) android.PostDepsMutators(RegisterPostDepsMutators) // Populate the dependency tags for each member list property. This needs to // be done here to break an initialization cycle. for _, memberListProperty := range sdkMemberListProperties { memberListProperty.dependencyTag = &sdkMemberDependencyTag{ memberListProperty: memberListProperty, } } } type sdk struct { android.ModuleBase android.DefaultableModuleBase // The dynamically generated information about the registered SdkMemberType dynamicSdkMemberTypes *dynamicSdkMemberTypes // The dynamically created instance of the properties struct containing the sdk member // list properties, e.g. java_libs. dynamicMemberTypeListProperties interface{} properties sdkProperties snapshotFile android.OptionalPath Loading @@ -61,92 +59,141 @@ type sdk struct { } type sdkProperties struct { // For module types from the cc package // The list of shared native libraries in this SDK Native_shared_libs []string // The list of static native libraries in this SDK Native_static_libs []string // For module types from the java package // The list of java header libraries in this SDK // // This should be used for java libraries that are provided separately at runtime, // e.g. through an APEX. Java_header_libs []string // The list of java implementation libraries in this SDK Java_libs []string // The list of stub sources in this SDK Stubs_sources []string Snapshot bool `blueprint:"mutated"` } type sdkMemberDependencyTag struct { blueprint.BaseDependencyTag memberListProperty *sdkMemberListProperty memberType android.SdkMemberType } // Contains information about the sdk properties that list sdk members, e.g. // Java_header_libs. type sdkMemberListProperty struct { // the name of the property as used in a .bp file name string // getter for the list of member names getter func(properties *sdkProperties) []string getter func(properties interface{}) []string // the type of member referenced in the list memberType android.SdkMemberType // the dependency tag used for items in this list. // the dependency tag used for items in this list that can be used to determine the memberType // for a resolved dependency. dependencyTag *sdkMemberDependencyTag } // Information about how to handle each member list property. func (p *sdkMemberListProperty) propertyName() string { return p.memberType.SdkPropertyName() } // Cache of dynamically generated dynamicSdkMemberTypes objects. The key is the pointer // to a slice of SdkMemberType instances held in android.SdkMemberTypes. var dynamicSdkMemberTypesMap android.OncePer // A dynamically generated set of member list properties and associated structure type. type dynamicSdkMemberTypes struct { // The dynamically generated structure type. // // It is organized first by package and then by name within the package. // Packages are in alphabetical order and properties are in alphabetical order // within each package. var sdkMemberListProperties = []*sdkMemberListProperty{ // Members from cc package. { name: "native_shared_libs", getter: func(properties *sdkProperties) []string { return properties.Native_shared_libs }, memberType: cc.SharedLibrarySdkMemberType, }, { name: "native_static_libs", getter: func(properties *sdkProperties) []string { return properties.Native_static_libs }, memberType: cc.StaticLibrarySdkMemberType, }, // Members from java package. { name: "java_header_libs", getter: func(properties *sdkProperties) []string { return properties.Java_header_libs }, memberType: java.HeaderLibrarySdkMemberType, }, { name: "java_libs", getter: func(properties *sdkProperties) []string { return properties.Java_libs }, memberType: java.ImplLibrarySdkMemberType, // Contains one []string exported field for each android.SdkMemberTypes. The name of the field // is the exported form of the value returned by SdkMemberType.SdkPropertyName(). propertiesStructType reflect.Type // Information about each of the member type specific list properties. memberListProperties []*sdkMemberListProperty } func (d *dynamicSdkMemberTypes) createMemberListProperties() interface{} { return reflect.New(d.propertiesStructType).Interface() } func getDynamicSdkMemberTypes(registry *android.SdkMemberTypesRegistry) *dynamicSdkMemberTypes { // Get a key that uniquely identifies the registry contents. key := registry.UniqueOnceKey() // Get the registered types. registeredTypes := registry.RegisteredTypes() // Get the cached value, creating new instance if necessary. return dynamicSdkMemberTypesMap.Once(key, func() interface{} { return createDynamicSdkMemberTypes(registeredTypes) }).(*dynamicSdkMemberTypes) } // Create the dynamicSdkMemberTypes from the list of registered member types. // // A struct is created which contains one exported field per member type corresponding to // the SdkMemberType.SdkPropertyName() value. // // A list of sdkMemberListProperty instances is created, one per member type that provides: // * a reference to the member type. // * a getter for the corresponding field in the properties struct. // * a dependency tag that identifies the member type of a resolved dependency. // func createDynamicSdkMemberTypes(sdkMemberTypes []android.SdkMemberType) *dynamicSdkMemberTypes { var listProperties []*sdkMemberListProperty var fields []reflect.StructField // Iterate over the member types creating StructField and sdkMemberListProperty objects. for f, memberType := range sdkMemberTypes { p := memberType.SdkPropertyName() // Create a dynamic exported field for the member type's property. fields = append(fields, reflect.StructField{ Name: proptools.FieldNameForProperty(p), Type: reflect.TypeOf([]string{}), }) // Copy the field index for use in the getter func as using the loop variable directly will // cause all funcs to use the last value. fieldIndex := f // Create an sdkMemberListProperty for the member type. memberListProperty := &sdkMemberListProperty{ getter: func(properties interface{}) []string { // The properties is expected to be of the following form (where // <Module_types> is the name of an SdkMemberType.SdkPropertyName(). // properties *struct {<Module_types> []string, ....} // // Although it accesses the field by index the following reflection code is equivalent to: // *properties.<Module_types> // list := reflect.ValueOf(properties).Elem().Field(fieldIndex).Interface().([]string) return list }, { name: "stubs_sources", getter: func(properties *sdkProperties) []string { return properties.Stubs_sources }, memberType: java.DroidStubsSdkMemberType, memberType: memberType, dependencyTag: &sdkMemberDependencyTag{ memberType: memberType, }, } listProperties = append(listProperties, memberListProperty) } // Create a dynamic struct from the collated fields. propertiesStructType := reflect.StructOf(fields) return &dynamicSdkMemberTypes{ memberListProperties: listProperties, propertiesStructType: propertiesStructType, } } // sdk defines an SDK which is a logical group of modules (e.g. native libs, headers, java libs, etc.) // which Mainline modules like APEX can choose to build with. func ModuleFactory() android.Module { s := &sdk{} s.AddProperties(&s.properties) // Get the dynamic sdk member type data for the currently registered sdk member types. s.dynamicSdkMemberTypes = getDynamicSdkMemberTypes(android.SdkMemberTypes) // Create an instance of the dynamically created struct that contains all the // properties for the member type specific list properties. s.dynamicMemberTypeListProperties = s.dynamicSdkMemberTypes.createMemberListProperties() s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties) android.InitAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(s) android.AddLoadHook(s, func(ctx android.LoadHookContext) { Loading Loading @@ -235,9 +282,9 @@ type sdkMemberVesionedDepTag struct { // Step 1: create dependencies from an SDK module to its members. func memberMutator(mctx android.BottomUpMutatorContext) { if m, ok := mctx.Module().(*sdk); ok { for _, memberListProperty := range sdkMemberListProperties { names := memberListProperty.getter(&m.properties) if s, ok := mctx.Module().(*sdk); ok { for _, memberListProperty := range s.dynamicSdkMemberTypes.memberListProperties { names := memberListProperty.getter(s.dynamicMemberTypeListProperties) tag := memberListProperty.dependencyTag memberListProperty.memberType.AddDependencies(mctx, tag, names) } Loading Loading
android/sdk.go +75 −5 Original line number Diff line number Diff line Loading @@ -15,6 +15,7 @@ package android import ( "sort" "strings" "github.com/google/blueprint" Loading Loading @@ -218,18 +219,24 @@ type SdkMember interface { // The basic implementation should look something like this, where ModuleType is // the name of the module type being supported. // // var ModuleTypeSdkMemberType = newModuleTypeSdkMemberType() // // func newModuleTypeSdkMemberType() android.SdkMemberType { // return &moduleTypeSdkMemberType{} // type moduleTypeSdkMemberType struct { // android.SdkMemberTypeBase // } // // type moduleTypeSdkMemberType struct { // func init() { // android.RegisterSdkMemberType(&moduleTypeSdkMemberType{ // SdkMemberTypeBase: android.SdkMemberTypeBase{ // PropertyName: "module_types", // }, // } // } // // ...methods... // type SdkMemberType interface { // The name of the member type property on an sdk module. SdkPropertyName() string // Add dependencies from the SDK module to all the variants the member // contributes to the SDK. The exact set of variants required is determined // by the SDK and its properties. The dependencies must be added with the Loading @@ -254,3 +261,66 @@ type SdkMemberType interface { // IsInstance(Module) method returned true. BuildSnapshot(sdkModuleContext ModuleContext, builder SnapshotBuilder, member SdkMember) } type SdkMemberTypeBase struct { PropertyName string } func (b *SdkMemberTypeBase) SdkPropertyName() string { return b.PropertyName } // Encapsulates the information about registered SdkMemberTypes. type SdkMemberTypesRegistry struct { // The list of types sorted by property name. list []SdkMemberType // The key that uniquely identifies this registry instance. key OnceKey } func (r *SdkMemberTypesRegistry) RegisteredTypes() []SdkMemberType { return r.list } func (r *SdkMemberTypesRegistry) UniqueOnceKey() OnceKey { // Use the pointer to the registry as the unique key. return NewCustomOnceKey(r) } // The set of registered SdkMemberTypes. var SdkMemberTypes = &SdkMemberTypesRegistry{} // Register an SdkMemberType object to allow them to be used in the sdk and sdk_snapshot module // types. func RegisterSdkMemberType(memberType SdkMemberType) { oldList := SdkMemberTypes.list // Copy the slice just in case this is being read while being modified, e.g. when testing. list := make([]SdkMemberType, 0, len(oldList)+1) list = append(list, oldList...) list = append(list, memberType) // Sort the member types by their property name to ensure that registry order has no effect // on behavior. sort.Slice(list, func(i1, i2 int) bool { t1 := list[i1] t2 := list[i2] return t1.SdkPropertyName() < t2.SdkPropertyName() }) // Generate a key that identifies the slice of SdkMemberTypes by joining the property names // from all the SdkMemberType . var properties []string for _, t := range list { properties = append(properties, t.SdkPropertyName()) } key := NewOnceKey(strings.Join(properties, "|")) // Create a new registry so the pointer uniquely identifies the set of registered types. SdkMemberTypes = &SdkMemberTypesRegistry{ list: list, key: key, } }
cc/library_sdk_member.go +19 −8 Original line number Diff line number Diff line Loading @@ -24,17 +24,28 @@ import ( // This file contains support for using cc library modules within an sdk. var SharedLibrarySdkMemberType = &librarySdkMemberType{ func init() { // Register sdk member types. android.RegisterSdkMemberType(&librarySdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "native_shared_libs", }, prebuiltModuleType: "cc_prebuilt_library_shared", linkTypes: []string{"shared"}, } }) var StaticLibrarySdkMemberType = &librarySdkMemberType{ android.RegisterSdkMemberType(&librarySdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "native_static_libs", }, prebuiltModuleType: "cc_prebuilt_library_static", linkTypes: []string{"static"}, }) } type librarySdkMemberType struct { android.SdkMemberTypeBase prebuiltModuleType string // The set of link types supported, set of "static", "shared". Loading
java/droiddoc.go +8 −2 Original line number Diff line number Diff line Loading @@ -40,6 +40,13 @@ func init() { android.RegisterModuleType("droidstubs_host", DroidstubsHostFactory) android.RegisterModuleType("prebuilt_stubs_sources", PrebuiltStubsSourcesFactory) // Register sdk member type. android.RegisterSdkMemberType(&droidStubsSdkMemberType{ SdkMemberTypeBase: android.SdkMemberTypeBase{ PropertyName: "stubs_sources", }, }) } var ( Loading Loading @@ -1974,9 +1981,8 @@ func PrebuiltStubsSourcesFactory() android.Module { return module } var DroidStubsSdkMemberType = &droidStubsSdkMemberType{} type droidStubsSdkMemberType struct { android.SdkMemberTypeBase } func (mt *droidStubsSdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { Loading
java/java.go +18 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,23 @@ func init() { android.RegisterSingletonType("logtags", LogtagsSingleton) android.RegisterSingletonType("kythe_java_extract", kytheExtractJavaFactory) // Register sdk member types. android.RegisterSdkMemberType(&headerLibrarySdkMemberType{ librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_header_libs", }, }, }) android.RegisterSdkMemberType(&implLibrarySdkMemberType{ librarySdkMemberType{ android.SdkMemberTypeBase{ PropertyName: "java_libs", }, }, }) } func (j *Module) checkSdkVersion(ctx android.ModuleContext) { Loading Loading @@ -1721,6 +1738,7 @@ func (j *Library) sdkSnapshotFilePathForJar() string { } type librarySdkMemberType struct { android.SdkMemberTypeBase } func (mt *librarySdkMemberType) AddDependencies(mctx android.BottomUpMutatorContext, dependencyTag blueprint.DependencyTag, names []string) { Loading Loading @@ -1764,8 +1782,6 @@ func (mt *librarySdkMemberType) buildSnapshot( module.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) } var HeaderLibrarySdkMemberType = &headerLibrarySdkMemberType{} type headerLibrarySdkMemberType struct { librarySdkMemberType } Loading @@ -1781,8 +1797,6 @@ func (mt *headerLibrarySdkMemberType) BuildSnapshot(sdkModuleContext android.Mod }) } var ImplLibrarySdkMemberType = &implLibrarySdkMemberType{} type implLibrarySdkMemberType struct { librarySdkMemberType } Loading
sdk/sdk.go +121 −74 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package sdk import ( "fmt" "io" "reflect" "strconv" "github.com/google/blueprint" Loading @@ -26,8 +27,6 @@ import ( // This package doesn't depend on the apex package, but import it to make its mutators to be // registered before mutators in this package. See RegisterPostDepsMutators for more details. _ "android/soong/apex" "android/soong/cc" "android/soong/java" ) func init() { Loading @@ -38,20 +37,19 @@ func init() { android.RegisterModuleType("sdk_snapshot", SnapshotModuleFactory) android.PreDepsMutators(RegisterPreDepsMutators) android.PostDepsMutators(RegisterPostDepsMutators) // Populate the dependency tags for each member list property. This needs to // be done here to break an initialization cycle. for _, memberListProperty := range sdkMemberListProperties { memberListProperty.dependencyTag = &sdkMemberDependencyTag{ memberListProperty: memberListProperty, } } } type sdk struct { android.ModuleBase android.DefaultableModuleBase // The dynamically generated information about the registered SdkMemberType dynamicSdkMemberTypes *dynamicSdkMemberTypes // The dynamically created instance of the properties struct containing the sdk member // list properties, e.g. java_libs. dynamicMemberTypeListProperties interface{} properties sdkProperties snapshotFile android.OptionalPath Loading @@ -61,92 +59,141 @@ type sdk struct { } type sdkProperties struct { // For module types from the cc package // The list of shared native libraries in this SDK Native_shared_libs []string // The list of static native libraries in this SDK Native_static_libs []string // For module types from the java package // The list of java header libraries in this SDK // // This should be used for java libraries that are provided separately at runtime, // e.g. through an APEX. Java_header_libs []string // The list of java implementation libraries in this SDK Java_libs []string // The list of stub sources in this SDK Stubs_sources []string Snapshot bool `blueprint:"mutated"` } type sdkMemberDependencyTag struct { blueprint.BaseDependencyTag memberListProperty *sdkMemberListProperty memberType android.SdkMemberType } // Contains information about the sdk properties that list sdk members, e.g. // Java_header_libs. type sdkMemberListProperty struct { // the name of the property as used in a .bp file name string // getter for the list of member names getter func(properties *sdkProperties) []string getter func(properties interface{}) []string // the type of member referenced in the list memberType android.SdkMemberType // the dependency tag used for items in this list. // the dependency tag used for items in this list that can be used to determine the memberType // for a resolved dependency. dependencyTag *sdkMemberDependencyTag } // Information about how to handle each member list property. func (p *sdkMemberListProperty) propertyName() string { return p.memberType.SdkPropertyName() } // Cache of dynamically generated dynamicSdkMemberTypes objects. The key is the pointer // to a slice of SdkMemberType instances held in android.SdkMemberTypes. var dynamicSdkMemberTypesMap android.OncePer // A dynamically generated set of member list properties and associated structure type. type dynamicSdkMemberTypes struct { // The dynamically generated structure type. // // It is organized first by package and then by name within the package. // Packages are in alphabetical order and properties are in alphabetical order // within each package. var sdkMemberListProperties = []*sdkMemberListProperty{ // Members from cc package. { name: "native_shared_libs", getter: func(properties *sdkProperties) []string { return properties.Native_shared_libs }, memberType: cc.SharedLibrarySdkMemberType, }, { name: "native_static_libs", getter: func(properties *sdkProperties) []string { return properties.Native_static_libs }, memberType: cc.StaticLibrarySdkMemberType, }, // Members from java package. { name: "java_header_libs", getter: func(properties *sdkProperties) []string { return properties.Java_header_libs }, memberType: java.HeaderLibrarySdkMemberType, }, { name: "java_libs", getter: func(properties *sdkProperties) []string { return properties.Java_libs }, memberType: java.ImplLibrarySdkMemberType, // Contains one []string exported field for each android.SdkMemberTypes. The name of the field // is the exported form of the value returned by SdkMemberType.SdkPropertyName(). propertiesStructType reflect.Type // Information about each of the member type specific list properties. memberListProperties []*sdkMemberListProperty } func (d *dynamicSdkMemberTypes) createMemberListProperties() interface{} { return reflect.New(d.propertiesStructType).Interface() } func getDynamicSdkMemberTypes(registry *android.SdkMemberTypesRegistry) *dynamicSdkMemberTypes { // Get a key that uniquely identifies the registry contents. key := registry.UniqueOnceKey() // Get the registered types. registeredTypes := registry.RegisteredTypes() // Get the cached value, creating new instance if necessary. return dynamicSdkMemberTypesMap.Once(key, func() interface{} { return createDynamicSdkMemberTypes(registeredTypes) }).(*dynamicSdkMemberTypes) } // Create the dynamicSdkMemberTypes from the list of registered member types. // // A struct is created which contains one exported field per member type corresponding to // the SdkMemberType.SdkPropertyName() value. // // A list of sdkMemberListProperty instances is created, one per member type that provides: // * a reference to the member type. // * a getter for the corresponding field in the properties struct. // * a dependency tag that identifies the member type of a resolved dependency. // func createDynamicSdkMemberTypes(sdkMemberTypes []android.SdkMemberType) *dynamicSdkMemberTypes { var listProperties []*sdkMemberListProperty var fields []reflect.StructField // Iterate over the member types creating StructField and sdkMemberListProperty objects. for f, memberType := range sdkMemberTypes { p := memberType.SdkPropertyName() // Create a dynamic exported field for the member type's property. fields = append(fields, reflect.StructField{ Name: proptools.FieldNameForProperty(p), Type: reflect.TypeOf([]string{}), }) // Copy the field index for use in the getter func as using the loop variable directly will // cause all funcs to use the last value. fieldIndex := f // Create an sdkMemberListProperty for the member type. memberListProperty := &sdkMemberListProperty{ getter: func(properties interface{}) []string { // The properties is expected to be of the following form (where // <Module_types> is the name of an SdkMemberType.SdkPropertyName(). // properties *struct {<Module_types> []string, ....} // // Although it accesses the field by index the following reflection code is equivalent to: // *properties.<Module_types> // list := reflect.ValueOf(properties).Elem().Field(fieldIndex).Interface().([]string) return list }, { name: "stubs_sources", getter: func(properties *sdkProperties) []string { return properties.Stubs_sources }, memberType: java.DroidStubsSdkMemberType, memberType: memberType, dependencyTag: &sdkMemberDependencyTag{ memberType: memberType, }, } listProperties = append(listProperties, memberListProperty) } // Create a dynamic struct from the collated fields. propertiesStructType := reflect.StructOf(fields) return &dynamicSdkMemberTypes{ memberListProperties: listProperties, propertiesStructType: propertiesStructType, } } // sdk defines an SDK which is a logical group of modules (e.g. native libs, headers, java libs, etc.) // which Mainline modules like APEX can choose to build with. func ModuleFactory() android.Module { s := &sdk{} s.AddProperties(&s.properties) // Get the dynamic sdk member type data for the currently registered sdk member types. s.dynamicSdkMemberTypes = getDynamicSdkMemberTypes(android.SdkMemberTypes) // Create an instance of the dynamically created struct that contains all the // properties for the member type specific list properties. s.dynamicMemberTypeListProperties = s.dynamicSdkMemberTypes.createMemberListProperties() s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties) android.InitAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(s) android.AddLoadHook(s, func(ctx android.LoadHookContext) { Loading Loading @@ -235,9 +282,9 @@ type sdkMemberVesionedDepTag struct { // Step 1: create dependencies from an SDK module to its members. func memberMutator(mctx android.BottomUpMutatorContext) { if m, ok := mctx.Module().(*sdk); ok { for _, memberListProperty := range sdkMemberListProperties { names := memberListProperty.getter(&m.properties) if s, ok := mctx.Module().(*sdk); ok { for _, memberListProperty := range s.dynamicSdkMemberTypes.memberListProperties { names := memberListProperty.getter(s.dynamicMemberTypeListProperties) tag := memberListProperty.dependencyTag memberListProperty.memberType.AddDependencies(mctx, tag, names) } Loading