From a326b320ab2b8b5cbad003571f3fccf1573b20a6 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Thu, 19 Sep 2024 21:02:52 +0000 Subject: [PATCH 1/8] Remove deapex support from java_*_import prebuilt_apex/apex_set currently supports its deapexed contents to be returned via a sibling java_import/java_sdk_import module. This is necesssary for 1. dexpreopt/hiddenapi processing 2. usage as shared library (1) is no longer necessary. this information is provided by the top-level prebuilt apexes now (2) is no longer possible since `exported_java_libs` has been removed in https://r.android.com/3272110 This CL uses a hack for java_sdk_library_improt. Even though (1) is provided by the top-level apex, there are still some places where dexpreopt/hiddenapi processing visits the import modules. This CL uses a bogus path to make analysis work. If this bogus path gets used, there will be an error during ninja execution Test: go test ./apex Test: in internal lunch cf_x86_64_phone-next-userdebug (uses mainline prebuilts) Test: verified that file_list.txt is same Bug: 368337090 Change-Id: I0ea2327f648f0fc60e337b232f7265e140772ffd --- apex/apex_test.go | 210 ------------------------- java/java.go | 39 +---- java/sdk_library.go | 38 +---- sdk/bootclasspath_fragment_sdk_test.go | 14 +- 4 files changed, 25 insertions(+), 276 deletions(-) diff --git a/apex/apex_test.go b/apex/apex_test.go index 0d5bad445..c45c1e42e 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -4907,23 +4907,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { }), ) - checkBootDexJarPath := func(t *testing.T, ctx *android.TestContext, stem string, bootDexJarPath string) { - t.Helper() - s := ctx.ModuleForTests("dex_bootjars", "android_common") - foundLibfooJar := false - base := stem + ".jar" - for _, output := range s.AllOutputs() { - if filepath.Base(output) == base { - foundLibfooJar = true - buildRule := s.Output(output) - android.AssertStringEquals(t, "boot dex jar path", bootDexJarPath, buildRule.Input.String()) - } - } - if !foundLibfooJar { - t.Errorf("Rule for libfoo.jar missing in dex_bootjars singleton outputs %q", android.StringPathsRelativeToTop(ctx.Config().SoongOutDir(), s.AllOutputs())) - } - } - checkHiddenAPIIndexFromClassesInputs := func(t *testing.T, ctx *android.TestContext, expectedIntermediateInputs string) { t.Helper() platformBootclasspath := ctx.ModuleForTests("platform-bootclasspath", "android_common") @@ -4996,8 +4979,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { ` ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) - checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar") - checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) @@ -5066,8 +5047,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { ` ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) - checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar") - checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) @@ -5259,8 +5238,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { ` ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) - checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar") - checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) @@ -5359,8 +5336,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { ` ctx := testDexpreoptWithApexes(t, bp, "", preparer, fragment) - checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/my-bootclasspath-fragment/android_common_myapex/hiddenapi-modular/encoded/libfoo.jar") - checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/my-bootclasspath-fragment/android_common_myapex/hiddenapi-modular/encoded/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) @@ -5472,8 +5447,6 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { ) ctx := testDexpreoptWithApexes(t, bp, "", preparer2, fragment) - checkBootDexJarPath(t, ctx, "libfoo", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libfoo.jar") - checkBootDexJarPath(t, ctx, "libbar", "out/soong/.intermediates/prebuilt_myapex.deapexer/android_common/deapexer/javalib/libbar.jar") // Verify the correct module jars contribute to the hiddenapi index file. checkHiddenAPIIndexFromClassesInputs(t, ctx, `out/soong/.intermediates/platform/foo/android_common/javac/foo.jar`) @@ -7973,189 +7946,6 @@ func testDexpreoptWithApexes(t *testing.T, bp, errmsg string, preparer android.F return result.TestContext } -func TestDuplicateDeapexersFromPrebuiltApexes(t *testing.T) { - preparers := android.GroupFixturePreparers( - java.PrepareForTestWithJavaDefaultModules, - prepareForTestWithBootclasspathFragment, - dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:libfoo"), - PrepareForTestWithApexBuildComponents, - ). - ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( - "Multiple installable prebuilt APEXes provide ambiguous deapexers: prebuilt_com.android.art and prebuilt_com.mycompany.android.art")) - - bpBase := ` - apex_set { - name: "com.android.art", - installable: true, - exported_bootclasspath_fragments: ["art-bootclasspath-fragment"], - set: "myapex.apks", - } - - apex_set { - name: "com.mycompany.android.art", - apex_name: "com.android.art", - installable: true, - exported_bootclasspath_fragments: ["art-bootclasspath-fragment"], - set: "company-myapex.apks", - } - - prebuilt_bootclasspath_fragment { - name: "art-bootclasspath-fragment", - apex_available: ["com.android.art"], - hidden_api: { - annotation_flags: "my-bootclasspath-fragment/annotation-flags.csv", - metadata: "my-bootclasspath-fragment/metadata.csv", - index: "my-bootclasspath-fragment/index.csv", - stub_flags: "my-bootclasspath-fragment/stub-flags.csv", - all_flags: "my-bootclasspath-fragment/all-flags.csv", - }, - %s - } - ` - - t.Run("java_import", func(t *testing.T) { - _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+` - java_import { - name: "libfoo", - jars: ["libfoo.jar"], - apex_available: ["com.android.art"], - } - `) - }) - - t.Run("java_sdk_library_import", func(t *testing.T) { - _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+` - java_sdk_library_import { - name: "libfoo", - public: { - jars: ["libbar.jar"], - }, - shared_library: false, - apex_available: ["com.android.art"], - } - `) - }) - - t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) { - _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, ` - image_name: "art", - contents: ["libfoo"], - `)+` - java_sdk_library_import { - name: "libfoo", - public: { - jars: ["libbar.jar"], - }, - shared_library: false, - apex_available: ["com.android.art"], - } - `) - }) -} - -func TestDuplicateButEquivalentDeapexersFromPrebuiltApexes(t *testing.T) { - preparers := android.GroupFixturePreparers( - java.PrepareForTestWithJavaDefaultModules, - PrepareForTestWithApexBuildComponents, - ) - - errCtx := moduleErrorfTestCtx{} - - bpBase := ` - apex_set { - name: "com.android.myapex", - installable: true, - exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], - set: "myapex.apks", - } - - apex_set { - name: "com.android.myapex_compressed", - apex_name: "com.android.myapex", - installable: true, - exported_bootclasspath_fragments: ["my-bootclasspath-fragment"], - set: "myapex_compressed.apks", - } - - prebuilt_bootclasspath_fragment { - name: "my-bootclasspath-fragment", - apex_available: [ - "com.android.myapex", - "com.android.myapex_compressed", - ], - hidden_api: { - annotation_flags: "annotation-flags.csv", - metadata: "metadata.csv", - index: "index.csv", - signature_patterns: "signature_patterns.csv", - }, - %s - } - ` - - t.Run("java_import", func(t *testing.T) { - result := preparers.RunTestWithBp(t, - fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+` - java_import { - name: "libfoo", - jars: ["libfoo.jar"], - apex_available: [ - "com.android.myapex", - "com.android.myapex_compressed", - ], - } - `) - - module := result.Module("libfoo", "android_common_com.android.myapex") - usesLibraryDep := module.(java.UsesLibraryDependency) - android.AssertPathRelativeToTopEquals(t, "dex jar path", - "out/soong/.intermediates/prebuilt_com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar", - usesLibraryDep.DexJarBuildPath(errCtx).Path()) - }) - - t.Run("java_sdk_library_import", func(t *testing.T) { - result := preparers.RunTestWithBp(t, - fmt.Sprintf(bpBase, `contents: ["libfoo"]`)+` - java_sdk_library_import { - name: "libfoo", - public: { - jars: ["libbar.jar"], - }, - apex_available: [ - "com.android.myapex", - "com.android.myapex_compressed", - ], - compile_dex: true, - } - `) - - module := result.Module("libfoo", "android_common_com.android.myapex") - usesLibraryDep := module.(java.UsesLibraryDependency) - android.AssertPathRelativeToTopEquals(t, "dex jar path", - "out/soong/.intermediates/prebuilt_com.android.myapex.deapexer/android_common/deapexer/javalib/libfoo.jar", - usesLibraryDep.DexJarBuildPath(errCtx).Path()) - }) - - t.Run("prebuilt_bootclasspath_fragment", func(t *testing.T) { - _ = preparers.RunTestWithBp(t, fmt.Sprintf(bpBase, ` - image_name: "art", - contents: ["libfoo"], - `)+` - java_sdk_library_import { - name: "libfoo", - public: { - jars: ["libbar.jar"], - }, - apex_available: [ - "com.android.myapex", - "com.android.myapex_compressed", - ], - compile_dex: true, - } - `) - }) -} - func TestUpdatable_should_set_min_sdk_version(t *testing.T) { testApexError(t, `"myapex" .*: updatable: updatable APEXes should set min_sdk_version`, ` apex { diff --git a/java/java.go b/java/java.go index d63bbe6e1..2863651d2 100644 --- a/java/java.go +++ b/java/java.go @@ -2818,41 +2818,14 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { } if ctx.Device() { - // If this is a variant created for a prebuilt_apex then use the dex implementation jar - // obtained from the associated deapexer module. + // Shared libraries deapexed from prebuilt apexes are no longer supported. + // Set the dexJarBuildPath to a fake path. + // This allows soong analysis pass, but will be an error during ninja execution if there are + // any rdeps. ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if ai.ForPrebuiltApex { - // Get the path of the dex implementation jar from the `deapexer` module. - di, err := android.FindDeapexerProviderForModule(ctx) - if err != nil { - // An error was found, possibly due to multiple apexes in the tree that export this library - // Defer the error till a client tries to call DexJarBuildPath - j.dexJarFileErr = err - j.initHiddenAPIError(err) - return - } - dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(j.BaseModuleName()) - if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil { - dexJarFile := makeDexJarPathFromPath(dexOutputPath) - j.dexJarFile = dexJarFile - installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, ApexRootRelativePathToJavaLib(j.BaseModuleName())) - j.dexJarInstallFile = installPath - - j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), installPath) - setUncompressDex(ctx, &j.dexpreopter, &j.dexer) - j.dexpreopter.uncompressedDex = *j.dexProperties.Uncompress_dex - - if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil { - j.dexpreopter.inputProfilePathOnHost = profilePath - } - - // Initialize the hiddenapi structure. - j.initHiddenAPI(ctx, dexJarFile, outputFile, j.dexProperties.Uncompress_dex) - } else { - // This should never happen as a variant for a prebuilt_apex is only created if the - // prebuilt_apex has been configured to export the java library dex file. - ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName()) - } + j.dexJarFile = makeDexJarPathFromPath(android.PathForModuleInstall(ctx, "intentionally_no_longer_supported")) + j.initHiddenAPI(ctx, j.dexJarFile, outputFile, j.dexProperties.Uncompress_dex) } else if Bool(j.dexProperties.Compile_dex) { sdkDep := decodeSdkDep(ctx, android.SdkContext(j)) if sdkDep.invalidVersion { diff --git a/java/sdk_library.go b/java/sdk_library.go index 9f0564a9c..f7cd8e16f 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2823,40 +2823,14 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo } if ctx.Device() { - // If this is a variant created for a prebuilt_apex then use the dex implementation jar - // obtained from the associated deapexer module. + // Shared libraries deapexed from prebuilt apexes are no longer supported. + // Set the dexJarBuildPath to a fake path. + // This allows soong analysis pass, but will be an error during ninja execution if there are + // any rdeps. ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if ai.ForPrebuiltApex { - // Get the path of the dex implementation jar from the `deapexer` module. - di, err := android.FindDeapexerProviderForModule(ctx) - if err != nil { - // An error was found, possibly due to multiple apexes in the tree that export this library - // Defer the error till a client tries to call DexJarBuildPath - module.dexJarFileErr = err - module.initHiddenAPIError(err) - return - } - dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(module.BaseModuleName()) - if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil { - dexJarFile := makeDexJarPathFromPath(dexOutputPath) - module.dexJarFile = dexJarFile - installPath := android.PathForModuleInPartitionInstall( - ctx, "apex", ai.ApexVariationName, dexJarFileApexRootRelative) - module.installFile = installPath - module.initHiddenAPI(ctx, dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) - - module.dexpreopter.installPath = module.dexpreopter.getInstallPath(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), installPath) - module.dexpreopter.isSDKLibrary = true - module.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()), &module.dexpreopter) - - if profilePath := di.PrebuiltExportPath(dexJarFileApexRootRelative + ".prof"); profilePath != nil { - module.dexpreopter.inputProfilePathOnHost = profilePath - } - } else { - // This should never happen as a variant for a prebuilt_apex is only created if the - // prebuilt_apex has been configured to export the java library dex file. - ctx.ModuleErrorf("internal error: no dex implementation jar available from prebuilt APEX %s", di.ApexModuleName()) - } + module.dexJarFile = makeDexJarPathFromPath(android.PathForModuleInstall(ctx, "intentionally_no_longer_supported")) + module.initHiddenAPI(ctx, module.dexJarFile, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) } } diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index 8b994eb64..9430d33f3 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -204,7 +204,19 @@ java_import { .intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core1.jar .intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/core2.jar `), - snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot), + snapshotTestPreparer(checkSnapshotWithoutSource, android.GroupFixturePreparers( + preparerForSnapshot, + // Flag ART prebuilts + android.FixtureMergeMockFs(android.MockFS{ + "apex_contributions/Android.bp": []byte(` + apex_contributions { + name: "prebuilt_art_contributions", + contents: ["prebuilt_com.android.art"], + api_domain: "com.android.art", + } + `)}), + android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"), + )), // Check the behavior of the snapshot without the source. snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) { From 52c01a1897f68e93bacfb2d7500ecc31f3bd3c61 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Fri, 20 Sep 2024 01:09:48 +0000 Subject: [PATCH 2/8] Remove internal deapexer module The build ations will be created by the top-level apex. Details 1. In GenerateAndroidBuildActions, do a graph walk to determine if the apex has exported deps. 2. If there are exported deps, call the newly introduced `deapex` function. This registers the build rules and returns a DeapexerInfo object. This was previously provided by the internal deapexer dependency. 3. Update `dexpreoptSystemServerJars and `provideApexExportsInfo` to use the DeapexerInfo object from (2). A lot of unit tests that relied on the legacy mechanism of deapexing have been updated. Test: go test ./apex Test: lunch cf_x86_64_phone-next-userdebug (uses mainline prebuilts) Test: verified no diff in file_list.txt Bug: 368337090 Change-Id: I0edb681beccac4d2a9ceb73f9a506c081a8a96e0 --- android/deapexer.go | 44 -------- apex/apex_test.go | 48 +++++---- apex/bootclasspath_fragment_test.go | 26 +++-- apex/deapexer.go | 84 ++------------- apex/dexpreopt_bootjars_test.go | 23 ++++- apex/prebuilt.go | 102 +++++++------------ apex/systemserver_classpath_fragment_test.go | 7 +- java/bootclasspath_fragment.go | 22 ++-- sdk/bootclasspath_fragment_sdk_test.go | 4 +- 9 files changed, 126 insertions(+), 234 deletions(-) diff --git a/android/deapexer.go b/android/deapexer.go index dcae3e46d..4049d2b2a 100644 --- a/android/deapexer.go +++ b/android/deapexer.go @@ -15,7 +15,6 @@ package android import ( - "fmt" "strings" "github.com/google/blueprint" @@ -109,10 +108,6 @@ func (i DeapexerInfo) GetExportedModuleNames() []string { return i.exportedModuleNames } -// Provider that can be used from within the `GenerateAndroidBuildActions` of a module that depends -// on a `deapexer` module to retrieve its `DeapexerInfo`. -var DeapexerProvider = blueprint.NewProvider[DeapexerInfo]() - // NewDeapexerInfo creates and initializes a DeapexerInfo that is suitable // for use with a prebuilt_apex module. // @@ -169,45 +164,6 @@ type RequiresFilesFromPrebuiltApexTag interface { RequiresFilesFromPrebuiltApex() } -// FindDeapexerProviderForModule searches through the direct dependencies of the current context -// module for a DeapexerTag dependency and returns its DeapexerInfo. If a single nonambiguous -// deapexer module isn't found then it returns it an error -// clients should check the value of error and call ctx.ModuleErrof if a non nil error is received -func FindDeapexerProviderForModule(ctx ModuleContext) (*DeapexerInfo, error) { - var di *DeapexerInfo - var err error - ctx.VisitDirectDepsWithTag(DeapexerTag, func(m Module) { - if err != nil { - // An err has been found. Do not visit further. - return - } - c, ok := OtherModuleProvider(ctx, m, DeapexerProvider) - if !ok { - ctx.ModuleErrorf("Expected all deps with DeapexerTag to have a DeapexerProvider, but module %q did not", m.Name()) - return - } - p := &c - if di != nil { - // If two DeapexerInfo providers have been found then check if they are - // equivalent. If they are then use the selected one, otherwise fail. - if selected := equivalentDeapexerInfoProviders(di, p); selected != nil { - di = selected - return - } - err = fmt.Errorf("Multiple installable prebuilt APEXes provide ambiguous deapexers: %s and %s", di.ApexModuleName(), p.ApexModuleName()) - } - di = p - }) - if err != nil { - return nil, err - } - if di != nil { - return di, nil - } - ai, _ := ModuleProvider(ctx, ApexInfoProvider) - return nil, fmt.Errorf("No prebuilt APEX provides a deapexer module for APEX variant %s", ai.ApexVariationName) -} - // removeCompressedApexSuffix removes the _compressed suffix from the name if present. func removeCompressedApexSuffix(name string) string { return strings.TrimSuffix(name, "_compressed") diff --git a/apex/apex_test.go b/apex/apex_test.go index c45c1e42e..0438a677e 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -3685,7 +3685,7 @@ func ensureExactContents(t *testing.T, ctx *android.TestContext, moduleName, var } func ensureExactDeapexedContents(t *testing.T, ctx *android.TestContext, moduleName string, variant string, files []string) { - deapexer := ctx.ModuleForTests(moduleName+".deapexer", variant).Description("deapex") + deapexer := ctx.ModuleForTests(moduleName, variant).Description("deapex") outputs := make([]string, 0, len(deapexer.ImplicitOutputs)+1) if deapexer.Output != nil { outputs = append(outputs, deapexer.Output.String()) @@ -4959,12 +4959,14 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { }, } - java_import { + java_sdk_library_import { name: "libfoo", - jars: ["libfoo.jar"], + public: { + jars: ["libfoo.jar"], + }, apex_available: ["myapex"], + shared_library: false, permitted_packages: ["foo"], - sdk_version: "core_current", } java_sdk_library_import { @@ -5018,13 +5020,17 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { apex_available: ["myapex"], } - java_import { + java_sdk_library_import { name: "libfoo", - jars: ["libfoo.jar"], + public: { + jars: ["libfoo.jar"], + }, apex_available: ["myapex"], - permitted_packages: ["foo"], + shared_library: false, + permitted_packages: ["libfoo"], } + java_sdk_library_import { name: "libbar", public: { @@ -5200,13 +5206,15 @@ func TestBootDexJarsFromSourcesAndPrebuilts(t *testing.T) { }, } - java_import { + java_sdk_library_import { name: "libfoo", prefer: true, - jars: ["libfoo.jar"], + public: { + jars: ["libfoo.jar"], + }, apex_available: ["myapex"], - permitted_packages: ["foo"], - sdk_version: "core_current", + shared_library: false, + permitted_packages: ["libfoo"], } java_library { @@ -8057,12 +8065,16 @@ func TestDexpreoptAccessDexFilesFromPrebuiltApex(t *testing.T) { }, } - java_import { - name: "libfoo", + java_sdk_library_import { + name: "libfoo", + prefer: true, + public: { jars: ["libfoo.jar"], - apex_available: ["myapex"], - permitted_packages: ["libfoo"], - } + }, + apex_available: ["myapex"], + shared_library: false, + permitted_packages: ["libfoo"], + } `, "", preparer, fragment) }) } @@ -10749,12 +10761,12 @@ func TestBootDexJarsMultipleApexPrebuilts(t *testing.T) { { desc: "Prebuilt apex prebuilt_com.android.foo is selected, profile should come from .prof deapexed from the prebuilt", selectedApexContributions: "foo.prebuilt.contributions", - expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo.deapexer/android_common/deapexer/javalib/framework-foo.jar", + expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo/android_common_com.android.foo/deapexer/javalib/framework-foo.jar", }, { desc: "Prebuilt apex prebuilt_com.android.foo.v2 is selected, profile should come from .prof deapexed from the prebuilt", selectedApexContributions: "foo.prebuilt.v2.contributions", - expectedBootJar: "out/soong/.intermediates/prebuilt_com.android.foo.v2.deapexer/android_common/deapexer/javalib/framework-foo.jar", + expectedBootJar: "out/soong/.intermediates/com.android.foo.v2/android_common_com.android.foo/deapexer/javalib/framework-foo.jar", }, } diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index df7857f29..a0bac9166 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -398,11 +398,20 @@ func TestBootclasspathFragmentInArtApex(t *testing.T) { // Make sure that a preferred prebuilt with consistent contents doesn't affect the apex. addPrebuilt(true, "foo", "bar"), + android.FixtureMergeMockFs(android.MockFS{ + "apex_contributions/Android.bp": []byte(` + apex_contributions { + name: "prebuilt_art_contributions", + contents: ["prebuilt_com.android.art"], + api_domain: "com.android.art", + } + `)}), + android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"), java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"), ).RunTest(t) - ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common", []string{ + ensureExactDeapexedContents(t, result.TestContext, "prebuilt_com.android.art", "android_common_com.android.art", []string{ "etc/boot-image.prof", "javalib/bar.jar", "javalib/foo.jar", @@ -495,6 +504,7 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { java.FixtureConfigureBootJars("com.android.art:foo", "com.android.art:bar"), dexpreopt.FixtureSetTestOnlyArtBootImageJars("com.android.art:foo", "com.android.art:bar"), java.FixtureSetBootImageInstallDirOnDevice("art", "apex/com.android.art/javalib"), + android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"), ) bp := ` @@ -552,6 +562,12 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { src: "com.mycompany.android.art.apex", exported_bootclasspath_fragments: ["art-bootclasspath-fragment"], } + + apex_contributions { + name: "prebuilt_art_contributions", + contents: ["prebuilt_com.android.art"], + api_domain: "com.android.art", + } ` t.Run("disabled alternative APEX", func(t *testing.T) { @@ -562,26 +578,18 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { `dex2oatd`, `prebuilt_art-bootclasspath-fragment`, `prebuilt_com.android.art.apex.selector`, - `prebuilt_com.android.art.deapexer`, }) java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{ `all_apex_contributions`, `dex2oatd`, `prebuilt_bar`, - `prebuilt_com.android.art.deapexer`, `prebuilt_foo`, }) module := result.ModuleForTests("dex_bootjars", "android_common") checkCopiesToPredefinedLocationForArt(t, result.Config, module, "bar", "foo") }) - - t.Run("enabled alternative APEX", func(t *testing.T) { - preparers.ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern( - "Multiple installable prebuilt APEXes provide ambiguous deapexers: prebuilt_com.android.art and prebuilt_com.mycompany.android.art")). - RunTestWithBp(t, fmt.Sprintf(bp, "")) - }) } // checkCopiesToPredefinedLocationForArt checks that the supplied modules are copied to the diff --git a/apex/deapexer.go b/apex/deapexer.go index a6731080c..3b8233d33 100644 --- a/apex/deapexer.go +++ b/apex/deapexer.go @@ -15,37 +15,9 @@ package apex import ( - "strings" - "android/soong/android" ) -// Contains 'deapexer' a private module type used by 'prebuilt_apex' to make dex files contained -// within a .apex file referenced by `prebuilt_apex` available for use by their associated -// `java_import` modules. -// -// An 'apex' module references `java_library` modules from which .dex files are obtained that are -// stored in the resulting `.apex` file. The resulting `.apex` file is then made available as a -// prebuilt by referencing it from a `prebuilt_apex`. For each such `java_library` that is used by -// modules outside the `.apex` file a `java_import` prebuilt is made available referencing a jar -// that contains the Java classes. -// -// When building a Java module type, e.g. `java_module` or `android_app` against such prebuilts the -// `java_import` provides the classes jar (jar containing `.class` files) against which the -// module's `.java` files are compiled. That classes jar usually contains only stub classes. The -// resulting classes jar is converted into a dex jar (jar containing `.dex` files). Then if -// necessary the dex jar is further processed by `dexpreopt` to produce an optimized form of the -// library specific to the current Android version. This process requires access to implementation -// dex jars for each `java_import`. The `java_import` will obtain the implementation dex jar from -// the `.apex` file in the associated `prebuilt_apex`. -// -// This is intentionally not registered by name as it is not intended to be used from within an -// `Android.bp` file. - -// DeapexerProperties specifies the properties supported by the deapexer module. -// -// As these are never intended to be supplied in a .bp file they use a different naming convention -// to make it clear that they are different. type DeapexerProperties struct { // List of common modules that may need access to files exported by this module. // @@ -72,46 +44,9 @@ type SelectedApexProperties struct { Selected_apex *string `android:"path" blueprint:"mutated"` } -type Deapexer struct { - android.ModuleBase - - properties DeapexerProperties - selectedApexProperties SelectedApexProperties - - inputApex android.Path -} - -// Returns the name of the deapexer module corresponding to an APEX module with the given name. -func deapexerModuleName(apexModuleName string) string { - return apexModuleName + ".deapexer" -} - -// Returns the name of the APEX module corresponding to an deapexer module with -// the given name. This reverses deapexerModuleName. -func apexModuleName(deapexerModuleName string) string { - return strings.TrimSuffix(deapexerModuleName, ".deapexer") -} - -func privateDeapexerFactory() android.Module { - module := &Deapexer{} - module.AddProperties(&module.properties, &module.selectedApexProperties) - android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) - return module -} - -func (p *Deapexer) DepsMutator(ctx android.BottomUpMutatorContext) { - // Add dependencies from the java modules to which this exports files from the `.apex` file onto - // this module so that they can access the `DeapexerInfo` object that this provides. - // TODO: b/308174306 - Once all the mainline modules have been flagged, drop this dependency edge - for _, lib := range p.properties.CommonModules { - dep := prebuiltApexExportedModuleName(ctx, lib) - ctx.AddReverseDependency(ctx.Module(), android.DeapexerTag, dep) - } -} - -func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) { - p.inputApex = android.OptionalPathForModuleSrc(ctx, p.selectedApexProperties.Selected_apex).Path() - +// deapex creates the build rules to deapex a prebuilt .apex file +// it returns a pointer to a DeapexerInfo object +func deapex(ctx android.ModuleContext, apexFile android.Path, deapexerProps DeapexerProperties) *android.DeapexerInfo { // Create and remember the directory into which the .apex file's contents will be unpacked. deapexerOutput := android.PathForModuleOut(ctx, "deapexer") @@ -119,7 +54,7 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Create mappings from apex relative path to the extracted file's path. exportedPaths := make(android.Paths, 0, len(exports)) - for _, path := range p.properties.ExportedFiles { + for _, path := range deapexerProps.ExportedFiles { // Populate the exports that this makes available. extractedPath := deapexerOutput.Join(ctx, path) exports[path] = extractedPath @@ -131,9 +66,8 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) { // apex relative path to extracted file path available for other modules. if len(exports) > 0 { // Make the information available for other modules. - di := android.NewDeapexerInfo(apexModuleName(ctx.ModuleName()), exports, p.properties.CommonModules) - di.AddDexpreoptProfileGuidedExportedModuleNames(p.properties.DexpreoptProfileGuidedModules...) - android.SetProvider(ctx, android.DeapexerProvider, di) + di := android.NewDeapexerInfo(ctx.ModuleName(), exports, deapexerProps.CommonModules) + di.AddDexpreoptProfileGuidedExportedModuleNames(deapexerProps.DexpreoptProfileGuidedModules...) // Create a sorted list of the files that this exports. exportedPaths = android.SortedUniquePaths(exportedPaths) @@ -147,11 +81,13 @@ func (p *Deapexer) GenerateAndroidBuildActions(ctx android.ModuleContext) { BuiltTool("deapexer"). BuiltTool("debugfs"). BuiltTool("fsck.erofs"). - Input(p.inputApex). + Input(apexFile). Text(deapexerOutput.String()) for _, p := range exportedPaths { command.Output(p.(android.WritablePath)) } - builder.Build("deapexer", "deapex "+apexModuleName(ctx.ModuleName())) + builder.Build("deapexer", "deapex "+ctx.ModuleName()) + return &di } + return nil } diff --git a/apex/dexpreopt_bootjars_test.go b/apex/dexpreopt_bootjars_test.go index d8ee4ba6c..4feade8ca 100644 --- a/apex/dexpreopt_bootjars_test.go +++ b/apex/dexpreopt_bootjars_test.go @@ -127,16 +127,29 @@ func testDexpreoptBoot(t *testing.T, ruleFile string, expectedInputs, expectedOu src: "com.android.art-arm.apex", exported_bootclasspath_fragments: ["art-bootclasspath-fragment"], } + + apex_contributions { + name: "prebuilt_art_contributions", + contents: ["prebuilt_com.android.art"], + api_domain: "com.android.art", + } ` - result := android.GroupFixturePreparers( + fixture := android.GroupFixturePreparers( java.PrepareForTestWithDexpreopt, java.PrepareForTestWithJavaSdkLibraryFiles, java.FixtureWithLastReleaseApis("foo"), java.FixtureConfigureBootJars("com.android.art:core-oj", "platform:foo", "system_ext:bar", "platform:baz"), PrepareForTestWithApexBuildComponents, prepareForTestWithArtApex, - ).RunTestWithBp(t, fmt.Sprintf(bp, preferPrebuilt)) + ) + if preferPrebuilt { + fixture = android.GroupFixturePreparers( + fixture, + android.PrepareForTestWithBuildFlag("RELEASE_APEX_CONTRIBUTIONS_ART", "prebuilt_art_contributions"), + ) + } + result := fixture.RunTestWithBp(t, fmt.Sprintf(bp, preferPrebuilt)) dexBootJars := result.ModuleForTests("dex_bootjars", "android_common") rule := dexBootJars.Output(ruleFile) @@ -200,7 +213,7 @@ func TestDexpreoptBootJarsWithPrebuiltArtApex(t *testing.T) { "out/soong/dexpreopt_arm64/dex_bootjars_input/foo.jar", "out/soong/dexpreopt_arm64/dex_bootjars_input/bar.jar", "out/soong/dexpreopt_arm64/dex_bootjars_input/baz.jar", - "out/soong/.intermediates/prebuilt_com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof", + "out/soong/.intermediates/prebuilt_com.android.art/android_common_com.android.art/deapexer/etc/boot-image.prof", "out/soong/.intermediates/default/java/dex_bootjars/android_common/boot/boot.prof", "out/soong/dexpreopt/uffd_gc_flag.txt", } @@ -384,12 +397,12 @@ func TestDexpreoptProfileWithMultiplePrebuiltArtApexes(t *testing.T) { { desc: "Prebuilt apex prebuilt_com.android.art is selected, profile should come from .prof deapexed from the prebuilt", selectedArtApexContributions: "art.prebuilt.contributions", - expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art.deapexer/android_common/deapexer/etc/boot-image.prof", + expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art/android_common_com.android.art/deapexer/etc/boot-image.prof", }, { desc: "Prebuilt apex prebuilt_com.android.art.v2 is selected, profile should come from .prof deapexed from the prebuilt", selectedArtApexContributions: "art.prebuilt.v2.contributions", - expectedProfile: "out/soong/.intermediates/prebuilt_com.android.art.v2.deapexer/android_common/deapexer/etc/boot-image.prof", + expectedProfile: "out/soong/.intermediates/com.android.art.v2/android_common_com.android.art/deapexer/etc/boot-image.prof", }, } for _, tc := range testCases { diff --git a/apex/prebuilt.go b/apex/prebuilt.go index f6f3efbfb..148ccc489 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -194,9 +194,8 @@ func (p *prebuiltCommon) initApexFilesForAndroidMk(ctx android.ModuleContext) { } // If this prebuilt has system server jar, create the rules to dexpreopt it and install it alongside the prebuilt apex -func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext) { - // If this apex does not export anything, return - if !p.hasExportedDeps() { +func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext, di *android.DeapexerInfo) { + if di == nil { return } // If this prebuilt apex has not been selected, return @@ -205,10 +204,7 @@ func (p *prebuiltCommon) dexpreoptSystemServerJars(ctx android.ModuleContext) { } // Use apex_name to determine the api domain of this prebuilt apex apexName := p.ApexVariationName() - di, err := android.FindDeapexerProviderForModule(ctx) - if err != nil { - ctx.ModuleErrorf(err.Error()) - } + // TODO: do not compute twice dc := dexpreopt.GetGlobalConfig(ctx) systemServerJarList := dc.AllApexSystemServerJars(ctx) @@ -545,17 +541,7 @@ func createApexSelectorModule(ctx android.BottomUpMutatorContext, name string, a ) } -// createDeapexerModuleIfNeeded will create a deapexer module if it is needed. -// -// A deapexer module is only needed when the prebuilt apex specifies one or more modules in either -// the `exported_bootclasspath_fragments` properties as that indicates that -// the listed modules need access to files from within the prebuilt .apex file. -func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.BottomUpMutatorContext, deapexerName string, apexFileSource string) { - // Only create the deapexer module if it is needed. - if !p.hasExportedDeps() { - return - } - +func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext) DeapexerProperties { // Compute the deapexer properties from the transitive dependencies of this module. commonModules := []string{} dexpreoptProfileGuidedModules := []string{} @@ -589,7 +575,7 @@ func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.BottomUpMutato }) // Create properties for deapexer module. - deapexerProperties := &DeapexerProperties{ + deapexerProperties := DeapexerProperties{ // Remove any duplicates from the common modules lists as a module may be included via a direct // dependency as well as transitive ones. CommonModules: android.SortedUniqueStrings(commonModules), @@ -598,18 +584,7 @@ func (p *prebuiltCommon) createDeapexerModuleIfNeeded(ctx android.BottomUpMutato // Populate the exported files property in a fixed order. deapexerProperties.ExportedFiles = android.SortedUniqueStrings(exportedFiles) - - props := struct { - Name *string - Selected_apex *string - }{ - Name: proptools.StringPtr(deapexerName), - Selected_apex: proptools.StringPtr(apexFileSource), - } - ctx.CreateModule(privateDeapexerFactory, - &props, - deapexerProperties, - ) + return deapexerProperties } func apexSelectorModuleName(baseModuleName string) string { @@ -661,6 +636,7 @@ var ( var _ prebuiltApexModuleCreator = (*Prebuilt)(nil) +// DEPRECATED: This dependency graph is being removed. // createPrebuiltApexModules creates modules necessary to export files from the prebuilt apex to the // build. // @@ -696,7 +672,6 @@ func (p *Prebuilt) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties) apexFileSource := ":" + apexSelectorModuleName - p.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(p.Name()), apexFileSource) // Add a source reference to retrieve the selected apex from the selector module. p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) @@ -706,45 +681,43 @@ func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { p.prebuiltApexContentsDeps(ctx) } -func (p *prebuiltCommon) DepsMutator(ctx android.BottomUpMutatorContext) { - if p.hasExportedDeps() { - // Create a dependency from the prebuilt apex (prebuilt_apex/apex_set) to the internal deapexer module - // The deapexer will return a provider which will be used to determine the exported artfifacts from this prebuilt. - ctx.AddDependency(ctx.Module(), android.DeapexerTag, deapexerModuleName(p.Name())) - } -} - var _ ApexInfoMutator = (*Prebuilt)(nil) func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) { p.apexInfoMutator(mctx) } +// creates the build rules to deapex the prebuilt, and returns a deapexerInfo +func (p *prebuiltCommon) getDeapexerInfo(ctx android.ModuleContext) *android.DeapexerInfo { + if !p.hasExportedDeps() { + // nothing to do + return nil + } + apexFile := android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path() + deapexerProps := p.getDeapexerPropertiesIfNeeded(ctx) + return deapex(ctx, apexFile, deapexerProps) +} + // Set a provider containing information about the jars and .prof provided by the apex // Apexes built from prebuilts retrieve this information by visiting its internal deapexer module // Used by dex_bootjars to generate the boot image -func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext) { - if !p.hasExportedDeps() { - // nothing to do +func (p *prebuiltCommon) provideApexExportsInfo(ctx android.ModuleContext, di *android.DeapexerInfo) { + if di == nil { return } - if di, err := android.FindDeapexerProviderForModule(ctx); err == nil { - javaModuleToDexPath := map[string]android.Path{} - for _, commonModule := range di.GetExportedModuleNames() { - if dex := di.PrebuiltExportPath(java.ApexRootRelativePathToJavaLib(commonModule)); dex != nil { - javaModuleToDexPath[commonModule] = dex - } + javaModuleToDexPath := map[string]android.Path{} + for _, commonModule := range di.GetExportedModuleNames() { + if dex := di.PrebuiltExportPath(java.ApexRootRelativePathToJavaLib(commonModule)); dex != nil { + javaModuleToDexPath[commonModule] = dex } - - exports := android.ApexExportsInfo{ - ApexName: p.ApexVariationName(), - ProfilePathOnHost: di.PrebuiltExportPath(java.ProfileInstallPathInApex), - LibraryNameToDexJarPathOnHost: javaModuleToDexPath, - } - android.SetProvider(ctx, android.ApexExportsInfoProvider, exports) - } else { - ctx.ModuleErrorf(err.Error()) } + + exports := android.ApexExportsInfo{ + ApexName: p.ApexVariationName(), + ProfilePathOnHost: di.PrebuiltExportPath(java.ProfileInstallPathInApex), + LibraryNameToDexJarPathOnHost: javaModuleToDexPath, + } + android.SetProvider(ctx, android.ApexExportsInfoProvider, exports) } // Set prebuiltInfoProvider. This will be used by `apex_prebuiltinfo_singleton` to print out a metadata file @@ -798,11 +771,13 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { return } + deapexerInfo := p.getDeapexerInfo(ctx) + // dexpreopt any system server jars if present - p.dexpreoptSystemServerJars(ctx) + p.dexpreoptSystemServerJars(ctx, deapexerInfo) // provide info used for generating the boot image - p.provideApexExportsInfo(ctx) + p.provideApexExportsInfo(ctx, deapexerInfo) p.providePrebuiltInfo(ctx) @@ -977,7 +952,6 @@ func (a *ApexSet) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties) apexFileSource := ":" + apexExtractorModuleName - a.createDeapexerModuleIfNeeded(ctx, deapexerModuleName(a.Name()), apexFileSource) // After passing the arch specific src properties to the creating the apex selector module a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) @@ -1024,11 +998,13 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { return } + deapexerInfo := a.getDeapexerInfo(ctx) + // dexpreopt any system server jars if present - a.dexpreoptSystemServerJars(ctx) + a.dexpreoptSystemServerJars(ctx, deapexerInfo) // provide info used for generating the boot image - a.provideApexExportsInfo(ctx) + a.provideApexExportsInfo(ctx, deapexerInfo) a.providePrebuiltInfo(ctx) diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go index fd9020b7f..ac119a587 100644 --- a/apex/systemserver_classpath_fragment_test.go +++ b/apex/systemserver_classpath_fragment_test.go @@ -278,7 +278,6 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { `all_apex_contributions`, `dex2oatd`, `prebuilt_myapex.apex.selector`, - `prebuilt_myapex.deapexer`, `prebuilt_mysystemserverclasspathfragment`, }) @@ -286,10 +285,9 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { `all_apex_contributions`, `prebuilt_bar`, `prebuilt_foo`, - `prebuilt_myapex.deapexer`, }) - ensureExactDeapexedContents(t, ctx, "prebuilt_myapex", "android_common", []string{ + ensureExactDeapexedContents(t, ctx, "myapex", "android_common_myapex", []string{ "javalib/foo.jar", "javalib/bar.jar", "javalib/bar.jar.prof", @@ -439,10 +437,9 @@ func TestPrebuiltStandaloneSystemserverclasspathFragmentContents(t *testing.T) { `all_apex_contributions`, `prebuilt_bar`, `prebuilt_foo`, - `prebuilt_myapex.deapexer`, }) - ensureExactDeapexedContents(t, ctx, "prebuilt_myapex", "android_common", []string{ + ensureExactDeapexedContents(t, ctx, "myapex", "android_common_myapex", []string{ "javalib/foo.jar", "javalib/bar.jar", "javalib/bar.jar.prof", diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index fe4cc7685..4fcd40bd3 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -414,6 +414,12 @@ func (b *BootclasspathFragmentModule) DepIsInSameApex(ctx android.BaseModuleCont // Cross-cutting metadata dependencies are metadata. return false } + // Dependency to the bootclasspath fragment of another apex + // e.g. concsrypt-bootclasspath-fragment --> art-bootclasspath-fragment + if tag == bootclasspathFragmentDepTag { + return false + + } panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag))) } @@ -1099,22 +1105,10 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an return &output } +// DEPRECATED: this information is now generated in the context of the top level prebuilt apex. // produceBootImageProfile extracts the boot image profile from the APEX if available. func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx android.ModuleContext) android.WritablePath { - // This module does not provide a boot image profile. - if module.getProfileProviderApex(ctx) == "" { - return nil - } - - di, err := android.FindDeapexerProviderForModule(ctx) - if err != nil { - // An error was found, possibly due to multiple apexes in the tree that export this library - // Defer the error till a client tries to call getProfilePath - module.profilePathErr = err - return nil // An error has been reported by FindDeapexerProviderForModule. - } - - return di.PrebuiltExportPath(ProfileInstallPathInApex) + return android.PathForModuleInstall(ctx, "intentionally_no_longer_supported") } func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path { diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index 9430d33f3..39c81235e 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -224,8 +224,8 @@ java_import { checkBootJarsPackageCheckRule(t, result, append( []string{ - "out/soong/.intermediates/prebuilts/apex/prebuilt_com.android.art.deapexer/android_common/deapexer/javalib/core1.jar", - "out/soong/.intermediates/prebuilts/apex/prebuilt_com.android.art.deapexer/android_common/deapexer/javalib/core2.jar", + "out/soong/.intermediates/prebuilts/apex/com.android.art/android_common_com.android.art/deapexer/javalib/core1.jar", + "out/soong/.intermediates/prebuilts/apex/com.android.art/android_common_com.android.art/deapexer/javalib/core2.jar", "out/soong/.intermediates/default/java/framework/android_common/aligned/framework.jar", }, java.ApexBootJarDexJarPaths..., From 9cf2e8e1403b5e057aca10870080adbe3e621f83 Mon Sep 17 00:00:00 2001 From: Zhi Dou Date: Mon, 23 Sep 2024 16:49:48 +0000 Subject: [PATCH 3/8] pass read new storage parameter to java codegen When RELEASE_READ_FROM_NEW_STORAGE is true, enable reading from new storage. So that we can ensure nextfood is not impacted. Test: m and check cf Bug: 349874828 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:c98032785339de11e34ee3d4f94b3ec3ed70d324) Merged-In: Id12816206a16b17c23e3a53832d268f1600107b3 Change-Id: I95ad9457e6d9c07a5a5b3074045a383f004113a9 --- aconfig/codegen/init.go | 3 ++- aconfig/codegen/java_aconfig_library.go | 5 ++++- java/testing.go | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go index 98d288f0a..ed0b3ed7f 100644 --- a/aconfig/codegen/init.go +++ b/aconfig/codegen/init.go @@ -32,6 +32,7 @@ var ( ` --mode ${mode}` + ` --cache ${in}` + ` --out ${out}.tmp` + + ` --allow-instrumentation ${debug}` + ` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` + ` && rm -rf ${out}.tmp`, CommandDeps: []string{ @@ -39,7 +40,7 @@ var ( "$soong_zip", }, Restat: true, - }, "mode") + }, "mode", "debug") // For cc_aconfig_library: Generate C++ library cppRule = pctx.AndroidStaticRule("cc_aconfig_library", diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index 673ac2afe..ebca4134c 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -20,6 +20,7 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/proptools" + "strconv" ) type declarationsTagType struct { @@ -71,6 +72,7 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) DepsMutator(module *ja module.AddSharedLibrary("aconfig-annotations-lib") // TODO(b/303773055): Remove the annotation after access issue is resolved. module.AddSharedLibrary("unsupportedappusage") + module.AddSharedLibrary("aconfig_storage_reader_java") } } @@ -102,7 +104,8 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild Output: srcJarPath, Description: "aconfig.srcjar", Args: map[string]string{ - "mode": mode, + "mode": mode, + "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()), }, }) diff --git a/java/testing.go b/java/testing.go index 0c79e9f7e..6cc9fd125 100644 --- a/java/testing.go +++ b/java/testing.go @@ -424,7 +424,9 @@ func gatherRequiredDepsForTest() string { "kotlin-stdlib-jdk8", "kotlin-annotations", "stub-annotations", + "aconfig-annotations-lib", + "aconfig_storage_reader_java", "unsupportedappusage", } From e350e36e7ba345ea37cc6818dd27ed816d0072ad Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Sat, 21 Sep 2024 01:49:34 +0000 Subject: [PATCH 4/8] Remove the internal selector module created by prebuilt_apex Since the deapex actions have been moved to the top-level apex, this internal module is no longer neessary. Test: go test ./apex Test: lunch cf_x86_64_phone-next-userdebug (uses mainline prebuilts) Test: verified no diff in file_list.txt Bug: 368337090 Change-Id: I53695e028a36a689fd1b026f5783de7d8567be76 --- apex/bootclasspath_fragment_test.go | 1 - apex/prebuilt.go | 112 +++---------------- apex/systemserver_classpath_fragment_test.go | 1 - 3 files changed, 15 insertions(+), 99 deletions(-) diff --git a/apex/bootclasspath_fragment_test.go b/apex/bootclasspath_fragment_test.go index a0bac9166..e44d3f552 100644 --- a/apex/bootclasspath_fragment_test.go +++ b/apex/bootclasspath_fragment_test.go @@ -577,7 +577,6 @@ func TestBootclasspathFragmentInPrebuiltArtApex(t *testing.T) { `all_apex_contributions`, `dex2oatd`, `prebuilt_art-bootclasspath-fragment`, - `prebuilt_com.android.art.apex.selector`, }) java.CheckModuleDependencies(t, result.TestContext, "art-bootclasspath-fragment", "android_common_com.android.art", []string{ diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 148ccc489..34a7e9adf 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -399,34 +399,6 @@ func (p *prebuiltCommon) apexInfoMutator(mctx android.TopDownMutatorContext) { } } -// prebuiltApexSelectorModule is a private module type that is only created by the prebuilt_apex -// module. It selects the apex to use and makes it available for use by prebuilt_apex and the -// deapexer. -type prebuiltApexSelectorModule struct { - android.ModuleBase - - apexFileProperties ApexFileProperties - - inputApex android.Path -} - -func privateApexSelectorModuleFactory() android.Module { - module := &prebuiltApexSelectorModule{} - module.AddProperties( - &module.apexFileProperties, - ) - android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) - return module -} - -func (p *prebuiltApexSelectorModule) Srcs() android.Paths { - return android.Paths{p.inputApex} -} - -func (p *prebuiltApexSelectorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { - p.inputApex = android.SingleSourcePathFromSupplier(ctx, p.apexFileProperties.prebuiltApexSelector, "src") -} - type Prebuilt struct { prebuiltCommon @@ -469,11 +441,11 @@ type ApexFileProperties struct { // to use methods on it that are specific to the current module. // // See the ApexFileProperties.Src property. -func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext, prebuilt android.Module) []string { +func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext, prebuilt android.Module) string { multiTargets := prebuilt.MultiTargets() if len(multiTargets) != 1 { ctx.OtherModuleErrorf(prebuilt, "compile_multilib shouldn't be \"both\" for prebuilt_apex") - return nil + return "" } var src string switch multiTargets[0].Arch.ArchType { @@ -506,7 +478,7 @@ func (p *ApexFileProperties) prebuiltApexSelector(ctx android.BaseModuleContext, // logic from reporting a more general, less useful message. } - return []string{src} + return src } type PrebuiltProperties struct { @@ -523,24 +495,18 @@ func (a *Prebuilt) hasSanitizedSource(sanitizer string) bool { func PrebuiltFactory() android.Module { module := &Prebuilt{} module.AddProperties(&module.properties) - module.initPrebuiltCommon(module, &module.properties.PrebuiltCommonProperties) + module.prebuiltCommon.prebuiltCommonProperties = &module.properties.PrebuiltCommonProperties + + // init the module as a prebuilt + // even though this module type has srcs, use `InitPrebuiltModuleWithoutSrcs`, since the existing + // InitPrebuiltModule* are not friendly with Sources of Configurable type. + // The actual src will be evaluated in GenerateAndroidBuildActions. + android.InitPrebuiltModuleWithoutSrcs(module) + android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) return module } -func createApexSelectorModule(ctx android.BottomUpMutatorContext, name string, apexFileProperties *ApexFileProperties) { - props := struct { - Name *string - }{ - Name: proptools.StringPtr(name), - } - - ctx.CreateModule(privateApexSelectorModuleFactory, - &props, - apexFileProperties, - ) -} - func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext) DeapexerProperties { // Compute the deapexer properties from the transitive dependencies of this module. commonModules := []string{} @@ -587,10 +553,6 @@ func (p *prebuiltCommon) getDeapexerPropertiesIfNeeded(ctx android.ModuleContext return deapexerProperties } -func apexSelectorModuleName(baseModuleName string) string { - return baseModuleName + ".apex.selector" -} - func prebuiltApexExportedModuleName(ctx android.BottomUpMutatorContext, name string) string { // The prebuilt_apex should be depending on prebuilt modules but as this runs after // prebuilt_rename the prebuilt module may or may not be using the prebuilt_ prefixed named. So, @@ -634,49 +596,6 @@ var ( exportedSystemserverclasspathFragmentTag = exportedDependencyTag{name: "exported_systemserverclasspath_fragments"} ) -var _ prebuiltApexModuleCreator = (*Prebuilt)(nil) - -// DEPRECATED: This dependency graph is being removed. -// createPrebuiltApexModules creates modules necessary to export files from the prebuilt apex to the -// build. -// -// If this needs to make files from within a `.apex` file available for use by other Soong modules, -// e.g. make dex implementation jars available for `contents` listed in exported_bootclasspath_fragments, -// it does so as follows: -// -// 1. It creates a `deapexer` module that actually extracts the files from the `.apex` file and -// makes them available for use by other modules, at both Soong and ninja levels. -// -// 2. It adds a dependency onto those modules and creates an apex specific variant similar to what -// an `apex` module does. That ensures that code which looks for specific apex variant, e.g. -// dexpreopt, will work the same way from source and prebuilt. -// -// 3. The `deapexer` module adds a dependency from the modules that require the exported files onto -// itself so that they can retrieve the file paths to those files. -// -// It also creates a child module `selector` that is responsible for selecting the appropriate -// input apex for both the prebuilt_apex and the deapexer. That is needed for a couple of reasons: -// -// 1. To dedup the selection logic so it only runs in one module. -// -// 2. To allow the deapexer to be wired up to a different source for the input apex, e.g. an -// `apex_set`. -// -// prebuilt_apex -// / | \ -// / | \ -// V V V -// selector <--- deapexer <--- exported java lib -func (p *Prebuilt) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) { - apexSelectorModuleName := apexSelectorModuleName(p.Name()) - createApexSelectorModule(ctx, apexSelectorModuleName, &p.properties.ApexFileProperties) - - apexFileSource := ":" + apexSelectorModuleName - - // Add a source reference to retrieve the selected apex from the selector module. - p.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) -} - func (p *Prebuilt) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { p.prebuiltApexContentsDeps(ctx) } @@ -688,12 +607,11 @@ func (p *Prebuilt) ApexInfoMutator(mctx android.TopDownMutatorContext) { } // creates the build rules to deapex the prebuilt, and returns a deapexerInfo -func (p *prebuiltCommon) getDeapexerInfo(ctx android.ModuleContext) *android.DeapexerInfo { +func (p *prebuiltCommon) getDeapexerInfo(ctx android.ModuleContext, apexFile android.Path) *android.DeapexerInfo { if !p.hasExportedDeps() { // nothing to do return nil } - apexFile := android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path() deapexerProps := p.getDeapexerPropertiesIfNeeded(ctx) return deapex(ctx, apexFile, deapexerProps) } @@ -753,7 +671,7 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { p.apexKeysPath = writeApexKeys(ctx, p) // TODO(jungjw): Check the key validity. - p.inputApex = android.OptionalPathForModuleSrc(ctx, p.prebuiltCommonProperties.Selected_apex).Path() + p.inputApex = android.PathForModuleSrc(ctx, p.properties.prebuiltApexSelector(ctx, ctx.Module())) p.installDir = android.PathForModuleInstall(ctx, "apex") p.installFilename = p.InstallFilename() if !strings.HasSuffix(p.installFilename, imageApexSuffix) { @@ -771,7 +689,7 @@ func (p *Prebuilt) GenerateAndroidBuildActions(ctx android.ModuleContext) { return } - deapexerInfo := p.getDeapexerInfo(ctx) + deapexerInfo := p.getDeapexerInfo(ctx, p.inputApex) // dexpreopt any system server jars if present p.dexpreoptSystemServerJars(ctx, deapexerInfo) @@ -998,7 +916,7 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { return } - deapexerInfo := a.getDeapexerInfo(ctx) + deapexerInfo := a.getDeapexerInfo(ctx, inputApex) // dexpreopt any system server jars if present a.dexpreoptSystemServerJars(ctx, deapexerInfo) diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go index ac119a587..acb364973 100644 --- a/apex/systemserver_classpath_fragment_test.go +++ b/apex/systemserver_classpath_fragment_test.go @@ -277,7 +277,6 @@ func TestPrebuiltSystemserverclasspathFragmentContents(t *testing.T) { java.CheckModuleDependencies(t, ctx, "myapex", "android_common_myapex", []string{ `all_apex_contributions`, `dex2oatd`, - `prebuilt_myapex.apex.selector`, `prebuilt_mysystemserverclasspathfragment`, }) From 9d6e209f44696f4813b528350846f7adb794cb5f Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Sat, 21 Sep 2024 02:50:00 +0000 Subject: [PATCH 5/8] Remove the internal extractor module created by apex_set The build actions will be generated by the top-level apex. Test: go test ./apex Test: lunch cf_x86_64_phone-next-userdebug (uses mainline prebuilts) Test: verified no diff in file_list.txt Bug: 368337090 Change-Id: I170cf4beec18b54cd950560ea0991bc6f1455d76 --- apex/apex_test.go | 12 +++---- apex/prebuilt.go | 92 ++++++++++++++++------------------------------- 2 files changed, 36 insertions(+), 68 deletions(-) diff --git a/apex/apex_test.go b/apex/apex_test.go index 7fd9d8743..1f4e5eafa 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -7862,9 +7862,9 @@ func TestAppSetBundlePrebuilt(t *testing.T) { ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress) // Check that the extractor produces the correct output file from the correct input file. - extractorOutput := "out/soong/.intermediates/prebuilt_myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks" + extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.hwasan.apks" - m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common") + m := ctx.ModuleForTests("myapex", "android_common_myapex") extractedApex := m.Output(extractorOutput) android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings()) @@ -7889,10 +7889,10 @@ func TestApexSetApksModuleAssignment(t *testing.T) { } `) - m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common") + m := ctx.ModuleForTests("myapex", "android_common_myapex") // Check that the extractor produces the correct apks file from the input module - extractorOutput := "out/soong/.intermediates/prebuilt_myapex.apex.extractor/android_common/extracted/myapex.apks" + extractorOutput := "out/soong/.intermediates/myapex/android_common_myapex/extracted/myapex.apks" extractedApex := m.Output(extractorOutput) android.AssertArrayString(t, "extractor input", []string{"myapex.apks"}, extractedApex.Inputs.Strings()) @@ -8454,7 +8454,7 @@ func TestApexSet(t *testing.T) { }), ) - m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common") + m := ctx.ModuleForTests("myapex", "android_common_myapex") // Check extract_apks tool parameters. extractedApex := m.Output("extracted/myapex.apks") @@ -8495,7 +8495,7 @@ func TestApexSet_NativeBridge(t *testing.T) { }), ) - m := ctx.ModuleForTests("prebuilt_myapex.apex.extractor", "android_common") + m := ctx.ModuleForTests("myapex", "android_common_myapex") // Check extract_apks tool parameters. No native bridge arch expected extractedApex := m.Output("extracted/myapex.apks") diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 34a7e9adf..d3f14f9c0 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -253,6 +253,8 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries { return entriesList } +// DEPRECATED. // TODO (spandandas): Remove this interface. + // prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and // apex_set in order to create the modules needed to provide access to the prebuilt .apex file. type prebuiltApexModuleCreator interface { @@ -731,26 +733,11 @@ type prebuiltApexExtractorModule struct { extractedApex android.WritablePath } -func privateApexExtractorModuleFactory() android.Module { - module := &prebuiltApexExtractorModule{} - module.AddProperties( - &module.properties, - ) - android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) - return module -} - -func (p *prebuiltApexExtractorModule) Srcs() android.Paths { - return android.Paths{p.extractedApex} -} - -func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { - srcsSupplier := func(ctx android.BaseModuleContext, prebuilt android.Module) []string { - return p.properties.prebuiltSrcs(ctx) - } +// extract registers the build actions to extract an apex from .apks file +// returns the path of the extracted apex +func extract(ctx android.ModuleContext, apexSet android.Path, prerelease *bool) android.Path { defaultAllowPrerelease := ctx.Config().IsEnvTrue("SOONG_ALLOW_PRERELEASE_APEXES") - apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set") - p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base()) + extractedApex := android.PathForModuleOut(ctx, "extracted", apexSet.Base()) // Filter out NativeBridge archs (b/260115309) abis := java.SupportedAbis(ctx, true) ctx.Build(pctx, @@ -758,14 +745,16 @@ func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.Mo Rule: extractMatchingApex, Description: "Extract an apex from an apex set", Inputs: android.Paths{apexSet}, - Output: p.extractedApex, + Output: extractedApex, Args: map[string]string{ "abis": strings.Join(abis, ","), - "allow-prereleased": strconv.FormatBool(proptools.BoolDefault(p.properties.Prerelease, defaultAllowPrerelease)), + "allow-prereleased": strconv.FormatBool(proptools.BoolDefault(prerelease, defaultAllowPrerelease)), "sdk-version": ctx.Config().PlatformSdkVersion().String(), "skip-sdk-check": strconv.FormatBool(ctx.Config().IsEnvTrue("SOONG_SKIP_APPSET_SDK_CHECK")), }, - }) + }, + ) + return extractedApex } type ApexSet struct { @@ -834,47 +823,18 @@ func (a *ApexSet) hasSanitizedSource(sanitizer string) bool { func apexSetFactory() android.Module { module := &ApexSet{} module.AddProperties(&module.properties) - module.initPrebuiltCommon(module, &module.properties.PrebuiltCommonProperties) + module.prebuiltCommon.prebuiltCommonProperties = &module.properties.PrebuiltCommonProperties + + // init the module as a prebuilt + // even though this module type has srcs, use `InitPrebuiltModuleWithoutSrcs`, since the existing + // InitPrebuiltModule* are not friendly with Sources of Configurable type. + // The actual src will be evaluated in GenerateAndroidBuildActions. + android.InitPrebuiltModuleWithoutSrcs(module) + android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) return module } -func createApexExtractorModule(ctx android.BottomUpMutatorContext, name string, apexExtractorProperties *ApexExtractorProperties) { - props := struct { - Name *string - }{ - Name: proptools.StringPtr(name), - } - - ctx.CreateModule(privateApexExtractorModuleFactory, - &props, - apexExtractorProperties, - ) -} - -func apexExtractorModuleName(baseModuleName string) string { - return baseModuleName + ".apex.extractor" -} - -var _ prebuiltApexModuleCreator = (*ApexSet)(nil) - -// createPrebuiltApexModules creates modules necessary to export files from the apex set to other -// modules. -// -// This effectively does for apex_set what Prebuilt.createPrebuiltApexModules does for a -// prebuilt_apex except that instead of creating a selector module which selects one .apex file -// from those provided this creates an extractor module which extracts the appropriate .apex file -// from the zip file containing them. -func (a *ApexSet) createPrebuiltApexModules(ctx android.BottomUpMutatorContext) { - apexExtractorModuleName := apexExtractorModuleName(a.Name()) - createApexExtractorModule(ctx, apexExtractorModuleName, &a.properties.ApexExtractorProperties) - - apexFileSource := ":" + apexExtractorModuleName - - // After passing the arch specific src properties to the creating the apex selector module - a.prebuiltCommonProperties.Selected_apex = proptools.StringPtr(apexFileSource) -} - func (a *ApexSet) ComponentDepsMutator(ctx android.BottomUpMutatorContext) { a.prebuiltApexContentsDeps(ctx) } @@ -897,7 +857,15 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.ModuleErrorf("filename should end in %s or %s for apex_set", imageApexSuffix, imageCapexSuffix) } - inputApex := android.OptionalPathForModuleSrc(ctx, a.prebuiltCommonProperties.Selected_apex).Path() + var apexSet android.Path + if srcs := a.properties.prebuiltSrcs(ctx); len(srcs) == 1 { + apexSet = android.PathForModuleSrc(ctx, srcs[0]) + } else { + ctx.ModuleErrorf("Expected exactly one source apex_set file, found %v\n", srcs) + } + + extractedApex := extract(ctx, apexSet, a.properties.Prerelease) + a.outputApex = android.PathForModuleOut(ctx, a.installFilename) // Build the output APEX. If compression is not enabled, make sure the output is not compressed even if the input is compressed @@ -907,7 +875,7 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { } ctx.Build(pctx, android.BuildParams{ Rule: buildRule, - Input: inputApex, + Input: extractedApex, Output: a.outputApex, }) @@ -916,7 +884,7 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { return } - deapexerInfo := a.getDeapexerInfo(ctx, inputApex) + deapexerInfo := a.getDeapexerInfo(ctx, extractedApex) // dexpreopt any system server jars if present a.dexpreoptSystemServerJars(ctx, deapexerInfo) From 490a6f9b76872fcd30ddd3303b6b1ecd4cf6be3f Mon Sep 17 00:00:00 2001 From: Chan Wang Date: Mon, 23 Sep 2024 11:52:00 +0000 Subject: [PATCH 6/8] Temporarily bypass apex availability check for /product apexes with a specific prefix Bug: 361501627 Test: m nothing --no-skip-soong-tests Change-Id: Ifb855bed3514d27ecccddb5cd986537c628683b1 --- apex/apex.go | 6 ++ apex/apex_test.go | 166 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+) diff --git a/apex/apex.go b/apex/apex.go index d5776b5de..3850ee137 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2785,6 +2785,12 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { return } + // Temporarily bypass /product APEXes with a specific prefix. + // TODO: b/352818241 - Remove this after APEX availability is enforced for /product APEXes. + if a.ProductSpecific() && strings.HasPrefix(a.ApexVariationName(), "com.sdv.") { + return + } + // Coverage build adds additional dependencies for the coverage-only runtime libraries. // Requiring them and their transitive depencies with apex_available is not right // because they just add noise. diff --git a/apex/apex_test.go b/apex/apex_test.go index 8d34e9fde..f36467ef4 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -6216,6 +6216,87 @@ func TestApexAvailable_DirectDep(t *testing.T) { system_shared_libs: [], apex_available: ["otherapex"], }`) + + // 'apex_available' check is bypassed for /product apex with a specific prefix. + // TODO: b/352818241 - Remove below two cases after APEX availability is enforced for /product APEXes. + testApex(t, ` + apex { + name: "com.sdv.myapex", + key: "myapex.key", + native_shared_libs: ["libfoo"], + updatable: false, + product_specific: true, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + apex { + name: "com.any.otherapex", + key: "otherapex.key", + native_shared_libs: ["libfoo"], + updatable: false, + } + + apex_key { + name: "otherapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libfoo", + stl: "none", + system_shared_libs: [], + apex_available: ["com.any.otherapex"], + product_specific: true, + }`, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/com.sdv.myapex-file_contexts": nil, + "system/sepolicy/apex/com.any.otherapex-file_contexts": nil, + })) + + // 'apex_available' check is not bypassed for non-product apex with a specific prefix. + testApexError(t, "requires \"libfoo\" that doesn't list the APEX under 'apex_available'.", ` + apex { + name: "com.sdv.myapex", + key: "myapex.key", + native_shared_libs: ["libfoo"], + updatable: false, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + apex { + name: "com.any.otherapex", + key: "otherapex.key", + native_shared_libs: ["libfoo"], + updatable: false, + } + + apex_key { + name: "otherapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libfoo", + stl: "none", + system_shared_libs: [], + apex_available: ["com.any.otherapex"], + }`, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/com.sdv.myapex-file_contexts": nil, + "system/sepolicy/apex/com.any.otherapex-file_contexts": nil, + })) } func TestApexAvailable_IndirectDep(t *testing.T) { @@ -6261,6 +6342,91 @@ func TestApexAvailable_IndirectDep(t *testing.T) { stl: "none", system_shared_libs: [], }`) + + // 'apex_available' check is bypassed for /product apex with a specific prefix. + // TODO: b/352818241 - Remove below two cases after APEX availability is enforced for /product APEXes. + testApex(t, ` + apex { + name: "com.sdv.myapex", + key: "myapex.key", + native_shared_libs: ["libfoo"], + updatable: false, + product_specific: true, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libfoo", + stl: "none", + shared_libs: ["libbar"], + system_shared_libs: [], + apex_available: ["com.sdv.myapex"], + product_specific: true, + } + + cc_library { + name: "libbar", + stl: "none", + shared_libs: ["libbaz"], + system_shared_libs: [], + apex_available: ["com.sdv.myapex"], + product_specific: true, + } + + cc_library { + name: "libbaz", + stl: "none", + system_shared_libs: [], + product_specific: true, + }`, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/com.sdv.myapex-file_contexts": nil, + })) + + // 'apex_available' check is not bypassed for non-product apex with a specific prefix. + testApexError(t, `requires "libbaz" that doesn't list the APEX under 'apex_available'.`, ` + apex { + name: "com.sdv.myapex", + key: "myapex.key", + native_shared_libs: ["libfoo"], + updatable: false, + } + + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + + cc_library { + name: "libfoo", + stl: "none", + shared_libs: ["libbar"], + system_shared_libs: [], + apex_available: ["com.sdv.myapex"], + } + + cc_library { + name: "libbar", + stl: "none", + shared_libs: ["libbaz"], + system_shared_libs: [], + apex_available: ["com.sdv.myapex"], + } + + cc_library { + name: "libbaz", + stl: "none", + system_shared_libs: [], + }`, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/com.sdv.myapex-file_contexts": nil, + })) } func TestApexAvailable_IndirectStaticDep(t *testing.T) { From df1c59a657e4c45f7452ab8b608aea155b8931aa Mon Sep 17 00:00:00 2001 From: Liana Kazanova Date: Mon, 23 Sep 2024 21:54:04 +0000 Subject: [PATCH 7/8] Revert "pass read new storage parameter to java codegen" This reverts commit 9cf2e8e1403b5e057aca10870080adbe3e621f83. Reason for revert:DroidMonitor - Potential culprit for http://b/369200837 - Verifying through ABTD before submission. Change-Id: I635ba732fba40b7c73b5c419ef204fb14e857cb2 --- aconfig/codegen/init.go | 3 +-- aconfig/codegen/java_aconfig_library.go | 5 +---- java/testing.go | 2 -- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/aconfig/codegen/init.go b/aconfig/codegen/init.go index ed0b3ed7f..98d288f0a 100644 --- a/aconfig/codegen/init.go +++ b/aconfig/codegen/init.go @@ -32,7 +32,6 @@ var ( ` --mode ${mode}` + ` --cache ${in}` + ` --out ${out}.tmp` + - ` --allow-instrumentation ${debug}` + ` && $soong_zip -write_if_changed -jar -o ${out} -C ${out}.tmp -D ${out}.tmp` + ` && rm -rf ${out}.tmp`, CommandDeps: []string{ @@ -40,7 +39,7 @@ var ( "$soong_zip", }, Restat: true, - }, "mode", "debug") + }, "mode") // For cc_aconfig_library: Generate C++ library cppRule = pctx.AndroidStaticRule("cc_aconfig_library", diff --git a/aconfig/codegen/java_aconfig_library.go b/aconfig/codegen/java_aconfig_library.go index ebca4134c..673ac2afe 100644 --- a/aconfig/codegen/java_aconfig_library.go +++ b/aconfig/codegen/java_aconfig_library.go @@ -20,7 +20,6 @@ import ( "github.com/google/blueprint" "github.com/google/blueprint/proptools" - "strconv" ) type declarationsTagType struct { @@ -72,7 +71,6 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) DepsMutator(module *ja module.AddSharedLibrary("aconfig-annotations-lib") // TODO(b/303773055): Remove the annotation after access issue is resolved. module.AddSharedLibrary("unsupportedappusage") - module.AddSharedLibrary("aconfig_storage_reader_java") } } @@ -104,8 +102,7 @@ func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) GenerateSourceJarBuild Output: srcJarPath, Description: "aconfig.srcjar", Args: map[string]string{ - "mode": mode, - "debug": strconv.FormatBool(ctx.Config().ReleaseReadFromNewStorage()), + "mode": mode, }, }) diff --git a/java/testing.go b/java/testing.go index 6cc9fd125..0c79e9f7e 100644 --- a/java/testing.go +++ b/java/testing.go @@ -424,9 +424,7 @@ func gatherRequiredDepsForTest() string { "kotlin-stdlib-jdk8", "kotlin-annotations", "stub-annotations", - "aconfig-annotations-lib", - "aconfig_storage_reader_java", "unsupportedappusage", } From 309a612c9f602c9021989c607a91917194d18e77 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Mon, 23 Sep 2024 23:03:18 +0000 Subject: [PATCH 8/8] Remove `prebuilt_apex_module_creator` mutator prebuilt apex modules no longer create internal modules, so this mutator is not necessary. Test: go build ./apex Change-Id: I12c08b8f36efab8a9898341052b6f3cd26a0e803 --- apex/apex.go | 5 ----- apex/prebuilt.go | 22 ---------------------- 2 files changed, 27 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index 9e3f288ce..9e9b9f202 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -49,15 +49,10 @@ func registerApexBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("override_apex", OverrideApexFactory) ctx.RegisterModuleType("apex_set", apexSetFactory) - ctx.PreArchMutators(registerPreArchMutators) ctx.PreDepsMutators(RegisterPreDepsMutators) ctx.PostDepsMutators(RegisterPostDepsMutators) } -func registerPreArchMutators(ctx android.RegisterMutatorsContext) { - ctx.BottomUp("prebuilt_apex_module_creator", prebuiltApexModuleCreatorMutator).Parallel() -} - func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) { ctx.BottomUp("apex_vndk_deps", apexVndkDepsMutator).Parallel() } diff --git a/apex/prebuilt.go b/apex/prebuilt.go index d3f14f9c0..9cd5688ba 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -253,28 +253,6 @@ func (p *prebuiltCommon) AndroidMkEntries() []android.AndroidMkEntries { return entriesList } -// DEPRECATED. // TODO (spandandas): Remove this interface. - -// prebuiltApexModuleCreator defines the methods that need to be implemented by prebuilt_apex and -// apex_set in order to create the modules needed to provide access to the prebuilt .apex file. -type prebuiltApexModuleCreator interface { - createPrebuiltApexModules(ctx android.BottomUpMutatorContext) -} - -// prebuiltApexModuleCreatorMutator is the mutator responsible for invoking the -// prebuiltApexModuleCreator's createPrebuiltApexModules method. -// -// It is registered as a pre-arch mutator as it must run after the ComponentDepsMutator because it -// will need to access dependencies added by that (exported modules) but must run before the -// DepsMutator so that the deapexer module it creates can add dependencies onto itself from the -// exported modules. -func prebuiltApexModuleCreatorMutator(ctx android.BottomUpMutatorContext) { - module := ctx.Module() - if creator, ok := module.(prebuiltApexModuleCreator); ok { - creator.createPrebuiltApexModules(ctx) - } -} - func (p *prebuiltCommon) hasExportedDeps() bool { return len(p.prebuiltCommonProperties.Exported_bootclasspath_fragments) > 0 || len(p.prebuiltCommonProperties.Exported_systemserverclasspath_fragments) > 0