Allow sdk snapshot code to identify native bridge variants
Previously, the snapshot code ignored native bridge related arch
specific variants and only used the non native bridge variants. This
change enabled it to track native bridge variants too.
There is currently no support for creating native bridge specific
prebuilts so this ensures that any attempt to create one will fail
during generation of the snapshot with a clear message.
At the moment that error message cannot be tested by creating an sdk as
there is no way to add a dependency from the sdk onto a native bridge
variant. A follow up change will add the capability to test this
functionality through an sdk.
Bug: 195754365
Test: m nothing
Change-Id: I0494fdba9cc2ff013ea990d12d6a03a0a444bd5c
diff --git a/sdk/update.go b/sdk/update.go
index e889f3a..02e61fb 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -1393,19 +1393,19 @@
osInfo.Properties = osSpecificVariantPropertiesFactory()
// Group the variants by arch type.
- var variantsByArchName = make(map[string][]android.Module)
- var archTypes []android.ArchType
+ var variantsByArchId = make(map[archId][]android.Module)
+ var archIds []archId
for _, variant := range osTypeVariants {
- archType := variant.Target().Arch.ArchType
- archTypeName := archType.Name
- if _, ok := variantsByArchName[archTypeName]; !ok {
- archTypes = append(archTypes, archType)
+ target := variant.Target()
+ id := archIdFromTarget(target)
+ if _, ok := variantsByArchId[id]; !ok {
+ archIds = append(archIds, id)
}
- variantsByArchName[archTypeName] = append(variantsByArchName[archTypeName], variant)
+ variantsByArchId[id] = append(variantsByArchId[id], variant)
}
- if commonVariants, ok := variantsByArchName["common"]; ok {
+ if commonVariants, ok := variantsByArchId[commonArchId]; ok {
if len(osTypeVariants) != 1 {
panic(fmt.Errorf("Expected to only have 1 variant when arch type is common but found %d", len(osTypeVariants)))
}
@@ -1415,11 +1415,9 @@
osInfo.Properties.PopulateFromVariant(ctx, commonVariants[0])
} else {
// Create an arch specific info for each supported architecture type.
- for _, archType := range archTypes {
- archTypeName := archType.Name
-
- archVariants := variantsByArchName[archTypeName]
- archInfo := newArchSpecificInfo(ctx, archType, osType, osSpecificVariantPropertiesFactory, archVariants)
+ for _, id := range archIds {
+ archVariants := variantsByArchId[id]
+ archInfo := newArchSpecificInfo(ctx, id, osType, osSpecificVariantPropertiesFactory, archVariants)
osInfo.archInfos = append(osInfo.archInfos, archInfo)
}
@@ -1438,7 +1436,7 @@
multilib := multilibNone
for _, archInfo := range osInfo.archInfos {
- multilib = multilib.addArchType(archInfo.archType)
+ multilib = multilib.addArchType(archInfo.archId.archType)
// Optimize the arch properties first.
archInfo.optimizeProperties(ctx, commonValueExtractor)
@@ -1531,11 +1529,55 @@
return fmt.Sprintf("OsType{%s}", osInfo.osType)
}
+// archId encapsulates the information needed to identify a combination of arch type and native
+// bridge support.
+//
+// Conceptually, native bridge support is a facet of an android.Target, not an android.Arch as it is
+// essentially using one android.Arch to implement another. However, in terms of the handling of
+// the variants native bridge is treated as part of the arch variation. See the ArchVariation method
+// on android.Target.
+//
+// So, it makes sense when optimizing the variants to combine native bridge with the arch type.
+type archId struct {
+ // The arch type of the variant's target.
+ archType android.ArchType
+
+ // True if the variants is for the native bridge, false otherwise.
+ nativeBridge bool
+}
+
+// propertyName returns the name of the property corresponding to use for this arch id.
+func (i *archId) propertyName() string {
+ name := i.archType.Name
+ if i.nativeBridge {
+ // Note: This does not result in a valid property because there is no architecture specific
+ // native bridge property, only a generic "native_bridge" property. However, this will be used
+ // in error messages if there is an attempt to use this in a generated bp file.
+ name += "_native_bridge"
+ }
+ return name
+}
+
+func (i *archId) String() string {
+ return fmt.Sprintf("ArchType{%s}, NativeBridge{%t}", i.archType, i.nativeBridge)
+}
+
+// archIdFromTarget returns an archId initialized from information in the supplied target.
+func archIdFromTarget(target android.Target) archId {
+ return archId{
+ archType: target.Arch.ArchType,
+ nativeBridge: target.NativeBridge == android.NativeBridgeEnabled,
+ }
+}
+
+// commonArchId is the archId for the common architecture.
+var commonArchId = archId{archType: android.Common}
+
type archTypeSpecificInfo struct {
baseInfo
- archType android.ArchType
- osType android.OsType
+ archId archId
+ osType android.OsType
linkInfos []*linkTypeSpecificInfo
}
@@ -1544,10 +1586,10 @@
// Create a new archTypeSpecificInfo for the specified arch type and its properties
// structures populated with information from the variants.
-func newArchSpecificInfo(ctx android.SdkMemberContext, archType android.ArchType, osType android.OsType, variantPropertiesFactory variantPropertiesFactoryFunc, archVariants []android.Module) *archTypeSpecificInfo {
+func newArchSpecificInfo(ctx android.SdkMemberContext, archId archId, osType android.OsType, variantPropertiesFactory variantPropertiesFactoryFunc, archVariants []android.Module) *archTypeSpecificInfo {
// Create an arch specific info into which the variant properties can be copied.
- archInfo := &archTypeSpecificInfo{archType: archType, osType: osType}
+ archInfo := &archTypeSpecificInfo{archId: archId, osType: osType}
// Create the properties into which the arch type specific properties will be
// added.
@@ -1605,8 +1647,9 @@
// Add the properties for an arch type to a property set.
func (archInfo *archTypeSpecificInfo) addToPropertySet(ctx *memberContext, archPropertySet android.BpPropertySet, archOsPrefix string) {
- archTypeName := archInfo.archType.Name
- archTypePropertySet := archPropertySet.AddPropertySet(archOsPrefix + archTypeName)
+ archPropertySuffix := archInfo.archId.propertyName()
+ propertySetName := archOsPrefix + archPropertySuffix
+ archTypePropertySet := archPropertySet.AddPropertySet(propertySetName)
// Enable the <os>_<arch> variant explicitly when we've disabled it by default on host.
if ctx.memberType.IsHostOsDependent() && archInfo.osType.Class == android.Host {
archTypePropertySet.AddProperty("enabled", true)
@@ -1616,10 +1659,36 @@
for _, linkInfo := range archInfo.linkInfos {
linkInfo.addToPropertySet(ctx, archTypePropertySet)
}
+
+ // If this is for a native bridge architecture then make sure that the property set does not
+ // contain any properties as providing native bridge specific properties is not currently
+ // supported.
+ if archInfo.archId.nativeBridge {
+ propertySetContents := getPropertySetContents(archTypePropertySet)
+ if propertySetContents != "" {
+ ctx.SdkModuleContext().ModuleErrorf("Architecture variant %q of sdk member %q has properties distinct from other variants; this is not yet supported. The properties are:\n%s",
+ propertySetName, ctx.name, propertySetContents)
+ }
+ }
+}
+
+// getPropertySetContents returns the string representation of the contents of a property set, after
+// recursively pruning any empty nested property sets.
+func getPropertySetContents(propertySet android.BpPropertySet) string {
+ set := propertySet.(*bpPropertySet)
+ set.transformContents(pruneEmptySetTransformer{})
+ if len(set.properties) != 0 {
+ contents := &generatedContents{}
+ contents.Indent()
+ outputPropertySet(contents, set)
+ setAsString := contents.content.String()
+ return setAsString
+ }
+ return ""
}
func (archInfo *archTypeSpecificInfo) String() string {
- return fmt.Sprintf("ArchType{%s}", archInfo.archType)
+ return archInfo.archId.String()
}
type linkTypeSpecificInfo struct {