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
This commit is contained in:
Paul Duffin 2021-09-09 18:50:49 +01:00
parent d19f894512
commit fefdb0bf0a

View file

@ -1393,19 +1393,19 @@ func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType,
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 @@ func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType,
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 @@ func (osInfo *osTypeSpecificInfo) optimizeProperties(ctx *memberContext, commonV
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 @@ func (osInfo *osTypeSpecificInfo) String() string {
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 @@ var _ propertiesContainer = (*archTypeSpecificInfo)(nil)
// 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 @@ func (archInfo *archTypeSpecificInfo) optimizeProperties(ctx *memberContext, com
// 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 @@ func (archInfo *archTypeSpecificInfo) addToPropertySet(ctx *memberContext, archP
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 {