Merge "Make SystemServerJars ConfiguredJarList."
diff --git a/android/arch.go b/android/arch.go
index 74fef3d..c1b2c33 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -1014,35 +1014,19 @@
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 @@
}
// 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 @@
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 @@
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 @@
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 @@
// },
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 @@
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 @@
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 @@
// 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 @@
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 12dfcaf..a71b12b 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -229,11 +229,47 @@
// 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 050679b..95a2747 100644
--- a/bp2build/configurability.go
+++ b/bp2build/configurability.go
@@ -59,22 +59,30 @@
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 @@
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 452f6ed..b925682 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -142,7 +142,7 @@
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 d52b817..1433f6f 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -58,7 +58,7 @@
}
}
- 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 @@
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 @@
// 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 @@
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 @@
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 @@
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...)
diff --git a/cc/test.go b/cc/test.go
index 9b77e45..d4c23d7 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -46,6 +46,14 @@
// If the test is a hostside(no device required) unittest that shall be run during presubmit check.
Unit_test *bool
+
+ // Add ShippingApiLevelModuleController to auto generated test config. If the device properties
+ // for the shipping api level is less than the test_min_api_level, skip this module.
+ Test_min_api_level *int64
+
+ // Add MinApiLevelModuleController with ro.vndk.version property. If ro.vndk.version has an
+ // integer value and the value is less than the test_min_vndk_version, skip this module.
+ Test_min_vndk_version *int64
}
type TestBinaryProperties struct {
@@ -89,6 +97,7 @@
// Add ShippingApiLevelModuleController to auto generated test config. If the device properties
// for the shipping api level is less than the test_min_api_level, skip this module.
+ // Deprecated (b/187258404). Use test_options.test_min_api_level instead.
Test_min_api_level *int64
// Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
@@ -395,11 +404,22 @@
for _, tag := range test.Properties.Test_options.Test_suite_tag {
configs = append(configs, tradefed.Option{Name: "test-suite-tag", Value: tag})
}
- if test.Properties.Test_min_api_level != nil {
+ if test.Properties.Test_options.Test_min_api_level != nil {
+ var options []tradefed.Option
+ options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Test_min_api_level), 10)})
+ configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
+ } else if test.Properties.Test_min_api_level != nil {
+ // TODO: (b/187258404) Remove test.Properties.Test_min_api_level
var options []tradefed.Option
options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_min_api_level), 10)})
configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.ShippingApiLevelModuleController", options})
}
+ if test.Properties.Test_options.Test_min_vndk_version != nil {
+ var options []tradefed.Option
+ options = append(options, tradefed.Option{Name: "min-api-level", Value: strconv.FormatInt(int64(*test.Properties.Test_options.Test_min_vndk_version), 10)})
+ options = append(options, tradefed.Option{Name: "api-level-prop", Value: "ro.vndk.version"})
+ configs = append(configs, tradefed.Object{"module_controller", "com.android.tradefed.testtype.suite.module.MinApiLevelModuleController", options})
+ }
test.testConfig = tradefed.AutoGenNativeTestConfig(ctx, test.Properties.Test_config,
test.Properties.Test_config_template, test.Properties.Test_suites, configs, test.Properties.Auto_gen_config, testInstallBase)
diff --git a/cmd/run_with_timeout/run_with_timeout.go b/cmd/run_with_timeout/run_with_timeout.go
index e225872..f2caaab 100644
--- a/cmd/run_with_timeout/run_with_timeout.go
+++ b/cmd/run_with_timeout/run_with_timeout.go
@@ -23,6 +23,7 @@
"io"
"os"
"os/exec"
+ "sync"
"syscall"
"time"
)
@@ -62,10 +63,42 @@
}
}
+// concurrentWriter wraps a writer to make it thread-safe to call Write.
+type concurrentWriter struct {
+ w io.Writer
+ sync.Mutex
+}
+
+// Write writes the data to the wrapped writer with a lock to allow for concurrent calls.
+func (c *concurrentWriter) Write(data []byte) (n int, err error) {
+ c.Lock()
+ defer c.Unlock()
+ if c.w == nil {
+ return 0, nil
+ }
+ return c.w.Write(data)
+}
+
+// Close ends the concurrentWriter, causing future calls to Write to be no-ops. It does not close
+// the underlying writer.
+func (c *concurrentWriter) Close() {
+ c.Lock()
+ defer c.Unlock()
+ c.w = nil
+}
+
func runWithTimeout(command string, args []string, timeout time.Duration, onTimeoutCmdStr string,
stdin io.Reader, stdout, stderr io.Writer) error {
cmd := exec.Command(command, args...)
- cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, stdout, stderr
+
+ // Wrap the writers in a locking writer so that cmd and onTimeoutCmd don't try to write to
+ // stdout or stderr concurrently.
+ concurrentStdout := &concurrentWriter{w: stdout}
+ concurrentStderr := &concurrentWriter{w: stderr}
+ defer concurrentStdout.Close()
+ defer concurrentStderr.Close()
+
+ cmd.Stdin, cmd.Stdout, cmd.Stderr = stdin, concurrentStdout, concurrentStderr
err := cmd.Start()
if err != nil {
return err
@@ -98,7 +131,7 @@
if onTimeoutCmdStr != "" {
onTimeoutCmd := exec.Command("sh", "-c", onTimeoutCmdStr)
- onTimeoutCmd.Stdin, onTimeoutCmd.Stdout, onTimeoutCmd.Stderr = stdin, stdout, stderr
+ onTimeoutCmd.Stdin, onTimeoutCmd.Stdout, onTimeoutCmd.Stderr = stdin, concurrentStdout, concurrentStderr
onTimeoutCmd.Env = append(os.Environ(), fmt.Sprintf("PID=%d", cmd.Process.Pid))
err := onTimeoutCmd.Run()
if err != nil {
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 01c0f16..56e6247 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -193,23 +193,6 @@
return false
}
-// Used by xsd_config
-type ApiFilePath interface {
- ApiFilePath() android.Path
-}
-
-type ApiStubsSrcProvider interface {
- StubsSrcJar() android.Path
-}
-
-// Provider of information about API stubs, used by java_sdk_library.
-type ApiStubsProvider interface {
- ApiFilePath
- RemovedApiFilePath() android.Path
-
- ApiStubsSrcProvider
-}
-
//
// Javadoc
//
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 90d9896..566f7e3 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -146,6 +146,23 @@
Write_sdk_values *bool
}
+// Used by xsd_config
+type ApiFilePath interface {
+ ApiFilePath() android.Path
+}
+
+type ApiStubsSrcProvider interface {
+ StubsSrcJar() android.Path
+}
+
+// Provider of information about API stubs, used by java_sdk_library.
+type ApiStubsProvider interface {
+ ApiFilePath
+ RemovedApiFilePath() android.Path
+
+ ApiStubsSrcProvider
+}
+
// droidstubs passes sources files through Metalava to generate stub .java files that only contain the API to be
// documented, filtering out hidden classes and methods. The resulting .java files are intended to be passed to
// a droiddoc module to generate documentation.
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index 4cb02e3..3a59822 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -321,6 +321,8 @@
}
hiddenAPISupportingModules = append(hiddenAPISupportingModules, hiddenAPISupportingModule)
+ } else if _, ok := module.(*DexImport); ok {
+ // Ignore this for the purposes of hidden API processing
} else {
ctx.ModuleErrorf("module %s of type %s does not support hidden API processing", module, ctx.OtherModuleType(module))
}
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index 2216b11..98d4614 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -133,6 +133,23 @@
"platform:bar",
})
})
+
+ t.Run("dex import", func(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ preparer,
+ android.FixtureAddTextFile("deximport/Android.bp", `
+ dex_import {
+ name: "foo",
+ jars: ["a.jar"],
+ }
+ `),
+ ).RunTest(t)
+
+ CheckPlatformBootclasspathModules(t, result, "platform-bootclasspath", []string{
+ "platform:prebuilt_foo",
+ "platform:bar",
+ })
+ })
}
func TestPlatformBootclasspath_Fragments(t *testing.T) {