Support generating sdk snapshot for specific build release
Previously, the sdk snapshot was assumed to be generated for the current build system. This change adds support for the SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE environment variable which can be used to select the target build release in which the generated snapshot will be used. At the moment this will only affect the properties that are output but if/when it becomes necessary it can also be used to control more aspects of the snapshots such as supported member types or even members. This change does not modify any properties that are build release specific. That will come in following changes. However, it does add a test that targets build release S which defines a baseline for properties that will be affected in following changes. That baseline makes it easier to see the effect of those follow up changes. Bug: 197842263 Test: m nothing Change-Id: I5cfde5e9e86af522b0d5030d301e116b0233fd62
This commit is contained in:
@@ -21,6 +21,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
"android/soong/java"
|
||||||
|
|
||||||
"github.com/google/blueprint/proptools"
|
"github.com/google/blueprint/proptools"
|
||||||
)
|
)
|
||||||
@@ -706,4 +707,88 @@ sdk_snapshot {
|
|||||||
snapshotTestPreparer(checkSnapshotWithoutSource, android.FixtureWithRootAndroidBp(bp)),
|
snapshotTestPreparer(checkSnapshotWithoutSource, android.FixtureWithRootAndroidBp(bp)),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) {
|
||||||
|
result := android.GroupFixturePreparers(
|
||||||
|
prepareForSdkTestWithJava,
|
||||||
|
java.PrepareForTestWithJavaDefaultModules,
|
||||||
|
java.PrepareForTestWithJavaSdkLibraryFiles,
|
||||||
|
java.FixtureWithLastReleaseApis("mysdklibrary"),
|
||||||
|
android.FixtureWithRootAndroidBp(`
|
||||||
|
sdk {
|
||||||
|
name: "mysdk",
|
||||||
|
bootclasspath_fragments: ["mybootclasspathfragment"],
|
||||||
|
}
|
||||||
|
|
||||||
|
bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
contents: ["mysdklibrary"],
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library {
|
||||||
|
name: "mysdklibrary",
|
||||||
|
srcs: ["Test.java"],
|
||||||
|
compile_dex: true,
|
||||||
|
public: {enabled: true},
|
||||||
|
permitted_packages: ["mysdklibrary"],
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
android.FixtureMergeEnv(map[string]string{
|
||||||
|
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": "S",
|
||||||
|
}),
|
||||||
|
).RunTest(t)
|
||||||
|
|
||||||
|
CheckSnapshot(t, result, "mysdk", "",
|
||||||
|
checkUnversionedAndroidBpContents(`
|
||||||
|
// This is auto-generated. DO NOT EDIT.
|
||||||
|
|
||||||
|
prebuilt_bootclasspath_fragment {
|
||||||
|
name: "mybootclasspathfragment",
|
||||||
|
prefer: false,
|
||||||
|
visibility: ["//visibility:public"],
|
||||||
|
apex_available: ["myapex"],
|
||||||
|
contents: ["mysdklibrary"],
|
||||||
|
hidden_api: {
|
||||||
|
annotation_flags: "hiddenapi/annotation-flags.csv",
|
||||||
|
metadata: "hiddenapi/metadata.csv",
|
||||||
|
index: "hiddenapi/index.csv",
|
||||||
|
signature_patterns: "hiddenapi/signature-patterns.csv",
|
||||||
|
stub_flags: "hiddenapi/filtered-stub-flags.csv",
|
||||||
|
all_flags: "hiddenapi/filtered-flags.csv",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
java_sdk_library_import {
|
||||||
|
name: "mysdklibrary",
|
||||||
|
prefer: false,
|
||||||
|
visibility: ["//visibility:public"],
|
||||||
|
apex_available: ["//apex_available:platform"],
|
||||||
|
shared_library: true,
|
||||||
|
compile_dex: true,
|
||||||
|
permitted_packages: ["mysdklibrary"],
|
||||||
|
public: {
|
||||||
|
jars: ["sdk_library/public/mysdklibrary-stubs.jar"],
|
||||||
|
stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"],
|
||||||
|
current_api: "sdk_library/public/mysdklibrary.txt",
|
||||||
|
removed_api: "sdk_library/public/mysdklibrary-removed.txt",
|
||||||
|
sdk_version: "current",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`),
|
||||||
|
|
||||||
|
checkAllCopyRules(`
|
||||||
|
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv
|
||||||
|
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv
|
||||||
|
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv
|
||||||
|
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv
|
||||||
|
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv
|
||||||
|
.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv
|
||||||
|
.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar
|
||||||
|
.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt
|
||||||
|
.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt
|
||||||
|
`),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -136,6 +136,7 @@ func getSdkSnapshotBuildInfo(t *testing.T, result *android.TestResult, sdk *sdk)
|
|||||||
androidUnversionedBpContents: sdk.GetUnversionedAndroidBpContentsForTests(),
|
androidUnversionedBpContents: sdk.GetUnversionedAndroidBpContentsForTests(),
|
||||||
androidVersionedBpContents: sdk.GetVersionedAndroidBpContentsForTests(),
|
androidVersionedBpContents: sdk.GetVersionedAndroidBpContentsForTests(),
|
||||||
snapshotTestCustomizations: map[snapshotTest]*snapshotTestCustomization{},
|
snapshotTestCustomizations: map[snapshotTest]*snapshotTestCustomization{},
|
||||||
|
targetBuildRelease: sdk.builderForTests.targetBuildRelease,
|
||||||
}
|
}
|
||||||
|
|
||||||
buildParams := sdk.BuildParamsForTests()
|
buildParams := sdk.BuildParamsForTests()
|
||||||
@@ -253,6 +254,13 @@ func CheckSnapshot(t *testing.T, result *android.TestResult, name string, dir st
|
|||||||
}
|
}
|
||||||
fs[filepath.Join(snapshotSubDir, "Android.bp")] = []byte(snapshotBuildInfo.androidBpContents)
|
fs[filepath.Join(snapshotSubDir, "Android.bp")] = []byte(snapshotBuildInfo.androidBpContents)
|
||||||
|
|
||||||
|
// If the generated snapshot builders not for the current release then it cannot be loaded by
|
||||||
|
// the current release.
|
||||||
|
currentBuildRelease := latestBuildRelease()
|
||||||
|
if snapshotBuildInfo.targetBuildRelease != currentBuildRelease {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// The preparers from the original source fixture.
|
// The preparers from the original source fixture.
|
||||||
sourcePreparers := result.Preparer()
|
sourcePreparers := result.Preparer()
|
||||||
|
|
||||||
@@ -476,6 +484,9 @@ type snapshotBuildInfo struct {
|
|||||||
// The final output zip.
|
// The final output zip.
|
||||||
outputZip string
|
outputZip string
|
||||||
|
|
||||||
|
// The target build release.
|
||||||
|
targetBuildRelease *buildRelease
|
||||||
|
|
||||||
// The test specific customizations for each snapshot test.
|
// The test specific customizations for each snapshot test.
|
||||||
snapshotTestCustomizations map[snapshotTest]*snapshotTestCustomization
|
snapshotTestCustomizations map[snapshotTest]*snapshotTestCustomization
|
||||||
}
|
}
|
||||||
|
@@ -81,6 +81,19 @@ import (
|
|||||||
// snapshot module only. The zip file containing the generated snapshot will be
|
// snapshot module only. The zip file containing the generated snapshot will be
|
||||||
// <sdk-name>-<number>.zip.
|
// <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
|
||||||
|
// to the current build release version. Otherwise, it must be the name of one of the build
|
||||||
|
// releases defined in nameToBuildRelease, e.g. S, T, etc..
|
||||||
|
//
|
||||||
|
// The generated snapshot must only be used in the specified target release. If the target
|
||||||
|
// build release is not the current build release then the generated Android.bp file not be
|
||||||
|
// checked for compatibility.
|
||||||
|
//
|
||||||
|
// e.g. if setting SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S will cause the generated snapshot
|
||||||
|
// to be compatible with S.
|
||||||
|
//
|
||||||
|
|
||||||
var pctx = android.NewPackageContext("android/soong/sdk")
|
var pctx = android.NewPackageContext("android/soong/sdk")
|
||||||
|
|
||||||
@@ -358,6 +371,14 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro
|
|||||||
snapshotZipFileSuffix = "-" + version
|
snapshotZipFileSuffix = "-" + version
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentBuildRelease := latestBuildRelease()
|
||||||
|
targetBuildReleaseEnv := config.GetenvWithDefault("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE", currentBuildRelease.name)
|
||||||
|
targetBuildRelease, err := nameToRelease(targetBuildReleaseEnv)
|
||||||
|
if err != nil {
|
||||||
|
ctx.ModuleErrorf("invalid SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE: %s", err)
|
||||||
|
targetBuildRelease = currentBuildRelease
|
||||||
|
}
|
||||||
|
|
||||||
builder := &snapshotBuilder{
|
builder := &snapshotBuilder{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
sdk: s,
|
sdk: s,
|
||||||
@@ -369,6 +390,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro
|
|||||||
prebuiltModules: make(map[string]*bpModule),
|
prebuiltModules: make(map[string]*bpModule),
|
||||||
allMembersByName: allMembersByName,
|
allMembersByName: allMembersByName,
|
||||||
exportedMembersByName: exportedMembersByName,
|
exportedMembersByName: exportedMembersByName,
|
||||||
|
targetBuildRelease: targetBuildRelease,
|
||||||
}
|
}
|
||||||
s.builderForTests = builder
|
s.builderForTests = builder
|
||||||
|
|
||||||
@@ -449,7 +471,11 @@ be unnecessary as every module in the sdk already has its own licenses property.
|
|||||||
generateBpContents(&bp.generatedContents, bpFile)
|
generateBpContents(&bp.generatedContents, bpFile)
|
||||||
|
|
||||||
contents := bp.content.String()
|
contents := bp.content.String()
|
||||||
syntaxCheckSnapshotBpFile(ctx, contents)
|
// If the snapshot is being generated for the current build release then check the syntax to make
|
||||||
|
// sure that it is compatible.
|
||||||
|
if targetBuildRelease == currentBuildRelease {
|
||||||
|
syntaxCheckSnapshotBpFile(ctx, contents)
|
||||||
|
}
|
||||||
|
|
||||||
bp.build(pctx, ctx, nil)
|
bp.build(pctx, ctx, nil)
|
||||||
|
|
||||||
@@ -1051,6 +1077,9 @@ type snapshotBuilder struct {
|
|||||||
|
|
||||||
// The set of exported members by name.
|
// The set of exported members by name.
|
||||||
exportedMembersByName map[string]struct{}
|
exportedMembersByName map[string]struct{}
|
||||||
|
|
||||||
|
// The target build release for which the snapshot is to be generated.
|
||||||
|
targetBuildRelease *buildRelease
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
|
func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) {
|
||||||
@@ -1426,6 +1455,16 @@ func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType,
|
|||||||
return osInfo
|
return osInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (osInfo *osTypeSpecificInfo) pruneUnsupportedProperties(pruner *propertyPruner) {
|
||||||
|
if len(osInfo.archInfos) == 0 {
|
||||||
|
pruner.pruneProperties(osInfo.Properties)
|
||||||
|
} else {
|
||||||
|
for _, archInfo := range osInfo.archInfos {
|
||||||
|
archInfo.pruneUnsupportedProperties(pruner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Optimize the properties by extracting common properties from arch type specific
|
// Optimize the properties by extracting common properties from arch type specific
|
||||||
// properties into os type specific properties.
|
// properties into os type specific properties.
|
||||||
func (osInfo *osTypeSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
|
func (osInfo *osTypeSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
|
||||||
@@ -1635,6 +1674,16 @@ func getLinkType(variant android.Module) string {
|
|||||||
return linkType
|
return linkType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (archInfo *archTypeSpecificInfo) pruneUnsupportedProperties(pruner *propertyPruner) {
|
||||||
|
if len(archInfo.imageVariantInfos) == 0 {
|
||||||
|
pruner.pruneProperties(archInfo.Properties)
|
||||||
|
} else {
|
||||||
|
for _, imageVariantInfo := range archInfo.imageVariantInfos {
|
||||||
|
imageVariantInfo.pruneUnsupportedProperties(pruner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Optimize the properties by extracting common properties from link type specific
|
// Optimize the properties by extracting common properties from link type specific
|
||||||
// properties into arch type specific properties.
|
// properties into arch type specific properties.
|
||||||
func (archInfo *archTypeSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
|
func (archInfo *archTypeSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
|
||||||
@@ -1732,6 +1781,16 @@ func newImageVariantSpecificInfo(ctx android.SdkMemberContext, imageVariant stri
|
|||||||
return imageInfo
|
return imageInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (imageInfo *imageVariantSpecificInfo) pruneUnsupportedProperties(pruner *propertyPruner) {
|
||||||
|
if len(imageInfo.linkInfos) == 0 {
|
||||||
|
pruner.pruneProperties(imageInfo.Properties)
|
||||||
|
} else {
|
||||||
|
for _, linkInfo := range imageInfo.linkInfos {
|
||||||
|
linkInfo.pruneUnsupportedProperties(pruner)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Optimize the properties by extracting common properties from link type specific
|
// Optimize the properties by extracting common properties from link type specific
|
||||||
// properties into arch type specific properties.
|
// properties into arch type specific properties.
|
||||||
func (imageInfo *imageVariantSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
|
func (imageInfo *imageVariantSpecificInfo) optimizeProperties(ctx *memberContext, commonValueExtractor *commonValueExtractor) {
|
||||||
@@ -1798,6 +1857,10 @@ func (l *linkTypeSpecificInfo) addToPropertySet(ctx *memberContext, propertySet
|
|||||||
addSdkMemberPropertiesToSet(ctx, l.Properties, linkPropertySet)
|
addSdkMemberPropertiesToSet(ctx, l.Properties, linkPropertySet)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *linkTypeSpecificInfo) pruneUnsupportedProperties(pruner *propertyPruner) {
|
||||||
|
pruner.pruneProperties(l.Properties)
|
||||||
|
}
|
||||||
|
|
||||||
func (l *linkTypeSpecificInfo) String() string {
|
func (l *linkTypeSpecificInfo) String() string {
|
||||||
return fmt.Sprintf("LinkType{%s}", l.linkType)
|
return fmt.Sprintf("LinkType{%s}", l.linkType)
|
||||||
}
|
}
|
||||||
@@ -1837,12 +1900,12 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu
|
|||||||
memberType := member.memberType
|
memberType := member.memberType
|
||||||
|
|
||||||
// Do not add the prefer property if the member snapshot module is a source module type.
|
// Do not add the prefer property if the member snapshot module is a source module type.
|
||||||
|
config := ctx.sdkMemberContext.Config()
|
||||||
if !memberType.UsesSourceModuleTypeInSnapshot() {
|
if !memberType.UsesSourceModuleTypeInSnapshot() {
|
||||||
// Set the prefer based on the environment variable. This is a temporary work around to allow a
|
// 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.
|
// snapshot to be created that sets prefer: true.
|
||||||
// TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
|
// TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
|
||||||
// dynamically at build time not at snapshot generation time.
|
// dynamically at build time not at snapshot generation time.
|
||||||
config := ctx.sdkMemberContext.Config()
|
|
||||||
prefer := config.IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
|
prefer := config.IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
|
||||||
|
|
||||||
// Set prefer. Setting this to false is not strictly required as that is the default but it does
|
// Set prefer. Setting this to false is not strictly required as that is the default but it does
|
||||||
@@ -1884,6 +1947,11 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu
|
|||||||
commonProperties := variantPropertiesFactory()
|
commonProperties := variantPropertiesFactory()
|
||||||
commonProperties.Base().Os = android.CommonOS
|
commonProperties.Base().Os = android.CommonOS
|
||||||
|
|
||||||
|
// Create a property pruner that will prune any properties unsupported by the target build
|
||||||
|
// release.
|
||||||
|
targetBuildRelease := ctx.builder.targetBuildRelease
|
||||||
|
unsupportedPropertyPruner := newPropertyPrunerByBuildRelease(commonProperties, targetBuildRelease)
|
||||||
|
|
||||||
// Create common value extractor that can be used to optimize the properties.
|
// Create common value extractor that can be used to optimize the properties.
|
||||||
commonValueExtractor := newCommonValueExtractor(commonProperties)
|
commonValueExtractor := newCommonValueExtractor(commonProperties)
|
||||||
|
|
||||||
@@ -1898,6 +1966,8 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu
|
|||||||
// independent properties structs.
|
// independent properties structs.
|
||||||
osSpecificPropertiesContainers = append(osSpecificPropertiesContainers, osInfo)
|
osSpecificPropertiesContainers = append(osSpecificPropertiesContainers, osInfo)
|
||||||
|
|
||||||
|
osInfo.pruneUnsupportedProperties(unsupportedPropertyPruner)
|
||||||
|
|
||||||
// Optimize the properties across all the variants for a specific os type.
|
// Optimize the properties across all the variants for a specific os type.
|
||||||
osInfo.optimizeProperties(ctx, commonValueExtractor)
|
osInfo.optimizeProperties(ctx, commonValueExtractor)
|
||||||
}
|
}
|
||||||
|
@@ -163,6 +163,7 @@ var BannerVars = []string{
|
|||||||
"AUX_OS_VARIANT_LIST",
|
"AUX_OS_VARIANT_LIST",
|
||||||
"PRODUCT_SOONG_NAMESPACES",
|
"PRODUCT_SOONG_NAMESPACES",
|
||||||
"SOONG_SDK_SNAPSHOT_PREFER",
|
"SOONG_SDK_SNAPSHOT_PREFER",
|
||||||
|
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
|
||||||
"SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR",
|
"SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR",
|
||||||
"SOONG_SDK_SNAPSHOT_VERSION",
|
"SOONG_SDK_SNAPSHOT_VERSION",
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user