diff --git a/android/arch.go b/android/arch.go index 74fef3d24..c1b2c33ca 100644 --- a/android/arch.go +++ b/android/arch.go @@ -1014,35 +1014,19 @@ func initArchModule(m Module) { base.customizableProperties = m.GetProperties() } -// appendProperties squashes properties from the given field of the given src property struct -// into the dst property struct. Returns the reflect.Value of the field in the src property -// struct to be used for further appendProperties calls on fields of that property struct. -func (m *ModuleBase) appendProperties(ctx BottomUpMutatorContext, - dst interface{}, src reflect.Value, field, srcPrefix string) reflect.Value { - - // Step into non-nil pointers to structs in the src value. - if src.Kind() == reflect.Ptr { - if src.IsNil() { - return src - } - src = src.Elem() - } - - // Find the requested field in the src struct. - src = src.FieldByName(field) - if !src.IsValid() { - ctx.ModuleErrorf("field %q does not exist", srcPrefix) - return src - } - - // Save the value of the field in the src struct to return. - ret := src - +func maybeBlueprintEmbed(src reflect.Value) reflect.Value { // If the value of the field is a struct (as opposed to a pointer to a struct) then step // into the BlueprintEmbed field. if src.Kind() == reflect.Struct { - src = src.FieldByName("BlueprintEmbed") + return src.FieldByName("BlueprintEmbed") + } else { + return src } +} + +// Merges the property struct in srcValue into dst. +func mergePropertyStruct(ctx BaseMutatorContext, dst interface{}, srcValue reflect.Value) { + src := maybeBlueprintEmbed(srcValue).Interface() // order checks the `android:"variant_prepend"` tag to handle properties where the // arch-specific value needs to come before the generic value, for example for lists of @@ -1058,7 +1042,7 @@ func (m *ModuleBase) appendProperties(ctx BottomUpMutatorContext, } // Squash the located property struct into the destination property struct. - err := proptools.ExtendMatchingProperties([]interface{}{dst}, src.Interface(), nil, order) + err := proptools.ExtendMatchingProperties([]interface{}{dst}, src, nil, order) if err != nil { if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) @@ -1066,8 +1050,29 @@ func (m *ModuleBase) appendProperties(ctx BottomUpMutatorContext, panic(err) } } +} - return ret +// Returns the immediate child of the input property struct that corresponds to +// the sub-property "field". +func getChildPropertyStruct(ctx BaseMutatorContext, + src reflect.Value, field, userFriendlyField string) reflect.Value { + + // Step into non-nil pointers to structs in the src value. + if src.Kind() == reflect.Ptr { + if src.IsNil() { + return src + } + src = src.Elem() + } + + // Find the requested field in the src struct. + src = src.FieldByName(proptools.FieldNameForProperty(field)) + if !src.IsValid() { + ctx.ModuleErrorf("field %q does not exist", userFriendlyField) + return src + } + + return src } // Squash the appropriate OS-specific property structs into the matching top level property structs @@ -1094,7 +1099,8 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if os.Class == Host { field := "Host" prefix := "target.host" - m.appendProperties(ctx, genProps, targetProp, field, prefix) + hostProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) + mergePropertyStruct(ctx, genProps, hostProperties) } // Handle target OS generalities of the form: @@ -1106,13 +1112,15 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if os.Linux() { field := "Linux" prefix := "target.linux" - m.appendProperties(ctx, genProps, targetProp, field, prefix) + linuxProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) + mergePropertyStruct(ctx, genProps, linuxProperties) } if os.Bionic() { field := "Bionic" prefix := "target.bionic" - m.appendProperties(ctx, genProps, targetProp, field, prefix) + bionicProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) + mergePropertyStruct(ctx, genProps, bionicProperties) } // Handle target OS properties in the form: @@ -1129,12 +1137,14 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { // }, field := os.Field prefix := "target." + os.Name - m.appendProperties(ctx, genProps, targetProp, field, prefix) + osProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) + mergePropertyStruct(ctx, genProps, osProperties) if os.Class == Host && os != Windows { field := "Not_windows" prefix := "target.not_windows" - m.appendProperties(ctx, genProps, targetProp, field, prefix) + notWindowsProperties := getChildPropertyStruct(ctx, targetProp, field, prefix) + mergePropertyStruct(ctx, genProps, notWindowsProperties) } // Handle 64-bit device properties in the form: @@ -1154,17 +1164,189 @@ func (m *ModuleBase) setOSProperties(ctx BottomUpMutatorContext) { if ctx.Config().Android64() { field := "Android64" prefix := "target.android64" - m.appendProperties(ctx, genProps, targetProp, field, prefix) + android64Properties := getChildPropertyStruct(ctx, targetProp, field, prefix) + mergePropertyStruct(ctx, genProps, android64Properties) } else { field := "Android32" prefix := "target.android32" - m.appendProperties(ctx, genProps, targetProp, field, prefix) + android32Properties := getChildPropertyStruct(ctx, targetProp, field, prefix) + mergePropertyStruct(ctx, genProps, android32Properties) } } } } } +// Returns the struct containing the properties specific to the given +// architecture type. These look like this in Blueprint files: +// arch: { +// arm64: { +// 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 getArchTypeStruct(ctx BaseMutatorContext, archProperties interface{}, archType ArchType) reflect.Value { + archPropValues := reflect.ValueOf(archProperties).Elem() + archProp := archPropValues.FieldByName("Arch").Elem() + prefix := "arch." + archType.Name + archStruct := getChildPropertyStruct(ctx, archProp, archType.Name, prefix) + return archStruct +} + +// Returns the struct containing the properties specific to a given multilib +// value. These look like this in the Blueprint file: +// multilib: { +// lib32: { +// key: value, +// }, +// }, +func getMultilibStruct(ctx BaseMutatorContext, archProperties interface{}, archType ArchType) reflect.Value { + archPropValues := reflect.ValueOf(archProperties).Elem() + multilibProp := archPropValues.FieldByName("Multilib").Elem() + multilibProperties := getChildPropertyStruct(ctx, multilibProp, archType.Multilib, "multilib."+archType.Multilib) + return multilibProperties +} + +// Returns the structs corresponding to the properties specific to the given +// architecture and OS in archProperties. +func getArchProperties(ctx BaseMutatorContext, archProperties interface{}, arch Arch, os OsType, nativeBridgeEnabled bool) []reflect.Value { + result := make([]reflect.Value, 0) + archPropValues := reflect.ValueOf(archProperties).Elem() + + targetProp := archPropValues.FieldByName("Target").Elem() + + archType := arch.ArchType + + if arch.ArchType != Common { + archStruct := getArchTypeStruct(ctx, archProperties, arch.ArchType) + result = append(result, archStruct) + + // Handle arch-variant-specific properties in the form: + // arch: { + // arm: { + // variant: { + // key: value, + // }, + // }, + // }, + v := variantReplacer.Replace(arch.ArchVariant) + if v != "" { + prefix := "arch." + archType.Name + "." + v + variantProperties := getChildPropertyStruct(ctx, archStruct, v, prefix) + result = append(result, variantProperties) + } + + // Handle cpu-variant-specific properties in the form: + // arch: { + // arm: { + // variant: { + // key: value, + // }, + // }, + // }, + if arch.CpuVariant != arch.ArchVariant { + c := variantReplacer.Replace(arch.CpuVariant) + if c != "" { + prefix := "arch." + archType.Name + "." + c + cpuVariantProperties := getChildPropertyStruct(ctx, archStruct, c, prefix) + result = append(result, cpuVariantProperties) + } + } + + // Handle arch-feature-specific properties in the form: + // arch: { + // arm: { + // feature: { + // key: value, + // }, + // }, + // }, + for _, feature := range arch.ArchFeatures { + prefix := "arch." + archType.Name + "." + feature + featureProperties := getChildPropertyStruct(ctx, archStruct, feature, prefix) + result = append(result, featureProperties) + } + + multilibProperties := getMultilibStruct(ctx, archProperties, archType) + result = append(result, multilibProperties) + + // Handle combined OS-feature and arch specific properties in the form: + // target: { + // bionic_x86: { + // key: value, + // }, + // } + if os.Linux() { + field := "Linux_" + arch.ArchType.Name + userFriendlyField := "target.linux_" + arch.ArchType.Name + linuxProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) + result = append(result, linuxProperties) + } + + if os.Bionic() { + field := "Bionic_" + archType.Name + userFriendlyField := "target.bionic_" + archType.Name + bionicProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) + result = append(result, bionicProperties) + } + + // Handle combined OS and arch specific properties in the form: + // target: { + // linux_glibc_x86: { + // key: value, + // }, + // linux_glibc_arm: { + // key: value, + // }, + // android_arm { + // key: value, + // }, + // android_x86 { + // key: value, + // }, + // }, + field := os.Field + "_" + archType.Name + userFriendlyField := "target." + os.Name + "_" + archType.Name + osArchProperties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) + result = append(result, osArchProperties) + } + + // Handle arm on x86 properties in the form: + // target { + // arm_on_x86 { + // key: value, + // }, + // arm_on_x86_64 { + // key: value, + // }, + // }, + if os.Class == Device { + if arch.ArchType == X86 && (hasArmAbi(arch) || + hasArmAndroidArch(ctx.Config().Targets[Android])) { + field := "Arm_on_x86" + userFriendlyField := "target.arm_on_x86" + armOnX86Properties := getChildPropertyStruct(ctx, targetProp, field, userFriendlyField) + 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) + result = append(result, armOnX8664Properties) + } + if os == Android && nativeBridgeEnabled { + userFriendlyField := "Native_bridge" + prefix := "target.native_bridge" + nativeBridgeProperties := getChildPropertyStruct(ctx, targetProp, userFriendlyField, prefix) + result = append(result, nativeBridgeProperties) + } + } + + return result +} + // Squash the appropriate arch-specific property structs into the matching top level property // structs based on the CompileTarget value that was annotated on the variant. func (m *ModuleBase) setArchProperties(ctx BottomUpMutatorContext) { @@ -1176,144 +1358,15 @@ func (m *ModuleBase) setArchProperties(ctx BottomUpMutatorContext) { if m.archProperties[i] == nil { continue } - for _, archProperties := range m.archProperties[i] { - archPropValues := reflect.ValueOf(archProperties).Elem() - archProp := archPropValues.FieldByName("Arch").Elem() - multilibProp := archPropValues.FieldByName("Multilib").Elem() - targetProp := archPropValues.FieldByName("Target").Elem() + propStructs := make([]reflect.Value, 0) + for _, archProperty := range m.archProperties[i] { + propStructShard := getArchProperties(ctx, archProperty, arch, os, m.Target().NativeBridge == NativeBridgeEnabled) + propStructs = append(propStructs, propStructShard...) + } - // Handle arch-specific properties in the form: - // arch: { - // arm64: { - // key: value, - // }, - // }, - t := arch.ArchType - - if arch.ArchType != Common { - field := proptools.FieldNameForProperty(t.Name) - prefix := "arch." + t.Name - archStruct := m.appendProperties(ctx, genProps, archProp, field, prefix) - - // Handle arch-variant-specific properties in the form: - // arch: { - // variant: { - // key: value, - // }, - // }, - v := variantReplacer.Replace(arch.ArchVariant) - if v != "" { - field := proptools.FieldNameForProperty(v) - prefix := "arch." + t.Name + "." + v - m.appendProperties(ctx, genProps, archStruct, field, prefix) - } - - // Handle cpu-variant-specific properties in the form: - // arch: { - // variant: { - // key: value, - // }, - // }, - if arch.CpuVariant != arch.ArchVariant { - c := variantReplacer.Replace(arch.CpuVariant) - if c != "" { - field := proptools.FieldNameForProperty(c) - prefix := "arch." + t.Name + "." + c - m.appendProperties(ctx, genProps, archStruct, field, prefix) - } - } - - // Handle arch-feature-specific properties in the form: - // arch: { - // feature: { - // key: value, - // }, - // }, - for _, feature := range arch.ArchFeatures { - field := proptools.FieldNameForProperty(feature) - prefix := "arch." + t.Name + "." + feature - m.appendProperties(ctx, genProps, archStruct, field, prefix) - } - - // Handle multilib-specific properties in the form: - // multilib: { - // lib32: { - // key: value, - // }, - // }, - field = proptools.FieldNameForProperty(t.Multilib) - prefix = "multilib." + t.Multilib - m.appendProperties(ctx, genProps, multilibProp, field, prefix) - } - - // Handle combined OS-feature and arch specific properties in the form: - // target: { - // bionic_x86: { - // key: value, - // }, - // } - if os.Linux() && arch.ArchType != Common { - field := "Linux_" + arch.ArchType.Name - prefix := "target.linux_" + arch.ArchType.Name - m.appendProperties(ctx, genProps, targetProp, field, prefix) - } - - if os.Bionic() && arch.ArchType != Common { - field := "Bionic_" + t.Name - prefix := "target.bionic_" + t.Name - m.appendProperties(ctx, genProps, targetProp, field, prefix) - } - - // Handle combined OS and arch specific properties in the form: - // target: { - // linux_glibc_x86: { - // key: value, - // }, - // linux_glibc_arm: { - // key: value, - // }, - // android_arm { - // key: value, - // }, - // android_x86 { - // key: value, - // }, - // }, - if arch.ArchType != Common { - field := os.Field + "_" + t.Name - prefix := "target." + os.Name + "_" + t.Name - m.appendProperties(ctx, genProps, targetProp, field, prefix) - } - - // Handle arm on x86 properties in the form: - // target { - // arm_on_x86 { - // key: value, - // }, - // arm_on_x86_64 { - // key: value, - // }, - // }, - if os.Class == Device { - if arch.ArchType == X86 && (hasArmAbi(arch) || - hasArmAndroidArch(ctx.Config().Targets[Android])) { - field := "Arm_on_x86" - prefix := "target.arm_on_x86" - m.appendProperties(ctx, genProps, targetProp, field, prefix) - } - if arch.ArchType == X86_64 && (hasArmAbi(arch) || - hasArmAndroidArch(ctx.Config().Targets[Android])) { - field := "Arm_on_x86_64" - prefix := "target.arm_on_x86_64" - m.appendProperties(ctx, genProps, targetProp, field, prefix) - } - if os == Android && m.Target().NativeBridge == NativeBridgeEnabled { - field := "Native_bridge" - prefix := "target.native_bridge" - m.appendProperties(ctx, genProps, targetProp, field, prefix) - } - } + for _, propStruct := range propStructs { + mergePropertyStruct(ctx, genProps, propStruct) } } } @@ -1810,7 +1863,7 @@ func (m *ModuleBase) getMultilibPropertySet(propertySet interface{}, archType Ar // 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) GetArchProperties(propertySet interface{}) map[ArchType]interface{} { +func (m *ModuleBase) GetArchProperties(ctx BaseMutatorContext, propertySet interface{}) map[ArchType]interface{} { // Return value of the arch types to the prop values for that arch. archToProp := map[ArchType]interface{}{} @@ -1819,27 +1872,47 @@ func (m *ModuleBase) GetArchProperties(propertySet interface{}) map[ArchType]int return archToProp } - // For each arch (x86, arm64, etc.), + 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.generalProperties[i]. + for i, generalProp := range m.generalProperties { + srcType := reflect.ValueOf(generalProp).Type() + if srcType == dstType { + archProperties = m.archProperties[i] + break + } + } + + if archProperties == nil { + // This module does not have the property set requested + return archToProp + } + + // For each arch type (x86, arm64, etc.) for _, arch := range ArchTypeList() { - // Find arch-specific properties matching that property set type. For example, any - // matching properties under `arch { x86 { ... } }`. - archPropertySet := m.getArchPropertySet(propertySet, arch) - - // Find multilib-specific properties matching that property set type. For example, any - // matching properties under `multilib { lib32 { ... } }` for x86, as x86 is 32-bit. - multilibPropertySet := m.getMultilibPropertySet(propertySet, arch) - - // Append the multilibPropertySet to archPropertySet. This combines the - // arch and multilib properties into a single property struct. - err := proptools.ExtendMatchingProperties([]interface{}{archPropertySet}, multilibPropertySet, nil, proptools.OrderAppend) - if err != nil { - // archPropertySet and multilibPropertySet must be of the same type, or - // something horrible went wrong. - panic(err) + // Arch properties are sometimes sharded (see createArchPropTypeDesc() ). + // Iterate over ever 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) + for _, archProperty := range archProperties { + archTypeStruct := getArchTypeStruct(ctx, archProperty, arch) + multilibStruct := getMultilibStruct(ctx, archProperty, arch) + propertyStructs = append(propertyStructs, archTypeStruct, multilibStruct) } - archToProp[arch] = archPropertySet + // 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) + } + + archToProp[arch] = value } + return archToProp } diff --git a/bazel/properties.go b/bazel/properties.go index 12dfcaff8..a71b12bfd 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -229,11 +229,47 @@ type Attribute interface { // Represents an attribute whose value is a single label type LabelAttribute struct { - Value Label + Value Label + X86 Label + X86_64 Label + Arm Label + Arm64 Label } -func (LabelAttribute) HasConfigurableValues() bool { - return false +func (attr *LabelAttribute) GetValueForArch(arch string) Label { + switch arch { + case ARCH_ARM: + return attr.Arm + case ARCH_ARM64: + return attr.Arm64 + case ARCH_X86: + return attr.X86 + case ARCH_X86_64: + return attr.X86_64 + case CONDITIONS_DEFAULT: + return attr.Value + default: + panic("Invalid arch type") + } +} + +func (attr *LabelAttribute) SetValueForArch(arch string, value Label) { + switch arch { + case ARCH_ARM: + attr.Arm = value + case ARCH_ARM64: + attr.Arm64 = value + case ARCH_X86: + attr.X86 = value + case ARCH_X86_64: + attr.X86_64 = value + default: + panic("Invalid arch type") + } +} + +func (attr LabelAttribute) HasConfigurableValues() bool { + return attr.Arm.Label != "" || attr.Arm64.Label != "" || attr.X86.Label != "" || attr.X86_64.Label != "" } // Arch-specific label_list typed Bazel attribute values. This should correspond diff --git a/bp2build/configurability.go b/bp2build/configurability.go index 050679b53..95a2747d6 100644 --- a/bp2build/configurability.go +++ b/bp2build/configurability.go @@ -59,22 +59,30 @@ func getLabelListValues(list bazel.LabelListAttribute) (reflect.Value, selects, func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) { var value reflect.Value var archSelects, osSelects selects + var defaultSelectValue string switch list := v.(type) { case bazel.StringListAttribute: value, archSelects, osSelects = getStringListValues(list) + defaultSelectValue = "[]" case bazel.LabelListAttribute: value, archSelects, osSelects = getLabelListValues(list) + defaultSelectValue = "[]" case bazel.LabelAttribute: value, archSelects, osSelects = getLabelValue(list) + defaultSelectValue = "None" default: return "", fmt.Errorf("Not a supported Bazel attribute type: %s", v) } - ret, err := prettyPrint(value, indent) - if err != nil { - return ret, err - } + ret := "" + if value.Kind() != reflect.Invalid { + s, err := prettyPrint(value, indent) + if err != nil { + return ret, err + } + ret += s + } // Convenience function to append selects components to an attribute value. appendSelects := func(selectsData selects, defaultValue, s string) (string, error) { selectMap, err := prettyPrintSelectMap(selectsData, defaultValue, indent) @@ -89,12 +97,12 @@ func prettyPrintAttribute(v bazel.Attribute, indent int) (string, error) { return s, nil } - ret, err = appendSelects(archSelects, "[]", ret) + ret, err := appendSelects(archSelects, defaultSelectValue, ret) if err != nil { return "", err } - ret, err = appendSelects(osSelects, "[]", ret) + ret, err = appendSelects(osSelects, defaultSelectValue, ret) return ret, err } diff --git a/bp2build/testing.go b/bp2build/testing.go index 452f6ed1a..b925682c4 100644 --- a/bp2build/testing.go +++ b/bp2build/testing.go @@ -142,7 +142,7 @@ func customBp2BuildMutator(ctx android.TopDownMutatorContext) { paths := bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.props.Arch_paths)) - for arch, props := range m.GetArchProperties(&customProps{}) { + for arch, props := range m.GetArchProperties(ctx, &customProps{}) { if archProps, ok := props.(*customProps); ok && archProps.Arch_paths != nil { paths.SetValueForArch(arch.Name, android.BazelLabelForModuleSrc(ctx, archProps.Arch_paths)) } diff --git a/cc/bp2build.go b/cc/bp2build.go index d52b817b2..1433f6f79 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -58,7 +58,7 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { } } - for _, p := range module.GetArchProperties(&BaseLinkerProperties{}) { + for _, p := range module.GetArchProperties(ctx, &BaseLinkerProperties{}) { // arch specific linker props if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok { allDeps = append(allDeps, baseLinkerProps.Header_libs...) @@ -198,7 +198,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul copts.Value = append(copts.Value, includeFlag(".")) } - for arch, props := range module.GetArchProperties(&BaseCompilerProperties{}) { + for arch, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) { if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { // If there's arch specific srcs or exclude_srcs, generate a select entry for it. // TODO(b/186153868): do this for OS specific srcs and exclude_srcs too. @@ -215,7 +215,7 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul // After going through all archs, delete the duplicate files in the arch // values that are already in the base srcs.Value. - for arch, props := range module.GetArchProperties(&BaseCompilerProperties{}) { + for arch, props := range module.GetArchProperties(ctx, &BaseCompilerProperties{}) { if _, ok := props.(*BaseCompilerProperties); ok { srcs.SetValueForArch(arch.Name, bazel.SubtractBazelLabelList(srcs.GetValueForArch(arch.Name), srcs.Value)) } @@ -269,15 +269,13 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) linkopts.Value = baseLinkerProps.Ldflags if baseLinkerProps.Version_script != nil { - versionScript = bazel.LabelAttribute{ - Value: android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script), - } + versionScript.Value = android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script) } break } } - for arch, p := range module.GetArchProperties(&BaseLinkerProperties{}) { + for arch, p := range module.GetArchProperties(ctx, &BaseLinkerProperties{}) { if baseLinkerProps, ok := p.(*BaseLinkerProperties); ok { libs := baseLinkerProps.Header_libs libs = append(libs, baseLinkerProps.Export_header_lib_headers...) @@ -286,6 +284,10 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) libs = android.SortedUniqueStrings(libs) deps.SetValueForArch(arch.Name, android.BazelLabelForModuleDeps(ctx, libs)) linkopts.SetValueForArch(arch.Name, baseLinkerProps.Ldflags) + if baseLinkerProps.Version_script != nil { + versionScript.SetValueForArch(arch.Name, + android.BazelLabelForModuleSrcSingle(ctx, *baseLinkerProps.Version_script)) + } } } @@ -343,7 +345,7 @@ func bp2BuildParseExportedIncludes(ctx android.TopDownMutatorContext, module *Mo includeDirs = append(includeDirs, libraryDecorator.flagExporter.Properties.Export_include_dirs...) includeDirsAttribute := bazel.MakeStringListAttribute(includeDirs) - for arch, props := range module.GetArchProperties(&FlagExporterProperties{}) { + for arch, props := range module.GetArchProperties(ctx, &FlagExporterProperties{}) { if flagExporterProperties, ok := props.(*FlagExporterProperties); ok { archIncludeDirs := flagExporterProperties.Export_system_include_dirs archIncludeDirs = append(archIncludeDirs, flagExporterProperties.Export_include_dirs...)