diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go index 12545d666..a13b0d7d0 100644 --- a/sdk/sdk_test.go +++ b/sdk/sdk_test.go @@ -564,4 +564,101 @@ sdk_snapshot { `), ) }) + + t.Run("SOONG_SDK_SNAPSHOT_VERSION=unversioned", func(t *testing.T) { + result := android.GroupFixturePreparers( + preparer, + android.FixtureMergeEnv(map[string]string{ + "SOONG_SDK_SNAPSHOT_VERSION": "unversioned", + }), + ).RunTest(t) + + checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk.zip") + + CheckSnapshot(t, result, "mysdk", "", + checkAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_import { + name: "myjavalib", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + jars: ["java/myjavalib.jar"], +} + `), + ) + }) + + t.Run("SOONG_SDK_SNAPSHOT_VERSION=current", func(t *testing.T) { + result := android.GroupFixturePreparers( + preparer, + android.FixtureMergeEnv(map[string]string{ + "SOONG_SDK_SNAPSHOT_VERSION": "current", + }), + ).RunTest(t) + + checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip") + + CheckSnapshot(t, result, "mysdk", "", + checkAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_import { + name: "mysdk_myjavalib@current", + sdk_member_name: "myjavalib", + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + jars: ["java/myjavalib.jar"], +} + +java_import { + name: "myjavalib", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + jars: ["java/myjavalib.jar"], +} + +sdk_snapshot { + name: "mysdk@current", + visibility: ["//visibility:public"], + java_header_libs: ["mysdk_myjavalib@current"], +} + `), + ) + }) + + t.Run("SOONG_SDK_SNAPSHOT_VERSION=2", func(t *testing.T) { + result := android.GroupFixturePreparers( + preparer, + android.FixtureMergeEnv(map[string]string{ + "SOONG_SDK_SNAPSHOT_VERSION": "2", + }), + ).RunTest(t) + + checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-2.zip") + + CheckSnapshot(t, result, "mysdk", "", + checkAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_import { + name: "mysdk_myjavalib@2", + sdk_member_name: "myjavalib", + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + jars: ["java/myjavalib.jar"], +} + +sdk_snapshot { + name: "mysdk@2", + visibility: ["//visibility:public"], + java_header_libs: ["mysdk_myjavalib@2"], +} + `), + // A versioned snapshot cannot be used on its own so add the source back in. + snapshotTestPreparer(checkSnapshotWithoutSource, android.FixtureWithRootAndroidBp(bp)), + ) + }) } diff --git a/sdk/testing.go b/sdk/testing.go index f4e85c0cf..3254cf9f3 100644 --- a/sdk/testing.go +++ b/sdk/testing.go @@ -131,6 +131,7 @@ func getSdkSnapshotBuildInfo(t *testing.T, result *android.TestResult, sdk *sdk) info := &snapshotBuildInfo{ t: t, r: result, + version: sdk.builderForTests.version, androidBpContents: sdk.GetAndroidBpContentsForTests(), androidUnversionedBpContents: sdk.GetUnversionedAndroidBpContentsForTests(), androidVersionedBpContents: sdk.GetVersionedAndroidBpContentsForTests(), @@ -236,8 +237,13 @@ func CheckSnapshot(t *testing.T, result *android.TestResult, name string, dir st if dir != "" { dir = filepath.Clean(dir) + "/" } - android.AssertStringEquals(t, "Snapshot zip file in wrong place", - fmt.Sprintf(".intermediates/%s%s/%s/%s-current.zip", dir, name, variant, name), actual) + suffix := "" + if snapshotBuildInfo.version != soongSdkSnapshotVersionUnversioned { + suffix = "-" + snapshotBuildInfo.version + } + + expectedZipPath := fmt.Sprintf(".intermediates/%s%s/%s/%s%s.zip", dir, name, variant, name, suffix) + android.AssertStringEquals(t, "Snapshot zip file in wrong place", expectedZipPath, actual) // Populate a mock filesystem with the files that would have been copied by // the rules. @@ -432,6 +438,11 @@ type snapshotBuildInfo struct { // The result from RunTest() r *android.TestResult + // The version of the generated snapshot. + // + // See snapshotBuilder.version for more information about this field. + version string + // The contents of the generated Android.bp file androidBpContents string diff --git a/sdk/update.go b/sdk/update.go index 85dfc4acf..36b564fe6 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -36,6 +36,20 @@ import ( // 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_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 -current.zip. +// +// SOONG_SDK_SNAPSHOT_VERSION=unversioned will generate unversioned prebuilts only and the zip +// file containing the generated snapshot will be .zip. +// +// SOONG_SDK_SNAPSHOT_VERSION= will generate versioned prebuilts and a versioned +// snapshot module only. The zip file containing the generated snapshot will be +// -.zip. +// var pctx = android.NewPackageContext("android/soong/sdk") @@ -69,6 +83,11 @@ var ( }) ) +const ( + soongSdkSnapshotVersionUnversioned = "unversioned" + soongSdkSnapshotVersionCurrent = "current" +) + type generatedContents struct { content strings.Builder indentLevel int @@ -257,10 +276,26 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro modules: make(map[string]*bpModule), } + 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 + + // 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 + snapshotZipFileSuffix := "" + if generateVersioned { + snapshotZipFileSuffix = "-" + version + } + builder := &snapshotBuilder{ ctx: ctx, sdk: s, - version: "current", + version: version, snapshotDir: snapshotDir.OutputPath, copies: make(map[string]string), filesToZip: []android.Path{bp.path}, @@ -314,20 +349,26 @@ be unnecessary as every module in the sdk already has its own licenses property. // Prune any empty property sets. unversioned = unversioned.transform(pruneEmptySetTransformer{}) - // Copy the unversioned module so it can be modified to make it versioned. - versioned := unversioned.deepCopy() + 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 unversioned module into a versioned one. + versioned.transform(unversionedToVersionedTransformer) + bpFile.AddModule(versioned) + } - // Transform the unversioned module to make it suitable for use in the snapshot. - unversioned.transform(unversionedTransformer) - bpFile.AddModule(unversioned) + if generateUnversioned { + // Transform the unversioned module to make it suitable for use in the snapshot. + unversioned.transform(unversionedTransformer) + bpFile.AddModule(unversioned) + } } - // Add the sdk/module_exports_snapshot module to the bp file. - s.addSnapshotModule(ctx, builder, sdkVariants, memberVariantDeps) + if generateVersioned { + // Add the sdk/module_exports_snapshot module to the bp file. + s.addSnapshotModule(ctx, builder, sdkVariants, memberVariantDeps) + } // generate Android.bp bp = newGeneratedFile(ctx, "snapshot", "Android.bp") @@ -341,7 +382,8 @@ be unnecessary as every module in the sdk already has its own licenses property. filesToZip := builder.filesToZip // zip them all - outputZipFile := android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.zip").OutputPath + zipPath := fmt.Sprintf("%s%s.zip", ctx.ModuleName(), snapshotZipFileSuffix) + outputZipFile := android.PathForModuleOut(ctx, zipPath).OutputPath outputDesc := "Building snapshot for " + ctx.ModuleName() // If there are no zips to merge then generate the output zip directly. @@ -353,7 +395,8 @@ be unnecessary as every module in the sdk already has its own licenses property. zipFile = outputZipFile desc = outputDesc } else { - zipFile = android.PathForModuleOut(ctx, ctx.ModuleName()+"-current.unmerged.zip").OutputPath + intermediatePath := fmt.Sprintf("%s%s.unmerged.zip", ctx.ModuleName(), snapshotZipFileSuffix) + zipFile = android.PathForModuleOut(ctx, intermediatePath).OutputPath desc = "Building intermediate snapshot for " + ctx.ModuleName() } @@ -801,9 +844,15 @@ func (s *sdk) GetVersionedAndroidBpContentsForTests() string { } type snapshotBuilder struct { - ctx android.ModuleContext - sdk *sdk - version string + 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 diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go index fe0aca983..54aeda082 100644 --- a/ui/build/dumpvars.go +++ b/ui/build/dumpvars.go @@ -162,6 +162,8 @@ var BannerVars = []string{ "OUT_DIR", "AUX_OS_VARIANT_LIST", "PRODUCT_SOONG_NAMESPACES", + "SOONG_SDK_SNAPSHOT_PREFER", + "SOONG_SDK_SNAPSHOT_VERSION", } func Banner(make_vars map[string]string) string {