Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b42fa67a authored by Paul Duffin's avatar Paul Duffin
Browse files

Insert imageVariantSpecificInfo between arch and link info

Previously, the archTypeSpecificInfo included an array of
*linkTypeSpecificInfo. This change replaces that array with an array of
*imageVariantSpecificInfo which themselves contain an array of
*linkTypeSpecificInfo.

That allows the sdk snapshot to handle image variants correctly, i.e.
collate their properties, optimize their properties and then detect if
there are any image variant specific properties for any image variant
other than the CoreImageVariant ("") and report it as an error.

The latter case is treated as an error because while Soong needs to
handle image specific variants there is currently no requirement to
handle generating a prebuilt with image specific properties. A follow
up change will test the error handling.

Image specific variants are needed because the "jni_headers"
cc_library_headers module provides a number of image variants (e.g.
recovery) that are used outside the ART module. Therefore, the sdk
snapshot needs to do the same.

At the moment image variants like the recovery variant are supported by
copying the property that creates the variant (e.g. recovery_available)
through to the prebuilt but that is not safe for a couple of reasons:
1. It ignores any differences between the recovery variant and the
   other variants which could cause compatibility issues in modules
   that build against the prebuilts.
2. It marks modules in the snapshot with recovery_available even when
   they do not need it.

This change will allow follow up changes to address both those issues.

Bug: 195754365
Test: m nothing
Change-Id: I1c187d814f44b2cb7607cd43a6b215134be0faad
parent b1f0f2aa
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
package android

import (
	"android/soong/bazel"
	"fmt"
	"os"
	"path"
@@ -24,6 +23,8 @@ import (
	"strings"
	"text/scanner"

	"android/soong/bazel"

	"github.com/google/blueprint"
	"github.com/google/blueprint/proptools"
)
@@ -468,6 +469,14 @@ type Module interface {
	Enabled() bool
	Target() Target
	MultiTargets() []Target

	// ImageVariation returns the image variation of this module.
	//
	// The returned structure has its Mutator field set to "image" and its Variation field set to the
	// image variation, e.g. recovery, ramdisk, etc.. The Variation field is "" for host modules and
	// device modules that have no image variation.
	ImageVariation() blueprint.Variation

	Owner() string
	InstallInData() bool
	InstallInTestcases() bool
+94 −15
Original line number Diff line number Diff line
@@ -1579,7 +1579,7 @@ type archTypeSpecificInfo struct {
	archId archId
	osType android.OsType

	linkInfos []*linkTypeSpecificInfo
	imageVariantInfos []*imageVariantSpecificInfo
}

var _ propertiesContainer = (*archTypeSpecificInfo)(nil)
@@ -1598,17 +1598,17 @@ func newArchSpecificInfo(ctx android.SdkMemberContext, archId archId, osType and
	if len(archVariants) == 1 {
		archInfo.Properties.PopulateFromVariant(ctx, archVariants[0])
	} else {
		// There is more than one variant for this arch type which must be differentiated
		// by link type.
		for _, linkVariant := range archVariants {
			linkType := getLinkType(linkVariant)
			if linkType == "" {
				panic(fmt.Errorf("expected one arch specific variant as it is not identified by link type but found %d", len(archVariants)))
			} else {
				linkInfo := newLinkSpecificInfo(ctx, linkType, variantPropertiesFactory, linkVariant)

				archInfo.linkInfos = append(archInfo.linkInfos, linkInfo)
		// Group the variants by image type.
		variantsByImage := make(map[string][]android.Module)
		for _, variant := range archVariants {
			image := variant.ImageVariation().Variation
			variantsByImage[image] = append(variantsByImage[image], variant)
		}

		// Create the image variant info in a fixed order.
		for _, imageVariantName := range android.SortedStringKeys(variantsByImage) {
			variants := variantsByImage[imageVariantName]
			archInfo.imageVariantInfos = append(archInfo.imageVariantInfos, newImageVariantSpecificInfo(ctx, imageVariantName, variantPropertiesFactory, variants))
		}
	}

@@ -1638,11 +1638,16 @@ func getLinkType(variant android.Module) string {
// Optimize the properties by extracting common properties from link type specific
// properties into arch type specific properties.
func (archInfo *archTypeSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
	if len(archInfo.linkInfos) == 0 {
	if len(archInfo.imageVariantInfos) == 0 {
		return
	}

	extractCommonProperties(ctx.sdkMemberContext, commonValueExtractor, archInfo.Properties, archInfo.linkInfos)
	// Optimize the image variant properties first.
	for _, imageVariantInfo := range archInfo.imageVariantInfos {
		imageVariantInfo.optimizeProperties(ctx, commonValueExtractor)
	}

	extractCommonProperties(ctx.sdkMemberContext, commonValueExtractor, archInfo.Properties, archInfo.imageVariantInfos)
}

// Add the properties for an arch type to a property set.
@@ -1656,8 +1661,8 @@ func (archInfo *archTypeSpecificInfo) addToPropertySet(ctx *memberContext, archP
	}
	addSdkMemberPropertiesToSet(ctx, archInfo.Properties, archTypePropertySet)

	for _, linkInfo := range archInfo.linkInfos {
		linkInfo.addToPropertySet(ctx, archTypePropertySet)
	for _, imageVariantInfo := range archInfo.imageVariantInfos {
		imageVariantInfo.addToPropertySet(ctx, archTypePropertySet)
	}

	// If this is for a native bridge architecture then make sure that the property set does not
@@ -1691,6 +1696,80 @@ func (archInfo *archTypeSpecificInfo) String() string {
	return archInfo.archId.String()
}

type imageVariantSpecificInfo struct {
	baseInfo

	imageVariant string

	linkInfos []*linkTypeSpecificInfo
}

func newImageVariantSpecificInfo(ctx android.SdkMemberContext, imageVariant string, variantPropertiesFactory variantPropertiesFactoryFunc, imageVariants []android.Module) *imageVariantSpecificInfo {

	// Create an image variant specific info into which the variant properties can be copied.
	imageInfo := &imageVariantSpecificInfo{imageVariant: imageVariant}

	// Create the properties into which the image variant specific properties will be added.
	imageInfo.Properties = variantPropertiesFactory()

	if len(imageVariants) == 1 {
		imageInfo.Properties.PopulateFromVariant(ctx, imageVariants[0])
	} else {
		// There is more than one variant for this image variant which must be differentiated by link
		// type.
		for _, linkVariant := range imageVariants {
			linkType := getLinkType(linkVariant)
			if linkType == "" {
				panic(fmt.Errorf("expected one arch specific variant as it is not identified by link type but found %d", len(imageVariants)))
			} else {
				linkInfo := newLinkSpecificInfo(ctx, linkType, variantPropertiesFactory, linkVariant)

				imageInfo.linkInfos = append(imageInfo.linkInfos, linkInfo)
			}
		}
	}

	return imageInfo
}

// Optimize the properties by extracting common properties from link type specific
// properties into arch type specific properties.
func (imageInfo *imageVariantSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
	if len(imageInfo.linkInfos) == 0 {
		return
	}

	extractCommonProperties(ctx.sdkMemberContext, commonValueExtractor, imageInfo.Properties, imageInfo.linkInfos)
}

// Add the properties for an arch type to a property set.
func (imageInfo *imageVariantSpecificInfo) addToPropertySet(ctx *memberContext, propertySet android.BpPropertySet) {
	if imageInfo.imageVariant != android.CoreVariation {
		propertySet = propertySet.AddPropertySet(imageInfo.imageVariant)
	}

	addSdkMemberPropertiesToSet(ctx, imageInfo.Properties, propertySet)

	for _, linkInfo := range imageInfo.linkInfos {
		linkInfo.addToPropertySet(ctx, propertySet)
	}

	// If this is for a non-core image variant then make sure that the property set does not contain
	// any properties as providing non-core image variant specific properties for prebuilts is not
	// currently supported.
	if imageInfo.imageVariant != android.CoreVariation {
		propertySetContents := getPropertySetContents(propertySet)
		if propertySetContents != "" {
			ctx.SdkModuleContext().ModuleErrorf("Image variant %q of sdk member %q has properties distinct from other variants; this is not yet supported. The properties are:\n%s",
				imageInfo.imageVariant, ctx.name, propertySetContents)
		}
	}
}

func (imageInfo *imageVariantSpecificInfo) String() string {
	return imageInfo.imageVariant
}

type linkTypeSpecificInfo struct {
	baseInfo