Loading android/arch.go +170 −150 Original line number Diff line number Diff line Loading @@ -1055,24 +1055,28 @@ func mergePropertyStruct(ctx ArchVariantContext, dst interface{}, srcValue refle // Returns the immediate child of the input property struct that corresponds to // the sub-property "field". func getChildPropertyStruct(ctx ArchVariantContext, src reflect.Value, field, userFriendlyField string) reflect.Value { src reflect.Value, field, userFriendlyField string) (reflect.Value, bool) { // Step into non-nil pointers to structs in the src value. if src.Kind() == reflect.Ptr { if src.IsNil() { return src return reflect.Value{}, false } src = src.Elem() } // Find the requested field in the src struct. src = src.FieldByName(proptools.FieldNameForProperty(field)) if !src.IsValid() { child := src.FieldByName(proptools.FieldNameForProperty(field)) if !child.IsValid() { ctx.ModuleErrorf("field %q does not exist", userFriendlyField) return src return reflect.Value{}, false } return src if child.IsZero() { return reflect.Value{}, false } return child, true } // Squash the appropriate OS-specific property structs into the matching top level property structs Loading @@ -1099,9 +1103,10 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if os.Class == Host { field := "Host" prefix := "target.host" hostProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if hostProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, hostProperties) } } // Handle target OS generalities of the form: // target: { Loading @@ -1112,16 +1117,18 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if os.Linux() { field := "Linux" prefix := "target.linux" linuxProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, linuxProperties) } } if os.Bionic() { field := "Bionic" prefix := "target.bionic" bionicProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, bionicProperties) } } // Handle target OS properties in the form: // target: { Loading @@ -1137,15 +1144,17 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { // }, field := os.Field prefix := "target." + os.Name osProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if osProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, osProperties) } if os.Class == Host && os != Windows { field := "Not_windows" prefix := "target.not_windows" notWindowsProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if notWindowsProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, notWindowsProperties) } } // Handle 64-bit device properties in the form: // target { Loading @@ -1164,18 +1173,20 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if ctx.Config().Android64() { field := "Android64" prefix := "target.android64" android64Properties := getChildPropertyStruct(ctx, targetProp, field, prefix) if android64Properties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, android64Properties) } } else { field := "Android32" prefix := "target.android32" android32Properties := getChildPropertyStruct(ctx, targetProp, field, prefix) if android32Properties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, android32Properties) } } } } } } // Returns the struct containing the properties specific to the given // architecture type. These look like this in Blueprint files: Loading @@ -1186,12 +1197,11 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { // }, // This struct will also contain sub-structs containing to the architecture/CPU // variants and features that themselves contain properties specific to those. func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) reflect.Value { func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) { archPropValues := reflect.ValueOf(archProperties).Elem() archProp := archPropValues.FieldByName("Arch").Elem() prefix := "arch." + archType.Name archStruct := getChildPropertyStruct(ctx, archProp, archType.Name, prefix) return archStruct return getChildPropertyStruct(ctx, archProp, archType.Name, prefix) } // Returns the struct containing the properties specific to a given multilib Loading @@ -1201,11 +1211,10 @@ func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archT // key: value, // }, // }, func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) reflect.Value { func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) { archPropValues := reflect.ValueOf(archProperties).Elem() multilibProp := archPropValues.FieldByName("Multilib").Elem() multilibProperties := getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib) return multilibProperties return getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib) } // Returns the structs corresponding to the properties specific to the given Loading @@ -1219,7 +1228,8 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch archType := arch.ArchType if arch.ArchType != Common { archStruct := getArchTypeStruct(ctx, archProperties, arch.ArchType) archStruct, ok := getArchTypeStruct(ctx, archProperties, arch.ArchType) if ok { result = append(result, archStruct) // Handle arch-variant-specific properties in the form: Loading @@ -1233,9 +1243,10 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch v := variantReplacer.Replace(arch.ArchVariant) if v != "" { prefix := "arch." + archType.Name + "." + v variantProperties := getChildPropertyStruct(ctx, archStruct, v, prefix) if variantProperties, ok := getChildPropertyStruct(ctx, archStruct, v, prefix); ok { result = append(result, variantProperties) } } // Handle cpu-variant-specific properties in the form: // arch: { Loading @@ -1249,10 +1260,11 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch c := variantReplacer.Replace(arch.CpuVariant) if c != "" { prefix := "arch." + archType.Name + "." + c cpuVariantProperties := getChildPropertyStruct(ctx, archStruct, c, prefix) if cpuVariantProperties, ok := getChildPropertyStruct(ctx, archStruct, c, prefix); ok { result = append(result, cpuVariantProperties) } } } // Handle arch-feature-specific properties in the form: // arch: { Loading @@ -1264,12 +1276,15 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch // }, for _, feature := range arch.ArchFeatures { prefix := "arch." + archType.Name + "." + feature featureProperties := getChildPropertyStruct(ctx, archStruct, feature, prefix) if featureProperties, ok := getChildPropertyStruct(ctx, archStruct, feature, prefix); ok { result = append(result, featureProperties) } } } multilibProperties := getMultilibStruct(ctx, archProperties, archType) if multilibProperties, ok := getMultilibStruct(ctx, archProperties, archType); ok { result = append(result, multilibProperties) } // Handle combined OS-feature and arch specific properties in the form: // target: { Loading @@ -1280,16 +1295,18 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch if os.Linux() { field := "Linux_" + arch.ArchType.Name userFriendlyField := "target.linux_" + arch.ArchType.Name linuxProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, linuxProperties) } } if os.Bionic() { field := "Bionic_" + archType.Name userFriendlyField := "target.bionic_" + archType.Name bionicProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, bionicProperties) } } // Handle combined OS and arch specific properties in the form: // target: { Loading @@ -1308,9 +1325,10 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch // }, field := os.Field + "_" + archType.Name userFriendlyField := "target." + os.Name + "_" + archType.Name osArchProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, osArchProperties) } } // Handle arm on x86 properties in the form: // target { Loading @@ -1326,23 +1344,26 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch hasArmAndroidArch(ctx.Config().Targets[Android])) { field := "Arm_on_x86" userFriendlyField := "target.arm_on_x86" armOnX86Properties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if armOnX86Properties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, armOnX86Properties) } } if arch.ArchType == X86_64 && (hasArmAbi(arch) || hasArmAndroidArch(ctx.Config().Targets[Android])) { field := "Arm_on_x86_64" userFriendlyField := "target.arm_on_x86_64" armOnX8664Properties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if armOnX8664Properties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, armOnX8664Properties) } } if os == Android && nativeBridgeEnabled { userFriendlyField := "Native_bridge" prefix := "target.native_bridge" nativeBridgeProperties := getChildPropertyStruct(ctx, targetProp, userFriendlyField, prefix) if nativeBridgeProperties, ok := getChildPropertyStruct(ctx, targetProp, userFriendlyField, prefix); ok { result = append(result, nativeBridgeProperties) } } } return result } Loading Loading @@ -1869,6 +1890,8 @@ type ArchVariantContext interface { // 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`. // // Implemented in a way very similar to GetTargetProperties(). func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet interface{}) map[ArchType]interface{} { // Return value of the arch types to the prop values for that arch. archToProp := map[ArchType]interface{}{} Loading Loading @@ -1903,9 +1926,14 @@ func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet inter // input one that contains the data specific to that arch. propertyStructs := make([]reflect.Value, 0) for _, archProperty := range archProperties { archTypeStruct := getArchTypeStruct(ctx, archProperty, arch) multilibStruct := getMultilibStruct(ctx, archProperty, arch) propertyStructs = append(propertyStructs, archTypeStruct, multilibStruct) archTypeStruct, ok := getArchTypeStruct(ctx, archProperty, arch) if ok { propertyStructs = append(propertyStructs, archTypeStruct) } multilibStruct, ok := getMultilibStruct(ctx, archProperty, arch) if ok { propertyStructs = append(propertyStructs, multilibStruct) } } // Create a new instance of the requested property set Loading @@ -1922,18 +1950,31 @@ func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet inter return archToProp } // Returns the struct containing the properties specific to the given // architecture type. These look like this in Blueprint files: // target: { // android: { // key: value, // }, // }, // This struct will also contain sub-structs containing to the architecture/CPU // variants and features that themselves contain properties specific to those. func getTargetStruct(ctx ArchVariantContext, archProperties interface{}, os OsType) (reflect.Value, bool) { archPropValues := reflect.ValueOf(archProperties).Elem() targetProp := archPropValues.FieldByName("Target").Elem() return getChildPropertyStruct(ctx, targetProp, os.Field, os.Field) } // GetTargetProperties returns a map of OS target (e.g. android, windows) to the // values of the properties of the 'dst' struct that are specific to that OS // target. // values of the properties of the 'propertySet' struct that are specific to // that OS target. // // 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 os-specific property value specified by the module if defined. // // While this looks similar to GetArchProperties, the internal representation of // the properties have a slightly different layout to warrant a standalone // lookup function. func (m *ModuleBase) GetTargetProperties(dst interface{}) map[OsType]interface{} { // Implemented in a way very similar to GetArchProperties(). func (m *ModuleBase) GetTargetProperties(ctx ArchVariantContext, propertySet interface{}) map[OsType]interface{} { // Return value of the arch types to the prop values for that arch. osToProp := map[OsType]interface{}{} Loading @@ -1942,69 +1983,48 @@ func (m *ModuleBase) GetTargetProperties(dst interface{}) map[OsType]interface{} return osToProp } // archProperties has the type of [][]interface{}. Looks complicated, so // let's explain this step by step. // // Loop over the outer index, which determines the property struct that // contains a matching set of properties in dst that we're interested in. // For example, BaseCompilerProperties or BaseLinkerProperties. for i := range m.archProperties { if m.archProperties[i] == nil { continue } // Iterate over the supported OS types for _, os := range osTypeList { // e.g android, linux_bionic field := os.Field // If it's not nil, loop over the inner index, which determines the arch variant // of the prop type. In an Android.bp file, this is like looping over: // // target: { android: { key: value, ... }, linux_bionic: { key: value, ... } } for _, archProperties := range m.archProperties[i] { archPropValues := reflect.ValueOf(archProperties).Elem() // This is the archPropRoot struct. Traverse into the Targetnested struct. src := archPropValues.FieldByName("Target").Elem() dstType := reflect.ValueOf(propertySet).Type() var archProperties []interface{} // Step into non-nil pointers to structs in the src value. if src.Kind() == reflect.Ptr { if src.IsNil() { continue // First find the property set in the module that corresponds to the requested // one. m.archProperties[i] corresponds to m.generalProperties[i]. for i, generalProp := range m.generalProperties { srcType := reflect.ValueOf(generalProp).Type() if srcType == dstType { archProperties = m.archProperties[i] break } src = src.Elem() } // Find the requested field (e.g. android, linux_bionic) in the src struct. src = src.FieldByName(field) // Validation steps. We want valid non-nil pointers to structs. if !src.IsValid() || src.IsNil() { continue if archProperties == nil { // This module does not have the property set requested return osToProp } if src.Kind() != reflect.Ptr || src.Elem().Kind() != reflect.Struct { for _, os := range osTypeList { if os == CommonOS { // It looks like this OS value is not used in Blueprint files continue } // Clone the destination prop, since we want a unique prop struct per arch. dstClone := reflect.New(reflect.ValueOf(dst).Elem().Type()).Interface() // Copy the located property struct into the cloned destination property struct. err := proptools.ExtendMatchingProperties([]interface{}{dstClone}, src.Interface(), nil, proptools.OrderReplace) if err != nil { // This is fine, it just means the src struct doesn't match. continue propertyStructs := make([]reflect.Value, 0) for _, archProperty := range archProperties { targetStruct, ok := getTargetStruct(ctx, archProperty, os) if ok { propertyStructs = append(propertyStructs, targetStruct) } } // Found the prop for the os, you have. osToProp[os] = dstClone // Create a new instance of the requested property set value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface() // Go to the next prop. break } // Merge all the structs together for _, propertyStruct := range propertyStructs { mergePropertyStruct(ctx, value, propertyStruct) } osToProp[os] = value } return osToProp } cc/bp2build.go +4 −4 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { var allDeps []string for _, p := range module.GetTargetProperties(&BaseLinkerProperties{}) { for _, p := range module.GetTargetProperties(ctx, &BaseLinkerProperties{}) { // arch specific linker props if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok { allDeps = append(allDeps, baseLinkerProps.Header_libs...) Loading Loading @@ -273,7 +273,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul srcs.SetValueForArch(bazel.CONDITIONS_DEFAULT, defaultsSrcs) // Handle OS specific props. for os, props := range module.GetTargetProperties(&BaseCompilerProperties{}) { for os, props := range module.GetTargetProperties(ctx, &BaseCompilerProperties{}) { if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { srcsList := parseSrcs(baseCompilerProps) // TODO(b/186153868): add support for os-specific srcs and exclude_srcs Loading Loading @@ -358,7 +358,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) } } for os, p := range module.GetTargetProperties(&BaseLinkerProperties{}) { for os, p := range module.GetTargetProperties(ctx, &BaseLinkerProperties{}) { if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok { libs := baseLinkerProps.Header_libs libs = append(libs, baseLinkerProps.Export_header_lib_headers...) Loading Loading @@ -434,7 +434,7 @@ func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Mo } } for os, props := range module.GetTargetProperties(&FlagExporterProperties{}) { for os, props := range module.GetTargetProperties(ctx, &FlagExporterProperties{}) { if flagExporterProperties, ok := props.(*FlagExporterProperties); ok { osIncludeDirs := flagExporterProperties.Export_system_include_dirs osIncludeDirs = append(osIncludeDirs, flagExporterProperties.Export_include_dirs...) Loading Loading
android/arch.go +170 −150 Original line number Diff line number Diff line Loading @@ -1055,24 +1055,28 @@ func mergePropertyStruct(ctx ArchVariantContext, dst interface{}, srcValue refle // Returns the immediate child of the input property struct that corresponds to // the sub-property "field". func getChildPropertyStruct(ctx ArchVariantContext, src reflect.Value, field, userFriendlyField string) reflect.Value { src reflect.Value, field, userFriendlyField string) (reflect.Value, bool) { // Step into non-nil pointers to structs in the src value. if src.Kind() == reflect.Ptr { if src.IsNil() { return src return reflect.Value{}, false } src = src.Elem() } // Find the requested field in the src struct. src = src.FieldByName(proptools.FieldNameForProperty(field)) if !src.IsValid() { child := src.FieldByName(proptools.FieldNameForProperty(field)) if !child.IsValid() { ctx.ModuleErrorf("field %q does not exist", userFriendlyField) return src return reflect.Value{}, false } return src if child.IsZero() { return reflect.Value{}, false } return child, true } // Squash the appropriate OS-specific property structs into the matching top level property structs Loading @@ -1099,9 +1103,10 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if os.Class == Host { field := "Host" prefix := "target.host" hostProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if hostProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, hostProperties) } } // Handle target OS generalities of the form: // target: { Loading @@ -1112,16 +1117,18 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if os.Linux() { field := "Linux" prefix := "target.linux" linuxProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, linuxProperties) } } if os.Bionic() { field := "Bionic" prefix := "target.bionic" bionicProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, bionicProperties) } } // Handle target OS properties in the form: // target: { Loading @@ -1137,15 +1144,17 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { // }, field := os.Field prefix := "target." + os.Name osProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if osProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, osProperties) } if os.Class == Host && os != Windows { field := "Not_windows" prefix := "target.not_windows" notWindowsProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) if notWindowsProperties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, notWindowsProperties) } } // Handle 64-bit device properties in the form: // target { Loading @@ -1164,18 +1173,20 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if ctx.Config().Android64() { field := "Android64" prefix := "target.android64" android64Properties := getChildPropertyStruct(ctx, targetProp, field, prefix) if android64Properties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, android64Properties) } } else { field := "Android32" prefix := "target.android32" android32Properties := getChildPropertyStruct(ctx, targetProp, field, prefix) if android32Properties, ok := getChildPropertyStruct(ctx, targetProp, field, prefix); ok { mergePropertyStruct(ctx, genProps, android32Properties) } } } } } } // Returns the struct containing the properties specific to the given // architecture type. These look like this in Blueprint files: Loading @@ -1186,12 +1197,11 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { // }, // This struct will also contain sub-structs containing to the architecture/CPU // variants and features that themselves contain properties specific to those. func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) reflect.Value { func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) { archPropValues := reflect.ValueOf(archProperties).Elem() archProp := archPropValues.FieldByName("Arch").Elem() prefix := "arch." + archType.Name archStruct := getChildPropertyStruct(ctx, archProp, archType.Name, prefix) return archStruct return getChildPropertyStruct(ctx, archProp, archType.Name, prefix) } // Returns the struct containing the properties specific to a given multilib Loading @@ -1201,11 +1211,10 @@ func getArchTypeStruct(ctx ArchVariantContext, archProperties interface{}, archT // key: value, // }, // }, func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) reflect.Value { func getMultilibStruct(ctx ArchVariantContext, archProperties interface{}, archType ArchType) (reflect.Value, bool) { archPropValues := reflect.ValueOf(archProperties).Elem() multilibProp := archPropValues.FieldByName("Multilib").Elem() multilibProperties := getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib) return multilibProperties return getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib) } // Returns the structs corresponding to the properties specific to the given Loading @@ -1219,7 +1228,8 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch archType := arch.ArchType if arch.ArchType != Common { archStruct := getArchTypeStruct(ctx, archProperties, arch.ArchType) archStruct, ok := getArchTypeStruct(ctx, archProperties, arch.ArchType) if ok { result = append(result, archStruct) // Handle arch-variant-specific properties in the form: Loading @@ -1233,9 +1243,10 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch v := variantReplacer.Replace(arch.ArchVariant) if v != "" { prefix := "arch." + archType.Name + "." + v variantProperties := getChildPropertyStruct(ctx, archStruct, v, prefix) if variantProperties, ok := getChildPropertyStruct(ctx, archStruct, v, prefix); ok { result = append(result, variantProperties) } } // Handle cpu-variant-specific properties in the form: // arch: { Loading @@ -1249,10 +1260,11 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch c := variantReplacer.Replace(arch.CpuVariant) if c != "" { prefix := "arch." + archType.Name + "." + c cpuVariantProperties := getChildPropertyStruct(ctx, archStruct, c, prefix) if cpuVariantProperties, ok := getChildPropertyStruct(ctx, archStruct, c, prefix); ok { result = append(result, cpuVariantProperties) } } } // Handle arch-feature-specific properties in the form: // arch: { Loading @@ -1264,12 +1276,15 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch // }, for _, feature := range arch.ArchFeatures { prefix := "arch." + archType.Name + "." + feature featureProperties := getChildPropertyStruct(ctx, archStruct, feature, prefix) if featureProperties, ok := getChildPropertyStruct(ctx, archStruct, feature, prefix); ok { result = append(result, featureProperties) } } } multilibProperties := getMultilibStruct(ctx, archProperties, archType) if multilibProperties, ok := getMultilibStruct(ctx, archProperties, archType); ok { result = append(result, multilibProperties) } // Handle combined OS-feature and arch specific properties in the form: // target: { Loading @@ -1280,16 +1295,18 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch if os.Linux() { field := "Linux_" + arch.ArchType.Name userFriendlyField := "target.linux_" + arch.ArchType.Name linuxProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if linuxProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, linuxProperties) } } if os.Bionic() { field := "Bionic_" + archType.Name userFriendlyField := "target.bionic_" + archType.Name bionicProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if bionicProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, bionicProperties) } } // Handle combined OS and arch specific properties in the form: // target: { Loading @@ -1308,9 +1325,10 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch // }, field := os.Field + "_" + archType.Name userFriendlyField := "target." + os.Name + "_" + archType.Name osArchProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if osArchProperties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, osArchProperties) } } // Handle arm on x86 properties in the form: // target { Loading @@ -1326,23 +1344,26 @@ func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch hasArmAndroidArch(ctx.Config().Targets[Android])) { field := "Arm_on_x86" userFriendlyField := "target.arm_on_x86" armOnX86Properties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if armOnX86Properties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, armOnX86Properties) } } if arch.ArchType == X86_64 && (hasArmAbi(arch) || hasArmAndroidArch(ctx.Config().Targets[Android])) { field := "Arm_on_x86_64" userFriendlyField := "target.arm_on_x86_64" armOnX8664Properties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) if armOnX8664Properties, ok := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField); ok { result = append(result, armOnX8664Properties) } } if os == Android && nativeBridgeEnabled { userFriendlyField := "Native_bridge" prefix := "target.native_bridge" nativeBridgeProperties := getChildPropertyStruct(ctx, targetProp, userFriendlyField, prefix) if nativeBridgeProperties, ok := getChildPropertyStruct(ctx, targetProp, userFriendlyField, prefix); ok { result = append(result, nativeBridgeProperties) } } } return result } Loading Loading @@ -1869,6 +1890,8 @@ type ArchVariantContext interface { // 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`. // // Implemented in a way very similar to GetTargetProperties(). func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet interface{}) map[ArchType]interface{} { // Return value of the arch types to the prop values for that arch. archToProp := map[ArchType]interface{}{} Loading Loading @@ -1903,9 +1926,14 @@ func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet inter // input one that contains the data specific to that arch. propertyStructs := make([]reflect.Value, 0) for _, archProperty := range archProperties { archTypeStruct := getArchTypeStruct(ctx, archProperty, arch) multilibStruct := getMultilibStruct(ctx, archProperty, arch) propertyStructs = append(propertyStructs, archTypeStruct, multilibStruct) archTypeStruct, ok := getArchTypeStruct(ctx, archProperty, arch) if ok { propertyStructs = append(propertyStructs, archTypeStruct) } multilibStruct, ok := getMultilibStruct(ctx, archProperty, arch) if ok { propertyStructs = append(propertyStructs, multilibStruct) } } // Create a new instance of the requested property set Loading @@ -1922,18 +1950,31 @@ func (m *ModuleBase) GetArchProperties(ctx ArchVariantContext, propertySet inter return archToProp } // Returns the struct containing the properties specific to the given // architecture type. These look like this in Blueprint files: // target: { // android: { // key: value, // }, // }, // This struct will also contain sub-structs containing to the architecture/CPU // variants and features that themselves contain properties specific to those. func getTargetStruct(ctx ArchVariantContext, archProperties interface{}, os OsType) (reflect.Value, bool) { archPropValues := reflect.ValueOf(archProperties).Elem() targetProp := archPropValues.FieldByName("Target").Elem() return getChildPropertyStruct(ctx, targetProp, os.Field, os.Field) } // GetTargetProperties returns a map of OS target (e.g. android, windows) to the // values of the properties of the 'dst' struct that are specific to that OS // target. // values of the properties of the 'propertySet' struct that are specific to // that OS target. // // 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 os-specific property value specified by the module if defined. // // While this looks similar to GetArchProperties, the internal representation of // the properties have a slightly different layout to warrant a standalone // lookup function. func (m *ModuleBase) GetTargetProperties(dst interface{}) map[OsType]interface{} { // Implemented in a way very similar to GetArchProperties(). func (m *ModuleBase) GetTargetProperties(ctx ArchVariantContext, propertySet interface{}) map[OsType]interface{} { // Return value of the arch types to the prop values for that arch. osToProp := map[OsType]interface{}{} Loading @@ -1942,69 +1983,48 @@ func (m *ModuleBase) GetTargetProperties(dst interface{}) map[OsType]interface{} return osToProp } // archProperties has the type of [][]interface{}. Looks complicated, so // let's explain this step by step. // // Loop over the outer index, which determines the property struct that // contains a matching set of properties in dst that we're interested in. // For example, BaseCompilerProperties or BaseLinkerProperties. for i := range m.archProperties { if m.archProperties[i] == nil { continue } // Iterate over the supported OS types for _, os := range osTypeList { // e.g android, linux_bionic field := os.Field // If it's not nil, loop over the inner index, which determines the arch variant // of the prop type. In an Android.bp file, this is like looping over: // // target: { android: { key: value, ... }, linux_bionic: { key: value, ... } } for _, archProperties := range m.archProperties[i] { archPropValues := reflect.ValueOf(archProperties).Elem() // This is the archPropRoot struct. Traverse into the Targetnested struct. src := archPropValues.FieldByName("Target").Elem() dstType := reflect.ValueOf(propertySet).Type() var archProperties []interface{} // Step into non-nil pointers to structs in the src value. if src.Kind() == reflect.Ptr { if src.IsNil() { continue // First find the property set in the module that corresponds to the requested // one. m.archProperties[i] corresponds to m.generalProperties[i]. for i, generalProp := range m.generalProperties { srcType := reflect.ValueOf(generalProp).Type() if srcType == dstType { archProperties = m.archProperties[i] break } src = src.Elem() } // Find the requested field (e.g. android, linux_bionic) in the src struct. src = src.FieldByName(field) // Validation steps. We want valid non-nil pointers to structs. if !src.IsValid() || src.IsNil() { continue if archProperties == nil { // This module does not have the property set requested return osToProp } if src.Kind() != reflect.Ptr || src.Elem().Kind() != reflect.Struct { for _, os := range osTypeList { if os == CommonOS { // It looks like this OS value is not used in Blueprint files continue } // Clone the destination prop, since we want a unique prop struct per arch. dstClone := reflect.New(reflect.ValueOf(dst).Elem().Type()).Interface() // Copy the located property struct into the cloned destination property struct. err := proptools.ExtendMatchingProperties([]interface{}{dstClone}, src.Interface(), nil, proptools.OrderReplace) if err != nil { // This is fine, it just means the src struct doesn't match. continue propertyStructs := make([]reflect.Value, 0) for _, archProperty := range archProperties { targetStruct, ok := getTargetStruct(ctx, archProperty, os) if ok { propertyStructs = append(propertyStructs, targetStruct) } } // Found the prop for the os, you have. osToProp[os] = dstClone // Create a new instance of the requested property set value := reflect.New(reflect.ValueOf(propertySet).Elem().Type()).Interface() // Go to the next prop. break } // Merge all the structs together for _, propertyStruct := range propertyStructs { mergePropertyStruct(ctx, value, propertyStruct) } osToProp[os] = value } return osToProp }
cc/bp2build.go +4 −4 Original line number Diff line number Diff line Loading @@ -49,7 +49,7 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { var allDeps []string for _, p := range module.GetTargetProperties(&BaseLinkerProperties{}) { for _, p := range module.GetTargetProperties(ctx, &BaseLinkerProperties{}) { // arch specific linker props if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok { allDeps = append(allDeps, baseLinkerProps.Header_libs...) Loading Loading @@ -273,7 +273,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul srcs.SetValueForArch(bazel.CONDITIONS_DEFAULT, defaultsSrcs) // Handle OS specific props. for os, props := range module.GetTargetProperties(&BaseCompilerProperties{}) { for os, props := range module.GetTargetProperties(ctx, &BaseCompilerProperties{}) { if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { srcsList := parseSrcs(baseCompilerProps) // TODO(b/186153868): add support for os-specific srcs and exclude_srcs Loading Loading @@ -358,7 +358,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) } } for os, p := range module.GetTargetProperties(&BaseLinkerProperties{}) { for os, p := range module.GetTargetProperties(ctx, &BaseLinkerProperties{}) { if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok { libs := baseLinkerProps.Header_libs libs = append(libs, baseLinkerProps.Export_header_lib_headers...) Loading Loading @@ -434,7 +434,7 @@ func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Mo } } for os, props := range module.GetTargetProperties(&FlagExporterProperties{}) { for os, props := range module.GetTargetProperties(ctx, &FlagExporterProperties{}) { if flagExporterProperties, ok := props.(*FlagExporterProperties); ok { osIncludeDirs := flagExporterProperties.Export_system_include_dirs osIncludeDirs = append(osIncludeDirs, flagExporterProperties.Export_include_dirs...) Loading