aboutsummaryrefslogtreecommitdiff
path: root/sdk/update.go
diff options
context:
space:
mode:
Diffstat (limited to 'sdk/update.go')
-rw-r--r--sdk/update.go526
1 files changed, 295 insertions, 231 deletions
diff --git a/sdk/update.go b/sdk/update.go
index c555ddc7a..e61ae0d0a 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -35,7 +35,7 @@ import (
// ========================================================
//
// SOONG_SDK_SNAPSHOT_PREFER
-// By default every module in the generated snapshot has prefer: false. Building it
+// By default every unversioned module in the generated snapshot has prefer: false. Building it
// with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true.
//
// SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR
@@ -69,6 +69,20 @@ import (
// maintainable solution has been implemented.
// TODO(b/174997203): Remove when no longer necessary.
//
+// SOONG_SDK_SNAPSHOT_VERSION
+// This provides control over the version of the generated snapshot.
+//
+// SOONG_SDK_SNAPSHOT_VERSION=current will generate unversioned and versioned prebuilts and a
+// versioned snapshot module. This is the default behavior. The zip file containing the
+// generated snapshot will be <sdk-name>-current.zip.
+//
+// SOONG_SDK_SNAPSHOT_VERSION=unversioned will generate unversioned prebuilts only and the zip
+// file containing the generated snapshot will be <sdk-name>.zip.
+//
+// SOONG_SDK_SNAPSHOT_VERSION=<number> will generate versioned prebuilts and a versioned
+// snapshot module only. The zip file containing the generated snapshot will be
+// <sdk-name>-<number>.zip.
+//
// SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE
// This allows the target build release (i.e. the release version of the build within which
// the snapshot will be used) of the snapshot to be specified. If unspecified then it defaults
@@ -108,7 +122,7 @@ var (
mergeZips = pctx.AndroidStaticRule("SnapshotMergeZips",
blueprint.RuleParams{
- Command: `${config.MergeZipsCmd} -s $out $in`,
+ Command: `${config.MergeZipsCmd} $out $in`,
CommandDeps: []string{
"${config.MergeZipsCmd}",
},
@@ -116,7 +130,8 @@ var (
)
const (
- soongSdkSnapshotVersionCurrent = "current"
+ soongSdkSnapshotVersionUnversioned = "unversioned"
+ soongSdkSnapshotVersionCurrent = "current"
)
type generatedContents struct {
@@ -148,13 +163,13 @@ func (gc *generatedContents) Dedent() {
// IndentedPrintf will add spaces to indent the line to the appropriate level before printing the
// arguments.
func (gc *generatedContents) IndentedPrintf(format string, args ...interface{}) {
- _, _ = fmt.Fprintf(&(gc.content), strings.Repeat(" ", gc.indentLevel)+format, args...)
+ fmt.Fprintf(&(gc.content), strings.Repeat(" ", gc.indentLevel)+format, args...)
}
// UnindentedPrintf does not add spaces to indent the line to the appropriate level before printing
// the arguments.
func (gc *generatedContents) UnindentedPrintf(format string, args ...interface{}) {
- _, _ = fmt.Fprintf(&(gc.content), format, args...)
+ fmt.Fprintf(&(gc.content), format, args...)
}
func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderContext, implicits android.Paths) {
@@ -239,7 +254,7 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) {
// Finally, the member type slices are concatenated together to form a single slice. The order in
// which they are concatenated is the order in which the member types were registered in the
// android.SdkMemberTypesRegistry.
-func (s *sdk) groupMemberVariantsByMemberThenType(ctx android.ModuleContext, targetBuildRelease *buildRelease, memberVariantDeps []sdkMemberVariantDep) []*sdkMember {
+func (s *sdk) groupMemberVariantsByMemberThenType(ctx android.ModuleContext, memberVariantDeps []sdkMemberVariantDep) []*sdkMember {
byType := make(map[android.SdkMemberType][]*sdkMember)
byName := make(map[string]*sdkMember)
@@ -253,54 +268,22 @@ func (s *sdk) groupMemberVariantsByMemberThenType(ctx android.ModuleContext, tar
member = &sdkMember{memberType: memberType, name: name}
byName[name] = member
byType[memberType] = append(byType[memberType], member)
- } else if member.memberType != memberType {
- // validate whether this is the same member type or and overriding member type
- if memberType.Overrides(member.memberType) {
- member.memberType = memberType
- } else if !member.memberType.Overrides(memberType) {
- ctx.ModuleErrorf("Incompatible member types %q %q", member.memberType, memberType)
- }
}
// Only append new variants to the list. This is needed because a member can be both
// exported by the sdk and also be a transitive sdk member.
member.variants = appendUniqueVariants(member.variants, variant)
}
+
var members []*sdkMember
for _, memberListProperty := range s.memberTypeListProperties() {
- memberType := memberListProperty.memberType
-
- if !isMemberTypeSupportedByTargetBuildRelease(memberType, targetBuildRelease) {
- continue
- }
-
- membersOfType := byType[memberType]
+ membersOfType := byType[memberListProperty.memberType]
members = append(members, membersOfType...)
}
return members
}
-// isMemberTypeSupportedByTargetBuildRelease returns true if the member type is supported by the
-// target build release.
-func isMemberTypeSupportedByTargetBuildRelease(memberType android.SdkMemberType, targetBuildRelease *buildRelease) bool {
- supportedByTargetBuildRelease := true
- supportedBuildReleases := memberType.SupportedBuildReleases()
- if supportedBuildReleases == "" {
- supportedBuildReleases = "S+"
- }
-
- set, err := parseBuildReleaseSet(supportedBuildReleases)
- if err != nil {
- panic(fmt.Errorf("member type %s has invalid supported build releases %q: %s",
- memberType.SdkPropertyName(), supportedBuildReleases, err))
- }
- if !set.contains(targetBuildRelease) {
- supportedByTargetBuildRelease = false
- }
- return supportedByTargetBuildRelease
-}
-
func appendUniqueVariants(variants []android.SdkAware, newVariant android.SdkAware) []android.SdkAware {
for _, v := range variants {
if v == newVariant {
@@ -332,6 +315,12 @@ const BUILD_NUMBER_FILE = "snapshot-creation-build-number.txt"
// <arch>/lib/
// libFoo.so : a stub library
+// A name that uniquely identifies a prebuilt SDK member for a version of SDK snapshot
+// This isn't visible to users, so could be changed in future.
+func versionedSdkMemberName(ctx android.ModuleContext, memberName string, version string) string {
+ return ctx.ModuleName() + "_" + memberName + string(android.SdkVersionSeparator) + version
+}
+
// buildSnapshot is the main function in this source file. It creates rules to copy
// the contents (header files, stub libraries, etc) into the zip file.
func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) {
@@ -383,9 +372,20 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) {
}
config := ctx.Config()
+ version := config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_VERSION", "current")
+
+ // Generate versioned modules in the snapshot unless an unversioned snapshot has been requested.
+ generateVersioned := version != soongSdkSnapshotVersionUnversioned
- // Always add -current to the end
- snapshotFileSuffix := "-current"
+ // Generate unversioned modules in the snapshot unless a numbered snapshot has been requested.
+ //
+ // Unversioned modules are not required in that case because the numbered version will be a
+ // finalized version of the snapshot that is intended to be kept separate from the
+ generateUnversioned := version == soongSdkSnapshotVersionUnversioned || version == soongSdkSnapshotVersionCurrent
+ snapshotFileSuffix := ""
+ if generateVersioned {
+ snapshotFileSuffix = "-" + version
+ }
currentBuildRelease := latestBuildRelease()
targetBuildReleaseEnv := config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", currentBuildRelease.name)
@@ -398,6 +398,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) {
builder := &snapshotBuilder{
ctx: ctx,
sdk: s,
+ version: version,
snapshotDir: snapshotDir.OutputPath,
copies: make(map[string]string),
filesToZip: []android.Path{bp.path},
@@ -427,15 +428,12 @@ be unnecessary as every module in the sdk already has its own licenses property.
// Group the variants for each member module together and then group the members of each member
// type together.
- members := s.groupMemberVariantsByMemberThenType(ctx, targetBuildRelease, memberVariantDeps)
+ members := s.groupMemberVariantsByMemberThenType(ctx, memberVariantDeps)
// Create the prebuilt modules for each of the member modules.
traits := s.gatherTraits()
for _, member := range members {
memberType := member.memberType
- if !memberType.ArePrebuiltsRequired() {
- continue
- }
name := member.name
requiredTraits := traits[name]
@@ -450,19 +448,38 @@ be unnecessary as every module in the sdk already has its own licenses property.
s.createMemberSnapshot(memberCtx, member, prebuiltModule.(*bpModule))
}
- // Create a transformer that will transform a module by replacing any references
+ // Create a transformer that will transform an unversioned module into a versioned module.
+ unversionedToVersionedTransformer := unversionedToVersionedTransformation{builder: builder}
+
+ // Create a transformer that will transform an unversioned module by replacing any references
// to internal members with a unique module name and setting prefer: false.
- snapshotTransformer := snapshotTransformation{
+ unversionedTransformer := unversionedTransformation{
builder: builder,
}
- for _, module := range builder.prebuiltOrder {
+ for _, unversioned := range builder.prebuiltOrder {
// Prune any empty property sets.
- module = module.transform(pruneEmptySetTransformer{})
+ unversioned = unversioned.transform(pruneEmptySetTransformer{})
+
+ if generateVersioned {
+ // Copy the unversioned module so it can be modified to make it versioned.
+ versioned := unversioned.deepCopy()
+
+ // Transform the unversioned module into a versioned one.
+ versioned.transform(unversionedToVersionedTransformer)
+ bpFile.AddModule(versioned)
+ }
- // Transform the module module to make it suitable for use in the snapshot.
- module.transform(snapshotTransformer)
- bpFile.AddModule(module)
+ if generateUnversioned {
+ // Transform the unversioned module to make it suitable for use in the snapshot.
+ unversioned.transform(unversionedTransformer)
+ bpFile.AddModule(unversioned)
+ }
+ }
+
+ if generateVersioned {
+ // Add the sdk/module_exports_snapshot module to the bp file.
+ s.addSnapshotModule(ctx, builder, sdkVariants, memberVariantDeps)
}
// generate Android.bp
@@ -481,7 +498,7 @@ be unnecessary as every module in the sdk already has its own licenses property.
// Copy the build number file into the snapshot.
builder.CopyToSnapshot(ctx.Config().BuildNumberFile(ctx), BUILD_NUMBER_FILE)
- filesToZip := android.SortedUniquePaths(builder.filesToZip)
+ filesToZip := builder.filesToZip
// zip them all
zipPath := fmt.Sprintf("%s%s.zip", ctx.ModuleName(), snapshotFileSuffix)
@@ -517,7 +534,7 @@ be unnecessary as every module in the sdk already has its own licenses property.
Description: outputDesc,
Rule: mergeZips,
Input: zipFile,
- Inputs: android.SortedUniquePaths(builder.zipsToMerge),
+ Inputs: builder.zipsToMerge,
Output: outputZipFile,
})
}
@@ -649,7 +666,7 @@ func (s *sdk) generateInfoData(ctx android.ModuleContext, memberVariantDeps []sd
func filterOutComponents(ctx android.ModuleContext, deps []sdkMemberVariantDep) []sdkMemberVariantDep {
// Collate the set of components that all the modules added to the sdk provide.
components := map[string]*sdkMemberVariantDep{}
- for i := range deps {
+ for i, _ := range deps {
dep := &deps[i]
for _, c := range dep.exportedComponentsInfo.Components {
components[c] = dep
@@ -684,6 +701,81 @@ func filterOutComponents(ctx android.ModuleContext, deps []sdkMemberVariantDep)
return filtered
}
+// addSnapshotModule adds the sdk_snapshot/module_exports_snapshot module to the builder.
+func (s *sdk) addSnapshotModule(ctx android.ModuleContext, builder *snapshotBuilder, sdkVariants []*sdk, memberVariantDeps []sdkMemberVariantDep) {
+ bpFile := builder.bpFile
+
+ snapshotName := ctx.ModuleName() + string(android.SdkVersionSeparator) + builder.version
+ var snapshotModuleType string
+ if s.properties.Module_exports {
+ snapshotModuleType = "module_exports_snapshot"
+ } else {
+ snapshotModuleType = "sdk_snapshot"
+ }
+ snapshotModule := bpFile.newModule(snapshotModuleType)
+ snapshotModule.AddProperty("name", snapshotName)
+
+ // Make sure that the snapshot has the same visibility as the sdk.
+ visibility := android.EffectiveVisibilityRules(ctx, s).Strings()
+ if len(visibility) != 0 {
+ snapshotModule.AddProperty("visibility", visibility)
+ }
+
+ addHostDeviceSupportedProperties(s.ModuleBase.DeviceSupported(), s.ModuleBase.HostSupported(), snapshotModule)
+
+ combinedPropertiesList := s.collateSnapshotModuleInfo(ctx, sdkVariants, memberVariantDeps)
+ commonCombinedProperties := s.optimizeSnapshotModuleProperties(ctx, combinedPropertiesList)
+
+ s.addSnapshotPropertiesToPropertySet(builder, snapshotModule, commonCombinedProperties)
+
+ targetPropertySet := snapshotModule.AddPropertySet("target")
+
+ // Create a mapping from osType to combined properties.
+ osTypeToCombinedProperties := map[android.OsType]*combinedSnapshotModuleProperties{}
+ for _, combined := range combinedPropertiesList {
+ osTypeToCombinedProperties[combined.sdkVariant.Os()] = combined
+ }
+
+ // Iterate over the os types in a fixed order.
+ for _, osType := range s.getPossibleOsTypes() {
+ if combined, ok := osTypeToCombinedProperties[osType]; ok {
+ osPropertySet := targetPropertySet.AddPropertySet(osType.Name)
+
+ s.addSnapshotPropertiesToPropertySet(builder, osPropertySet, combined)
+ }
+ }
+
+ // If host is supported and any member is host OS dependent then disable host
+ // by default, so that we can enable each host OS variant explicitly. This
+ // avoids problems with implicitly enabled OS variants when the snapshot is
+ // used, which might be different from this run (e.g. different build OS).
+ if s.HostSupported() {
+ var supportedHostTargets []string
+ for _, memberVariantDep := range memberVariantDeps {
+ if memberVariantDep.memberType.IsHostOsDependent() && memberVariantDep.variant.Target().Os.Class == android.Host {
+ targetString := memberVariantDep.variant.Target().Os.String() + "_" + memberVariantDep.variant.Target().Arch.ArchType.String()
+ if !android.InList(targetString, supportedHostTargets) {
+ supportedHostTargets = append(supportedHostTargets, targetString)
+ }
+ }
+ }
+ if len(supportedHostTargets) > 0 {
+ hostPropertySet := targetPropertySet.AddPropertySet("host")
+ hostPropertySet.AddProperty("enabled", false)
+ }
+ // Enable the <os>_<arch> variant explicitly when we've disabled it by default on host.
+ for _, hostTarget := range supportedHostTargets {
+ propertySet := targetPropertySet.AddPropertySet(hostTarget)
+ propertySet.AddProperty("enabled", true)
+ }
+ }
+
+ // Prune any empty property sets.
+ snapshotModule.transform(pruneEmptySetTransformer{})
+
+ bpFile.AddModule(snapshotModule)
+}
+
// Check the syntax of the generated Android.bp file contents and if they are
// invalid then log an error with the contents (tagged with line numbers) and the
// errors that were found so that it is easy to see where the problem lies.
@@ -820,34 +912,92 @@ func (s *sdk) optimizeSnapshotModuleProperties(ctx android.ModuleContext, list [
}
}
+func (s *sdk) addSnapshotPropertiesToPropertySet(builder *snapshotBuilder, propertySet android.BpPropertySet, combined *combinedSnapshotModuleProperties) {
+ staticProperties := combined.staticProperties
+ multilib := staticProperties.Compile_multilib
+ if multilib != "" && multilib != "both" {
+ // Compile_multilib defaults to both so only needs to be set when it's specified and not both.
+ propertySet.AddProperty("compile_multilib", multilib)
+ }
+
+ dynamicMemberTypeListProperties := combined.dynamicProperties
+ for _, memberListProperty := range s.memberTypeListProperties() {
+ if memberListProperty.getter == nil {
+ continue
+ }
+ names := memberListProperty.getter(dynamicMemberTypeListProperties)
+ if len(names) > 0 {
+ propertySet.AddProperty(memberListProperty.propertyName(), builder.versionedSdkMemberNames(names, false))
+ }
+ }
+}
+
type propertyTag struct {
name string
}
var _ android.BpPropertyTag = propertyTag{}
-// BpPropertyTag instances to add to a property that contains references to other sdk members.
+// A BpPropertyTag to add to a property that contains references to other sdk members.
//
-// These will ensure that the referenced modules are available, if required.
+// This will cause the references to be rewritten to a versioned reference in the version
+// specific instance of a snapshot module.
var requiredSdkMemberReferencePropertyTag = propertyTag{"requiredSdkMemberReferencePropertyTag"}
var optionalSdkMemberReferencePropertyTag = propertyTag{"optionalSdkMemberReferencePropertyTag"}
-type snapshotTransformation struct {
+// A BpPropertyTag that indicates the property should only be present in the versioned
+// module.
+//
+// This will cause the property to be removed from the unversioned instance of a
+// snapshot module.
+var sdkVersionedOnlyPropertyTag = propertyTag{"sdkVersionedOnlyPropertyTag"}
+
+type unversionedToVersionedTransformation struct {
identityTransformation
builder *snapshotBuilder
}
-func (t snapshotTransformation) transformModule(module *bpModule) *bpModule {
+func (t unversionedToVersionedTransformation) transformModule(module *bpModule) *bpModule {
+ // Use a versioned name for the module but remember the original name for the
+ // snapshot.
+ name := module.Name()
+ module.setProperty("name", t.builder.versionedSdkMemberName(name, true))
+ module.insertAfter("name", "sdk_member_name", name)
+ // Remove the prefer property if present as versioned modules never need marking with prefer.
+ module.removeProperty("prefer")
+ // Ditto for use_source_config_var
+ module.removeProperty("use_source_config_var")
+ return module
+}
+
+func (t unversionedToVersionedTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) {
+ if tag == requiredSdkMemberReferencePropertyTag || tag == optionalSdkMemberReferencePropertyTag {
+ required := tag == requiredSdkMemberReferencePropertyTag
+ return t.builder.versionedSdkMemberNames(value.([]string), required), tag
+ } else {
+ return value, tag
+ }
+}
+
+type unversionedTransformation struct {
+ identityTransformation
+ builder *snapshotBuilder
+}
+
+func (t unversionedTransformation) transformModule(module *bpModule) *bpModule {
// If the module is an internal member then use a unique name for it.
name := module.Name()
- module.setProperty("name", t.builder.snapshotSdkMemberName(name, true))
+ module.setProperty("name", t.builder.unversionedSdkMemberName(name, true))
return module
}
-func (t snapshotTransformation) transformProperty(_ string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) {
+func (t unversionedTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) {
if tag == requiredSdkMemberReferencePropertyTag || tag == optionalSdkMemberReferencePropertyTag {
required := tag == requiredSdkMemberReferencePropertyTag
- return t.builder.snapshotSdkMemberNames(value.([]string), required), tag
+ return t.builder.unversionedSdkMemberNames(value.([]string), required), tag
+ } else if tag == sdkVersionedOnlyPropertyTag {
+ // The property is not allowed in the unversioned module so remove it.
+ return nil, nil
} else {
return value, tag
}
@@ -859,7 +1009,7 @@ type pruneEmptySetTransformer struct {
var _ bpTransformer = (*pruneEmptySetTransformer)(nil)
-func (t pruneEmptySetTransformer) transformPropertySetAfterContents(_ string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+func (t pruneEmptySetTransformer) transformPropertySetAfterContents(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
if len(propertySet.properties) == 0 {
return nil, nil
} else {
@@ -868,12 +1018,20 @@ func (t pruneEmptySetTransformer) transformPropertySetAfterContents(_ string, pr
}
func generateBpContents(contents *generatedContents, bpFile *bpFile) {
+ generateFilteredBpContents(contents, bpFile, func(*bpModule) bool {
+ return true
+ })
+}
+
+func generateFilteredBpContents(contents *generatedContents, bpFile *bpFile, moduleFilter func(module *bpModule) bool) {
contents.IndentedPrintf("// This is auto-generated. DO NOT EDIT.\n")
for _, bpModule := range bpFile.order {
- contents.IndentedPrintf("\n")
- contents.IndentedPrintf("%s {\n", bpModule.moduleType)
- outputPropertySet(contents, bpModule.bpPropertySet)
- contents.IndentedPrintf("}\n")
+ if moduleFilter(bpModule) {
+ contents.IndentedPrintf("\n")
+ contents.IndentedPrintf("%s {\n", bpModule.moduleType)
+ outputPropertySet(contents, bpModule.bpPropertySet)
+ contents.IndentedPrintf("}\n")
+ }
}
}
@@ -1009,10 +1167,36 @@ func (s *sdk) GetInfoContentsForTests() string {
return s.builderForTests.infoContents
}
+func (s *sdk) GetUnversionedAndroidBpContentsForTests() string {
+ contents := &generatedContents{}
+ generateFilteredBpContents(contents, s.builderForTests.bpFile, func(module *bpModule) bool {
+ name := module.Name()
+ // Include modules that are either unversioned or have no name.
+ return !strings.Contains(name, "@")
+ })
+ return contents.content.String()
+}
+
+func (s *sdk) GetVersionedAndroidBpContentsForTests() string {
+ contents := &generatedContents{}
+ generateFilteredBpContents(contents, s.builderForTests.bpFile, func(module *bpModule) bool {
+ name := module.Name()
+ // Include modules that are either versioned or have no name.
+ return name == "" || strings.Contains(name, "@")
+ })
+ return contents.content.String()
+}
+
type snapshotBuilder struct {
ctx android.ModuleContext
sdk *sdk
+ // The version of the generated snapshot.
+ //
+ // See the documentation of SOONG_SDK_SNAPSHOT_VERSION above for details of the valid values of
+ // this field.
+ version string
+
snapshotDir android.OutputPath
bpFile *bpFile
@@ -1166,6 +1350,13 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType
addHostDeviceSupportedProperties(deviceSupported, hostSupported, m)
+ // Disable installation in the versioned module of those modules that are ever installable.
+ if installable, ok := variant.(interface{ EverInstallable() bool }); ok {
+ if installable.EverInstallable() {
+ m.AddPropertyWithTag("installable", false, sdkVersionedOnlyPropertyTag)
+ }
+ }
+
s.prebuiltModules[name] = m
s.prebuiltOrder = append(s.prebuiltOrder, m)
return m
@@ -1198,28 +1389,45 @@ func (s *snapshotBuilder) OptionalSdkMemberReferencePropertyTag() android.BpProp
return optionalSdkMemberReferencePropertyTag
}
-// Get a name for sdk snapshot member. If the member is private then generate a snapshot specific
-// name. As part of the processing this checks to make sure that any required members are part of
-// the snapshot.
-func (s *snapshotBuilder) snapshotSdkMemberName(name string, required bool) string {
- if _, ok := s.allMembersByName[name]; !ok {
+// Get a versioned name appropriate for the SDK snapshot version being taken.
+func (s *snapshotBuilder) versionedSdkMemberName(unversionedName string, required bool) string {
+ if _, ok := s.allMembersByName[unversionedName]; !ok {
if required {
- s.ctx.ModuleErrorf("Required member reference %s is not a member of the sdk", name)
+ s.ctx.ModuleErrorf("Required member reference %s is not a member of the sdk", unversionedName)
}
- return name
+ return unversionedName
}
+ return versionedSdkMemberName(s.ctx, unversionedName, s.version)
+}
- if s.isInternalMember(name) {
- return s.ctx.ModuleName() + "_" + name
+func (s *snapshotBuilder) versionedSdkMemberNames(members []string, required bool) []string {
+ var references []string = nil
+ for _, m := range members {
+ references = append(references, s.versionedSdkMemberName(m, required))
+ }
+ return references
+}
+
+// Get an internal name unique to the sdk.
+func (s *snapshotBuilder) unversionedSdkMemberName(unversionedName string, required bool) string {
+ if _, ok := s.allMembersByName[unversionedName]; !ok {
+ if required {
+ s.ctx.ModuleErrorf("Required member reference %s is not a member of the sdk", unversionedName)
+ }
+ return unversionedName
+ }
+
+ if s.isInternalMember(unversionedName) {
+ return s.ctx.ModuleName() + "_" + unversionedName
} else {
- return name
+ return unversionedName
}
}
-func (s *snapshotBuilder) snapshotSdkMemberNames(members []string, required bool) []string {
+func (s *snapshotBuilder) unversionedSdkMemberNames(members []string, required bool) []string {
var references []string = nil
for _, m := range members {
- references = append(references, s.snapshotSdkMemberName(m, required))
+ references = append(references, s.unversionedSdkMemberName(m, required))
}
return references
}
@@ -1322,119 +1530,6 @@ func (m multilibUsage) String() string {
}
}
-// TODO(187910671): BEGIN - Remove once modules do not have an APEX and default variant.
-// variantCoordinate contains the coordinates used to identify a variant of an SDK member.
-type variantCoordinate struct {
- // osType identifies the OS target of a variant.
- osType android.OsType
- // archId identifies the architecture and whether it is for the native bridge.
- archId archId
- // image is the image variant name.
- image string
- // linkType is the link type name.
- linkType string
-}
-
-func getVariantCoordinate(ctx *memberContext, variant android.Module) variantCoordinate {
- linkType := ""
- if len(ctx.MemberType().SupportedLinkages()) > 0 {
- linkType = getLinkType(variant)
- }
- return variantCoordinate{
- osType: variant.Target().Os,
- archId: archIdFromTarget(variant.Target()),
- image: variant.ImageVariation().Variation,
- linkType: linkType,
- }
-}
-
-// selectApexVariantsWhereAvailable filters the input list of variants by selecting the APEX
-// specific variant for a specific variantCoordinate when there is both an APEX and default variant.
-//
-// There is a long-standing issue where a module that is added to an APEX has both an APEX and
-// default/platform variant created even when the module does not require a platform variant. As a
-// result an indirect dependency onto a module via the APEX will use the APEX variant, whereas a
-// direct dependency onto the module will use the default/platform variant. That would result in a
-// failure while attempting to optimize the properties for a member as it would have two variants
-// when only one was expected.
-//
-// This function mitigates that problem by detecting when there are two variants that differ only
-// by apex variant, where one is the default/platform variant and one is the APEX variant. In that
-// case it picks the APEX variant. It picks the APEX variant because that is the behavior that would
-// be expected
-func selectApexVariantsWhereAvailable(ctx *memberContext, variants []android.SdkAware) []android.SdkAware {
- moduleCtx := ctx.sdkMemberContext
-
- // Group the variants by coordinates.
- variantsByCoord := make(map[variantCoordinate][]android.SdkAware)
- for _, variant := range variants {
- coord := getVariantCoordinate(ctx, variant)
- variantsByCoord[coord] = append(variantsByCoord[coord], variant)
- }
-
- toDiscard := make(map[android.SdkAware]struct{})
- for coord, list := range variantsByCoord {
- count := len(list)
- if count == 1 {
- continue
- }
-
- variantsByApex := make(map[string]android.SdkAware)
- conflictDetected := false
- for _, variant := range list {
- apexInfo := moduleCtx.OtherModuleProvider(variant, android.ApexInfoProvider).(android.ApexInfo)
- apexVariationName := apexInfo.ApexVariationName
- // If there are two variants for a specific APEX variation then there is conflict.
- if _, ok := variantsByApex[apexVariationName]; ok {
- conflictDetected = true
- break
- }
- variantsByApex[apexVariationName] = variant
- }
-
- // If there are more than 2 apex variations or one of the apex variations is not the
- // default/platform variation then there is a conflict.
- if len(variantsByApex) != 2 {
- conflictDetected = true
- } else if _, ok := variantsByApex[""]; !ok {
- conflictDetected = true
- }
-
- // If there are no conflicts then add the default/platform variation to the list to remove.
- if !conflictDetected {
- toDiscard[variantsByApex[""]] = struct{}{}
- continue
- }
-
- // There are duplicate variants at this coordinate and they are not the default and APEX variant
- // so fail.
- variantDescriptions := []string{}
- for _, m := range list {
- variantDescriptions = append(variantDescriptions, fmt.Sprintf(" %s", m.String()))
- }
-
- moduleCtx.ModuleErrorf("multiple conflicting variants detected for OsType{%s}, %s, Image{%s}, Link{%s}\n%s",
- coord.osType, coord.archId.String(), coord.image, coord.linkType,
- strings.Join(variantDescriptions, "\n"))
- }
-
- // If there are any variants to discard then remove them from the list of variants, while
- // preserving the order.
- if len(toDiscard) > 0 {
- filtered := []android.SdkAware{}
- for _, variant := range variants {
- if _, ok := toDiscard[variant]; !ok {
- filtered = append(filtered, variant)
- }
- }
- variants = filtered
- }
-
- return variants
-}
-
-// TODO(187910671): END - Remove once modules do not have an APEX and default variant.
-
type baseInfo struct {
Properties android.SdkMemberProperties
}
@@ -1490,14 +1585,7 @@ func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType,
if commonVariants, ok := variantsByArchId[commonArchId]; ok {
if len(osTypeVariants) != 1 {
- variants := []string{}
- for _, m := range osTypeVariants {
- variants = append(variants, fmt.Sprintf(" %s", m.String()))
- }
- panic(fmt.Errorf("expected to only have 1 variant of %q when arch type is common but found %d\n%s",
- ctx.Name(),
- len(osTypeVariants),
- strings.Join(variants, "\n")))
+ panic(fmt.Errorf("Expected to only have 1 variant when arch type is common but found %d", len(osTypeVariants)))
}
// A common arch type only has one variant and its properties should be treated
@@ -1695,9 +1783,7 @@ func newArchSpecificInfo(ctx android.SdkMemberContext, archId archId, osType and
// added.
archInfo.Properties = variantPropertiesFactory()
- // if there are multiple supported link variants, we want to nest based on linkage even if there
- // is only one variant, otherwise, if there is only one variant we can populate based on the arch
- if len(archVariants) == 1 && len(ctx.MemberType().SupportedLinkages()) <= 1 {
+ if len(archVariants) == 1 {
archInfo.Properties.PopulateFromVariant(ctx, archVariants[0])
} else {
// Group the variants by image type.
@@ -1824,13 +1910,11 @@ func newImageVariantSpecificInfo(ctx android.SdkMemberContext, imageVariant stri
// Create the properties into which the image variant specific properties will be added.
imageInfo.Properties = variantPropertiesFactory()
- // if there are multiple supported link variants, we want to nest even if there is only one
- // variant, otherwise, if there is only one variant we can populate based on the image
- if len(imageVariants) == 1 && len(ctx.MemberType().SupportedLinkages()) <= 1 {
+ 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. Or there are multiple supported linkages and we need to nest based on link type.
+ // type.
for _, linkVariant := range imageVariants {
linkType := getLinkType(linkVariant)
if linkType == "" {
@@ -1874,22 +1958,10 @@ func (imageInfo *imageVariantSpecificInfo) addToPropertySet(ctx *memberContext,
addSdkMemberPropertiesToSet(ctx, imageInfo.Properties, propertySet)
- usedLinkages := make(map[string]bool, len(imageInfo.linkInfos))
for _, linkInfo := range imageInfo.linkInfos {
- usedLinkages[linkInfo.linkType] = true
linkInfo.addToPropertySet(ctx, propertySet)
}
- // If not all supported linkages had existing variants, we need to disable the unsupported variant
- if len(imageInfo.linkInfos) < len(ctx.MemberType().SupportedLinkages()) {
- for _, l := range ctx.MemberType().SupportedLinkages() {
- if _, ok := usedLinkages[l]; !ok {
- otherLinkagePropertySet := propertySet.AddPropertySet(l)
- otherLinkagePropertySet.AddProperty("enabled", false)
- }
- }
- }
-
// 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.
@@ -1972,19 +2044,12 @@ func (m *memberContext) RequiresTrait(trait android.SdkMemberTrait) bool {
return m.requiredTraits.Contains(trait)
}
-func (m *memberContext) IsTargetBuildBeforeTiramisu() bool {
- return m.builder.targetBuildRelease.EarlierThan(buildReleaseT)
-}
-
-var _ android.SdkMemberContext = (*memberContext)(nil)
-
func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModule *bpModule) {
memberType := member.memberType
// Do not add the prefer property if the member snapshot module is a source module type.
- moduleCtx := ctx.sdkMemberContext
- config := moduleCtx.Config()
+ config := ctx.sdkMemberContext.Config()
if !memberType.UsesSourceModuleTypeInSnapshot() {
// Set the prefer based on the environment variable. This is a temporary work around to allow a
// snapshot to be created that sets prefer: true.
@@ -2009,10 +2074,9 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu
}
}
- variants := selectApexVariantsWhereAvailable(ctx, member.variants)
-
// Group the variants by os type.
variantsByOsType := make(map[android.OsType][]android.Module)
+ variants := member.Variants()
for _, variant := range variants {
osType := variant.Target().Os
variantsByOsType[osType] = append(variantsByOsType[osType], variant)
@@ -2058,7 +2122,7 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu
}
// Extract properties which are common across all architectures and os types.
- extractCommonProperties(moduleCtx, commonValueExtractor, commonProperties, osSpecificPropertiesContainers)
+ extractCommonProperties(ctx.sdkMemberContext, commonValueExtractor, commonProperties, osSpecificPropertiesContainers)
// Add the common properties to the module.
addSdkMemberPropertiesToSet(ctx, commonProperties, bpModule)