diff options
Diffstat (limited to 'java')
| -rw-r--r-- | java/androidmk.go | 6 | ||||
| -rwxr-xr-x | java/app.go | 3 | ||||
| -rw-r--r-- | java/app_import_test.go | 16 | ||||
| -rw-r--r-- | java/app_test.go | 2 | ||||
| -rw-r--r-- | java/base.go | 3 | ||||
| -rw-r--r-- | java/bootclasspath_fragment.go | 29 | ||||
| -rw-r--r-- | java/code_metadata_test.go | 19 | ||||
| -rw-r--r-- | java/config/config.go | 2 | ||||
| -rw-r--r-- | java/dex.go | 7 | ||||
| -rw-r--r-- | java/dexpreopt.go | 40 | ||||
| -rw-r--r-- | java/dexpreopt_bootjars.go | 166 | ||||
| -rw-r--r-- | java/dexpreopt_config.go | 2 | ||||
| -rw-r--r-- | java/dexpreopt_test.go | 6 | ||||
| -rw-r--r-- | java/droidstubs_test.go | 2 | ||||
| -rw-r--r-- | java/hiddenapi_modular.go | 20 | ||||
| -rw-r--r-- | java/java.go | 23 | ||||
| -rw-r--r-- | java/java_test.go | 4 | ||||
| -rw-r--r-- | java/platform_bootclasspath.go | 11 | ||||
| -rw-r--r-- | java/sdk_library.go | 25 | ||||
| -rw-r--r-- | java/sdk_library_test.go | 8 | ||||
| -rw-r--r-- | java/system_modules.go | 3 | ||||
| -rw-r--r-- | java/test_spec_test.go | 19 | ||||
| -rw-r--r-- | java/testing.go | 6 |
23 files changed, 281 insertions, 141 deletions
diff --git a/java/androidmk.go b/java/androidmk.go index 809f9b563..cbf9abb96 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -207,11 +207,7 @@ func (j *TestHelperLibrary) AndroidMkEntries() []android.AndroidMkEntries { func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries { if prebuilt.hideApexVariantFromMake { - // For a library imported from a prebuilt APEX, we don't need a Make module for itself, as we - // don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it - // is preopted. - dexpreoptEntries := prebuilt.dexpreopter.AndroidMkEntriesForApex() - return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true}) + return []android.AndroidMkEntries{} } return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "JAVA_LIBRARIES", diff --git a/java/app.go b/java/app.go index 7f0303a6b..8b28dac78 100755 --- a/java/app.go +++ b/java/app.go @@ -22,7 +22,6 @@ import ( "path/filepath" "strings" - "android/soong/aconfig" "android/soong/testing" "github.com/google/blueprint" @@ -509,7 +508,7 @@ func (a *AndroidApp) aaptBuildActions(ctx android.ModuleContext) { var aconfigTextFilePaths android.Paths ctx.VisitDirectDepsWithTag(aconfigDeclarationTag, func(dep android.Module) { - if provider, ok := android.OtherModuleProvider(ctx, dep, aconfig.DeclarationsProviderKey); ok { + if provider, ok := android.OtherModuleProvider(ctx, dep, android.AconfigDeclarationsProviderKey); ok { aconfigTextFilePaths = append(aconfigTextFilePaths, provider.IntermediateDumpOutputPath) } else { ctx.ModuleErrorf("Only aconfig_declarations module type is allowed for "+ diff --git a/java/app_import_test.go b/java/app_import_test.go index 8f29bb373..ef4626e26 100644 --- a/java/app_import_test.go +++ b/java/app_import_test.go @@ -40,8 +40,8 @@ func TestAndroidAppImport(t *testing.T) { variant := ctx.ModuleForTests("foo", "android_common") // Check dexpreopt outputs. - if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil || - variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil { + if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil || + variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil { t.Errorf("can't find dexpreopt outputs") } @@ -74,8 +74,8 @@ func TestAndroidAppImport_NoDexPreopt(t *testing.T) { variant := ctx.ModuleForTests("foo", "android_common") // Check dexpreopt outputs. They shouldn't exist. - if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule != nil || - variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule != nil { + if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule != nil || + variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule != nil { t.Errorf("dexpreopt shouldn't have run.") } @@ -101,8 +101,8 @@ func TestAndroidAppImport_Presigned(t *testing.T) { variant := ctx.ModuleForTests("foo", "android_common") // Check dexpreopt outputs. - if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil || - variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil { + if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil || + variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil { t.Errorf("can't find dexpreopt outputs") } // Make sure signing was skipped and aligning was done. @@ -210,8 +210,8 @@ func TestAndroidAppImport_DefaultDevCert(t *testing.T) { variant := ctx.ModuleForTests("foo", "android_common") // Check dexpreopt outputs. - if variant.MaybeOutput("dexpreopt/oat/arm64/package.vdex").Rule == nil || - variant.MaybeOutput("dexpreopt/oat/arm64/package.odex").Rule == nil { + if variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.vdex").Rule == nil || + variant.MaybeOutput("dexpreopt/foo/oat/arm64/package.odex").Rule == nil { t.Errorf("can't find dexpreopt outputs") } diff --git a/java/app_test.go b/java/app_test.go index 0936b281a..861c04761 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -3357,7 +3357,7 @@ func TestUsesLibraries(t *testing.T) { cmd := app.Rule("dexpreopt").RuleParams.Command android.AssertStringDoesContain(t, "dexpreopt app cmd context", cmd, "--context-json=") android.AssertStringDoesContain(t, "dexpreopt app cmd product_packages", cmd, - "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/product_packages.txt") + "--product-packages=out/soong/.intermediates/app/android_common/dexpreopt/app/product_packages.txt") } func TestDexpreoptBcp(t *testing.T) { diff --git a/java/base.go b/java/base.go index 41f2fcc96..0d3e4dbe3 100644 --- a/java/base.go +++ b/java/base.go @@ -24,7 +24,6 @@ import ( "github.com/google/blueprint/pathtools" "github.com/google/blueprint/proptools" - "android/soong/aconfig" "android/soong/android" "android/soong/dexpreopt" "android/soong/java/config" @@ -1694,7 +1693,7 @@ func (j *Module) compile(ctx android.ModuleContext, extraSrcJars, extraClasspath ctx.CheckbuildFile(outputFile) - aconfig.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles) + android.CollectDependencyAconfigFiles(ctx, &j.mergedAconfigFiles) android.SetProvider(ctx, JavaInfoProvider, JavaInfo{ HeaderJars: android.PathsIfNonNil(j.headerJarFile), diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index d2bb52315..ae2440466 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -240,7 +240,8 @@ type BootclasspathFragmentModule struct { sourceOnlyProperties SourceOnlyBootclasspathProperties // Path to the boot image profile. - profilePath android.WritablePath + profilePath android.WritablePath + profilePathErr error } // commonBootclasspathFragment defines the methods that are implemented by both source and prebuilt @@ -384,6 +385,10 @@ func (i BootclasspathFragmentApexContentInfo) DexBootJarPathForContentModule(mod } } +func (i BootclasspathFragmentApexContentInfo) DexBootJarPathMap() bootDexJarByModule { + return i.contentModuleDexJarPaths +} + func (i BootclasspathFragmentApexContentInfo) ProfilePathOnHost() android.Path { return i.profilePathOnHost } @@ -533,7 +538,7 @@ func (b *BootclasspathFragmentModule) provideApexContentInfo(ctx android.ModuleC if profile != nil { info.profilePathOnHost = profile - info.profileInstallPathInApex = profileInstallPathInApex + info.profileInstallPathInApex = ProfileInstallPathInApex } // Make the apex content info available for other modules. @@ -1033,10 +1038,6 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an return android.PathForModuleSrc(ctx, *src) } - // Retrieve the dex files directly from the content modules. They in turn should retrieve the - // encoded dex jars from the prebuilt .apex files. - encodedBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, contents) - output := HiddenAPIOutput{ HiddenAPIFlagOutput: HiddenAPIFlagOutput{ AnnotationFlagsPath: pathForSrc("hidden_api.annotation_flags", module.prebuiltProperties.Hidden_api.Annotation_flags), @@ -1047,8 +1048,6 @@ func (module *PrebuiltBootclasspathFragmentModule) produceHiddenAPIOutput(ctx an StubFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.Stub_flags, nil), AllFlagsPath: pathForOptionalSrc(module.prebuiltProperties.Hidden_api.All_flags, nil), }, - - EncodedBootDexFilesByModule: encodedBootDexJarsByModule, } // TODO: Temporarily fallback to stub_flags/all_flags properties until prebuilts have been updated. @@ -1065,15 +1064,21 @@ func (module *PrebuiltBootclasspathFragmentModule) produceBootImageProfile(ctx a return nil } - di := android.FindDeapexerProviderForModule(ctx) - if di == 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 di.PrebuiltExportPath(ProfileInstallPathInApex) } func (b *PrebuiltBootclasspathFragmentModule) getProfilePath() android.Path { + if b.profilePathErr != nil { + panic(b.profilePathErr.Error()) + } return b.profilePath } @@ -1087,7 +1092,7 @@ var _ commonBootclasspathFragment = (*PrebuiltBootclasspathFragmentModule)(nil) func (module *PrebuiltBootclasspathFragmentModule) RequiredFilesFromPrebuiltApex(ctx android.BaseModuleContext) []string { for _, apex := range module.ApexProperties.Apex_available { if isProfileProviderApex(ctx, apex) { - return []string{profileInstallPathInApex} + return []string{ProfileInstallPathInApex} } } return nil diff --git a/java/code_metadata_test.go b/java/code_metadata_test.go index 509e70112..0ef348afe 100644 --- a/java/code_metadata_test.go +++ b/java/code_metadata_test.go @@ -25,12 +25,10 @@ func TestCodeMetadata(t *testing.T) { }` result := runCodeMetadataTest(t, android.FixtureExpectsNoErrors, bp) - module := result.ModuleForTests( - "module-name", "", - ).Module().(*soongTesting.CodeMetadataModule) + module := result.ModuleForTests("module-name", "") // Check that the provider has the right contents - data, _ := android.SingletonModuleProvider(result, module, soongTesting.CodeMetadataProviderKey) + data, _ := android.SingletonModuleProvider(result, module.Module(), soongTesting.CodeMetadataProviderKey) if !strings.HasSuffix( data.IntermediatePath.String(), "/intermediateCodeMetadata.pb", ) { @@ -40,13 +38,8 @@ func TestCodeMetadata(t *testing.T) { ) } - buildParamsSlice := module.BuildParamsForTests() - var metadata = "" - for _, params := range buildParamsSlice { - if params.Rule.String() == "android/soong/android.writeFile" { - metadata = params.Args["content"] - } - } + metadata := android.ContentFromFileRuleForTests(t, result.TestContext, + module.Output(data.IntermediatePath.String())) metadataList := make([]*code_metadata_internal_proto.CodeMetadataInternal_TargetOwnership, 0, 2) teamId := "12345" @@ -63,9 +56,7 @@ func TestCodeMetadata(t *testing.T) { CodeMetadataMetadata := code_metadata_internal_proto.CodeMetadataInternal{TargetOwnershipList: metadataList} protoData, _ := proto.Marshal(&CodeMetadataMetadata) - rawData := string(protoData) - formattedData := strings.ReplaceAll(rawData, "\n", "\\n") - expectedMetadata := "'" + formattedData + "\\n'" + expectedMetadata := string(protoData) if metadata != expectedMetadata { t.Errorf( diff --git a/java/config/config.go b/java/config/config.go index d80ed4142..6a945ac9c 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -95,13 +95,11 @@ func init() { "-JXX:TieredStopAtLevel=1", "-JDcom.android.tools.r8.emitRecordAnnotationsInDex", "-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex", - "-JDcom.android.tools.r8.emitRecordAnnotationsExInDex", }, dexerJavaVmFlagsList...)) exportedVars.ExportStringListStaticVariable("R8Flags", append([]string{ "-JXmx4096M", "-JDcom.android.tools.r8.emitRecordAnnotationsInDex", "-JDcom.android.tools.r8.emitPermittedSubclassesAnnotationsInDex", - "-JDcom.android.tools.r8.emitRecordAnnotationsExInDex", }, dexerJavaVmFlagsList...)) exportedVars.ExportStringListStaticVariable("CommonJdkFlags", []string{ diff --git a/java/dex.go b/java/dex.go index cdae0a2df..fbb841860 100644 --- a/java/dex.go +++ b/java/dex.go @@ -223,6 +223,13 @@ func (d *dexer) dexCommonFlags(ctx android.ModuleContext, if err != nil { ctx.PropertyErrorf("min_sdk_version", "%s", err) } + if effectiveVersion.FinalOrFutureInt() >= 35 { + // V is 35, but we have not bumped the SDK version yet, so check for both. + if ctx.Config().PlatformSdkVersion().FinalInt() >= 35 || + ctx.Config().PlatformSdkCodename() == "VanillaIceCream" { + flags = append([]string{"-JDcom.android.tools.r8.dexContainerExperiment"}, flags...) + } + } // If the specified SDK level is 10000, then configure the compiler to use the // current platform SDK level and to compile the build as a platform build. diff --git a/java/dexpreopt.go b/java/dexpreopt.go index 0f69dc3a4..bd3cce412 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -79,18 +79,25 @@ func (install *dexpreopterInstall) SubModuleName() string { func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries { return android.AndroidMkEntries{ Class: "ETC", - SubName: install.SubModuleName(), OutputFile: android.OptionalPathForPath(install.outputPathOnHost), ExtraEntries: []android.AndroidMkExtraEntriesFunc{ func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE", install.FullModuleName()) entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String()) entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice) entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false") + // Unset LOCAL_SOONG_INSTALLED_MODULE so that this does not default to the primary .apex file + // Without this, installation of the dexpreopt artifacts get skipped + entries.SetString("LOCAL_SOONG_INSTALLED_MODULE", "") }, }, } } +type Dexpreopter struct { + dexpreopter +} + type dexpreopter struct { dexpreoptProperties DexpreoptProperties importDexpreoptProperties ImportDexpreoptProperties @@ -258,6 +265,17 @@ func (d *dexpreopter) getInstallPath( return defaultInstallPath } +// DexpreoptPrebuiltApexSystemServerJars generates the dexpreopt artifacts from a jar file that has been deapexed from a prebuilt apex +func (d *Dexpreopter) DexpreoptPrebuiltApexSystemServerJars(ctx android.ModuleContext, libraryName string, di *android.DeapexerInfo) { + // A single prebuilt apex can have multiple apex system jars + // initialize the output path for this dex jar + dc := dexpreopt.GetGlobalConfig(ctx) + d.installPath = android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexpreopt.GetSystemServerDexLocation(ctx, dc, libraryName), "/")) + // generate the rules for creating the .odex and .vdex files for this system server jar + dexJarFile := di.PrebuiltExportPath(ApexRootRelativePathToJavaLib(libraryName)) + d.dexpreopt(ctx, dexJarFile) +} + func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) { global := dexpreopt.GetGlobalConfig(ctx) @@ -346,11 +364,15 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr d.dexpreoptProperties.Dex_preopt_result.Profile_guided = profileClassListing.Valid() + // A single apex can have multiple system server jars + // Use the dexJar to create a unique scope for each + dexJarStem := strings.TrimSuffix(dexJarFile.Base(), dexJarFile.Ext()) + // Full dexpreopt config, used to create dexpreopt build rules. dexpreoptConfig := &dexpreopt.ModuleConfig{ Name: moduleName(ctx), DexLocation: dexLocation, - BuildPath: android.PathForModuleOut(ctx, "dexpreopt", moduleName(ctx)+".jar").OutputPath, + BuildPath: android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, moduleName(ctx)+".jar").OutputPath, DexPath: dexJarFile, ManifestPath: android.OptionalPathForPath(d.manifestFile), UncompressedDex: d.uncompressedDex, @@ -380,7 +402,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr PresignedPrebuilt: d.isPresignedPrebuilt, } - d.configPath = android.PathForModuleOut(ctx, "dexpreopt", "dexpreopt.config") + d.configPath = android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "dexpreopt.config") dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath) if d.dexpreoptDisabled(ctx) { @@ -394,7 +416,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr // dependencies to create a per-app list, and use `rsync --checksum` to prevent the file's mtime // from being changed if the contents don't change. This avoids unnecessary dexpreopt reruns. productPackages := android.PathForModuleInPartitionInstall(ctx, "", "product_packages.txt") - appProductPackages := android.PathForModuleOut(ctx, "dexpreopt", "product_packages.txt") + appProductPackages := android.PathForModuleOut(ctx, "dexpreopt", dexJarStem, "product_packages.txt") appProductPackagesStaging := appProductPackages.ReplaceExtension(ctx, "txt.tmp") clcNames, _ := dexpreopt.ComputeClassLoaderContextDependencies(dexpreoptConfig.ClassLoaderContexts) sort.Strings(clcNames) // The order needs to be deterministic. @@ -416,7 +438,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr Text("rsync --checksum"). Input(appProductPackagesStaging). Output(appProductPackages) - productPackagesRule.Restat().Build("product_packages", "dexpreopt product_packages") + productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages") dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule( ctx, globalSoong, global, dexpreoptConfig, appProductPackages) @@ -425,9 +447,11 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr return } - dexpreoptRule.Build("dexpreopt", "dexpreopt") + dexpreoptRule.Build("dexpreopt"+"."+dexJarStem, "dexpreopt") - isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx)) + // The current ctx might be of a deapexer module created by a prebuilt apex + // Use the path of the dex file to determine the library name + isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(dexJarStem) for _, install := range dexpreoptRule.Installs() { // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT. @@ -452,7 +476,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr // The installs will be handled by Make as sub-modules of the java library. d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{ name: arch + "-" + installBase, - moduleName: moduleName(ctx), + moduleName: dexJarStem, outputPathOnHost: install.From, installDirOnDevice: installPath, installFileOnDevice: installBase, diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 5a19945b4..82cece346 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -21,6 +21,7 @@ import ( "android/soong/android" "android/soong/dexpreopt" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -224,8 +225,9 @@ var artApexNames = []string{ } var ( - dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"} - dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments") + dexpreoptBootJarDepTag = bootclasspathDependencyTag{name: "dexpreopt-boot-jar"} + dexBootJarsFragmentsKey = android.NewOnceKey("dexBootJarsFragments") + apexContributionsMetadataDepTag = dependencyTag{name: "all_apex_contributions"} ) func init() { @@ -502,6 +504,11 @@ type dexpreoptBootJars struct { dexpreoptConfigForMake android.WritablePath } +func (dbj *dexpreoptBootJars) DepsMutator(ctx android.BottomUpMutatorContext) { + // Create a dependency on all_apex_contributions to determine the selected mainline module + ctx.AddDependency(ctx.Module(), apexContributionsMetadataDepTag, "all_apex_contributions") +} + func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) { if _, ok := ctx.Module().(*dexpreoptBootJars); !ok { return @@ -520,6 +527,14 @@ func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) { } // For accessing the boot jars. addDependenciesOntoBootImageModules(ctx, config.modules, dexpreoptBootJarDepTag) + // Create a dependency on the apex selected using RELEASE_APEX_CONTRIBUTIONS_* + // TODO: b/308174306 - Remove the direct depedendency edge to the java_library (source/prebuilt) once all mainline modules + // have been flagged using RELEASE_APEX_CONTRIBUTIONS_* + apexes := []string{} + for i := 0; i < config.modules.Len(); i++ { + apexes = append(apexes, config.modules.Apex(i)) + } + addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...) } if ctx.OtherModuleExists("platform-bootclasspath") { @@ -532,6 +547,28 @@ func DexpreoptBootJarsMutator(ctx android.BottomUpMutatorContext) { } } +// Create a dependency from dex_bootjars to the specific apexes selected using all_apex_contributions +// This dependency will be used to get the path to the deapexed dex boot jars and profile (via a provider) +func addDependenciesOntoSelectedBootImageApexes(ctx android.BottomUpMutatorContext, apexes ...string) { + psi := android.PrebuiltSelectionInfoMap{} + ctx.VisitDirectDepsWithTag(apexContributionsMetadataDepTag, func(am android.Module) { + if info, exists := android.OtherModuleProvider(ctx, am, android.PrebuiltSelectionInfoProvider); exists { + psi = info + } + }) + for _, apex := range apexes { + for _, selected := range psi.GetSelectedModulesForApiDomain(apex) { + // We need to add a dep on only the apex listed in `contents` of the selected apex_contributions module + // This is not available in a structured format in `apex_contributions`, so this hack adds a dep on all `contents` + // (some modules like art.module.public.api do not have an apex variation since it is a pure stub module that does not get installed) + apexVariationOfSelected := append(ctx.Target().Variations(), blueprint.Variation{Mutator: "apex", Variation: apex}) + if ctx.OtherModuleDependencyVariantExists(apexVariationOfSelected, selected) { + ctx.AddFarVariationDependencies(apexVariationOfSelected, dexpreoptBootJarDepTag, selected) + } + } + } +} + func gatherBootclasspathFragments(ctx android.ModuleContext) map[string]android.Module { return ctx.Config().Once(dexBootJarsFragmentsKey, func() interface{} { fragments := make(map[string]android.Module) @@ -662,36 +699,67 @@ func getModulesForImage(ctx android.ModuleContext, imageConfig *bootImageConfig) // extractEncodedDexJarsFromModulesOrBootclasspathFragments gets the hidden API encoded dex jars for // the given modules. func extractEncodedDexJarsFromModulesOrBootclasspathFragments(ctx android.ModuleContext, apexJarModulePairs []apexJarModulePair) bootDexJarByModule { + apexNameToApexExportInfoMap := getApexNameToApexExportsInfoMap(ctx) encodedDexJarsByModuleName := bootDexJarByModule{} for _, pair := range apexJarModulePairs { - var path android.Path - if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) { - // This gives us the dex jar with the hidden API flags encoded from the monolithic hidden API - // files or the dex jar extracted from a prebuilt APEX. We can't use this for a boot jar for - // a source APEX because there is no guarantee that it is the same as the jar packed into the - // APEX. In practice, they are the same when we are building from a full source tree, but they - // are different when we are building from a thin manifest (e.g., master-art), where there is - // no monolithic hidden API files at all. - path = retrieveEncodedBootDexJarFromModule(ctx, pair.jarModule) + dexJarPath := getDexJarForApex(ctx, pair, apexNameToApexExportInfoMap) + encodedDexJarsByModuleName.addPath(pair.jarModule, dexJarPath) + } + return encodedDexJarsByModuleName +} + +type apexNameToApexExportsInfoMap map[string]android.ApexExportsInfo + +// javaLibraryPathOnHost returns the path to the java library which is exported by the apex for hiddenapi and dexpreopt and a boolean indicating whether the java library exists +// For prebuilt apexes, this is created by deapexing the prebuilt apex +func (m *apexNameToApexExportsInfoMap) javaLibraryDexPathOnHost(ctx android.ModuleContext, apex string, javalib string) (android.Path, bool) { + if info, exists := (*m)[apex]; exists { + if dex, exists := info.LibraryNameToDexJarPathOnHost[javalib]; exists { + return dex, true } else { - // Use exactly the same jar that is packed into the APEX. - fragment := getBootclasspathFragmentByApex(ctx, pair.apex) - if fragment == nil { - ctx.ModuleErrorf("Boot jar '%[1]s' is from APEX '%[2]s', but a bootclasspath_fragment for "+ - "APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars", - pair.jarModule.Name(), - pair.apex) - } - bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragment, BootclasspathFragmentApexContentInfoProvider) - jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule) - if err != nil { - ctx.ModuleErrorf("%s", err) - } - path = jar + ctx.ModuleErrorf("Apex %s does not provide a dex boot jar for library %s\n", apex, javalib) } - encodedDexJarsByModuleName.addPath(pair.jarModule, path) } - return encodedDexJarsByModuleName + // An apex entry could not be found. Return false. + // TODO: b/308174306 - When all the mainline modules have been flagged, make this a hard error + return nil, false +} + +// Returns the java libraries exported by the apex for hiddenapi and dexpreopt +// This information can come from two mechanisms +// 1. New: Direct deps to _selected_ apexes. The apexes return a ApexExportsInfo +// 2. Legacy: An edge to java_library or java_import (java_sdk_library) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes +// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2) +func getDexJarForApex(ctx android.ModuleContext, pair apexJarModulePair, apexNameToApexExportsInfoMap apexNameToApexExportsInfoMap) android.Path { + if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, pair.apex, android.RemoveOptionalPrebuiltPrefix(pair.jarModule.Name())); found { + return dex + } + // TODO: b/308174306 - Remove the legacy mechanism + if android.IsConfiguredJarForPlatform(pair.apex) || android.IsModulePrebuilt(pair.jarModule) { + // This gives us the dex jar with the hidden API flags encoded from the monolithic hidden API + // files or the dex jar extracted from a prebuilt APEX. We can't use this for a boot jar for + // a source APEX because there is no guarantee that it is the same as the jar packed into the + // APEX. In practice, they are the same when we are building from a full source tree, but they + // are different when we are building from a thin manifest (e.g., master-art), where there is + // no monolithic hidden API files at all. + return retrieveEncodedBootDexJarFromModule(ctx, pair.jarModule) + } else { + // Use exactly the same jar that is packed into the APEX. + fragment := getBootclasspathFragmentByApex(ctx, pair.apex) + if fragment == nil { + ctx.ModuleErrorf("Boot jar '%[1]s' is from APEX '%[2]s', but a bootclasspath_fragment for "+ + "APEX '%[2]s' doesn't exist or is not added as a dependency of dex_bootjars", + pair.jarModule.Name(), + pair.apex) + } + bootclasspathFragmentInfo, _ := android.OtherModuleProvider(ctx, fragment, BootclasspathFragmentApexContentInfoProvider) + jar, err := bootclasspathFragmentInfo.DexBootJarPathForContentModule(pair.jarModule) + if err != nil { + ctx.ModuleErrorf("%s", err) + } + return jar + } + return nil } // copyBootJarsToPredefinedLocations generates commands that will copy boot jars to predefined @@ -823,6 +891,37 @@ type bootImageVariantOutputs struct { config *bootImageVariant } +// Returns the profile file for an apex +// This information can come from two mechanisms +// 1. New: Direct deps to _selected_ apexes. The apexes return a BootclasspathFragmentApexContentInfo +// 2. Legacy: An edge to bootclasspath_fragment module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes +// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2) +func getProfilePathForApex(ctx android.ModuleContext, apexName string, apexNameToBcpInfoMap map[string]android.ApexExportsInfo) android.Path { + if info, exists := apexNameToBcpInfoMap[apexName]; exists { + return info.ProfilePathOnHost + } + // TODO: b/308174306 - Remove the legacy mechanism + fragment := getBootclasspathFragmentByApex(ctx, apexName) + if fragment == nil { + ctx.ModuleErrorf("Boot image config imports profile from '%[2]s', but a "+ + "bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+ + "dependency of dex_bootjars", + apexName) + return nil + } + return fragment.(commonBootclasspathFragment).getProfilePath() +} + +func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexExportsInfoMap { + apexNameToApexExportsInfoMap := apexNameToApexExportsInfoMap{} + ctx.VisitDirectDepsWithTag(dexpreoptBootJarDepTag, func(am android.Module) { + if info, exists := android.OtherModuleProvider(ctx, am, android.ApexExportsInfoProvider); exists { + apexNameToApexExportsInfoMap[info.ApexName] = info + } + }) + return apexNameToApexExportsInfoMap +} + // Generate boot image build rules for a specific target. func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs { @@ -865,6 +964,8 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p invocationPath := outputPath.ReplaceExtension(ctx, "invocation") + apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx) + cmd.Tool(globalSoong.Dex2oat). Flag("--avoid-storing-invocation"). FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath). @@ -877,16 +978,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p } for _, apex := range image.profileImports { - fragment := getBootclasspathFragmentByApex(ctx, apex) - if fragment == nil { - ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but a "+ - "bootclasspath_fragment for APEX '%[2]s' doesn't exist or is not added as a "+ - "dependency of dex_bootjars", - image.name, - apex) - return bootImageVariantOutputs{} - } - importedProfile := fragment.(commonBootclasspathFragment).getProfilePath() + importedProfile := getProfilePathForApex(ctx, apex, apexNameToApexExportsInfoMap) if importedProfile == nil { ctx.ModuleErrorf("Boot image config '%[1]s' imports profile from '%[2]s', but '%[2]s' "+ "doesn't provide a profile", diff --git a/java/dexpreopt_config.go b/java/dexpreopt_config.go index 2bd696c3d..254b2c1b0 100644 --- a/java/dexpreopt_config.go +++ b/java/dexpreopt_config.go @@ -45,7 +45,7 @@ var ( frameworkBootImageName = "boot" mainlineBootImageName = "mainline" bootImageStem = "boot" - profileInstallPathInApex = "etc/boot-image.prof" + ProfileInstallPathInApex = "etc/boot-image.prof" ) // getImageNames returns an ordered list of image names. The order doesn't matter but needs to be diff --git a/java/dexpreopt_test.go b/java/dexpreopt_test.go index fedd5640e..73e33f4fb 100644 --- a/java/dexpreopt_test.go +++ b/java/dexpreopt_test.go @@ -410,7 +410,7 @@ func TestAndroidMkEntriesForApex(t *testing.T) { verifyEntries(t, "entriesList[0]", "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.odex", - "/dexpreopt/oat/arm64/javalib.odex", + "/dexpreopt/service-foo/oat/arm64/javalib.odex", "/system/framework/oat/arm64", "apex@com.android.apex1@javalib@service-foo.jar@classes.odex", entriesList[0]) @@ -418,7 +418,7 @@ func TestAndroidMkEntriesForApex(t *testing.T) { verifyEntries(t, "entriesList[1]", "service-foo-dexpreopt-arm64-apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", - "/dexpreopt/oat/arm64/javalib.vdex", + "/dexpreopt/service-foo/oat/arm64/javalib.vdex", "/system/framework/oat/arm64", "apex@com.android.apex1@javalib@service-foo.jar@classes.vdex", entriesList[1]) @@ -459,7 +459,7 @@ func TestGenerateProfileEvenIfDexpreoptIsDisabled(t *testing.T) { ctx := result.TestContext dexpreopt := ctx.ModuleForTests("foo", "android_common").MaybeRule("dexpreopt") - expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/profile.prof"} + expected := []string{"out/soong/.intermediates/foo/android_common/dexpreopt/foo/profile.prof"} android.AssertArrayString(t, "outputs", expected, dexpreopt.AllOutputs()) } diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go index 17cad8958..7bcaca1d4 100644 --- a/java/droidstubs_test.go +++ b/java/droidstubs_test.go @@ -213,7 +213,7 @@ func TestDroidstubsSandbox(t *testing.T) { } manifest := android.RuleBuilderSboxProtoForTests(t, ctx, m.Output("metalava.sbox.textproto")) - if g, w := manifest.Commands[0].GetCommand(), "reference __SBOX_SANDBOX_DIR__/out/.intermediates/foo/gen/foo.txt"; !strings.Contains(g, w) { + if g, w := manifest.Commands[0].GetCommand(), "reference __SBOX_SANDBOX_DIR__/out/soong/.intermediates/foo/gen/foo.txt"; !strings.Contains(g, w) { t.Errorf("Expected command to contain %q, got %q", w, g) } } diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index 8011f343b..c3caa084f 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -19,6 +19,7 @@ import ( "strings" "android/soong/android" + "android/soong/dexpreopt" "github.com/google/blueprint" ) @@ -947,6 +948,7 @@ type HiddenAPIOutput struct { HiddenAPIFlagOutput // The map from base module name to the path to the encoded boot dex file. + // This field is not available in prebuilt apexes EncodedBootDexFilesByModule bootDexJarByModule } @@ -1249,9 +1251,27 @@ func buildRuleToGenerateRemovedDexSignatures(ctx android.ModuleContext, suffix s } // extractBootDexJarsFromModules extracts the boot dex jars from the supplied modules. +// This information can come from two mechanisms +// 1. New: Direct deps to _selected_ apexes. The apexes contain a ApexExportsInfo +// 2. Legacy: An edge to java_sdk_library(_import) module. For prebuilt apexes, this serves as a hook and is populated by deapexers of prebuilt apxes +// TODO: b/308174306 - Once all mainline modules have been flagged, drop (2) func extractBootDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule { bootDexJars := bootDexJarByModule{} + + apexNameToApexExportsInfoMap := getApexNameToApexExportsInfoMap(ctx) + // For ART and mainline module jars, query apexNameToApexExportsInfoMap to get the dex file + apexJars := dexpreopt.GetGlobalConfig(ctx).ArtApexJars.AppendList(&dexpreopt.GetGlobalConfig(ctx).ApexBootJars) + for i := 0; i < apexJars.Len(); i++ { + if dex, found := apexNameToApexExportsInfoMap.javaLibraryDexPathOnHost(ctx, apexJars.Apex(i), apexJars.Jar(i)); found { + bootDexJars[apexJars.Jar(i)] = dex + } + } + + // TODO - b/308174306: Drop the legacy mechanism for _, module := range contents { + if _, exists := bootDexJars[android.RemoveOptionalPrebuiltPrefix(module.Name())]; exists { + continue + } hiddenAPIModule := hiddenAPIModuleFromModule(ctx, module) if hiddenAPIModule == nil { continue diff --git a/java/java.go b/java/java.go index 630318e6d..2a4fafa8b 100644 --- a/java/java.go +++ b/java/java.go @@ -2100,6 +2100,7 @@ type Import struct { // output file containing classes.dex and resources dexJarFile OptionalDexJarPath + dexJarFileErr error dexJarInstallFile android.Path combinedClasspathFile android.Path @@ -2250,15 +2251,18 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if ai.ForPrebuiltApex { // Get the path of the dex implementation jar from the `deapexer` module. - di := android.FindDeapexerProviderForModule(ctx) - if di == nil { - return // An error has been reported by FindDeapexerProviderForModule. + 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 + return } - dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(j.BaseModuleName()) + 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())) + installPath := android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, ApexRootRelativePathToJavaLib(j.BaseModuleName())) j.dexJarInstallFile = installPath j.dexpreopter.installPath = j.dexpreopter.getInstallPath(ctx, installPath) @@ -2375,6 +2379,9 @@ func (j *Import) ImplementationAndResourcesJars() android.Paths { } func (j *Import) DexJarBuildPath() OptionalDexJarPath { + if j.dexJarFileErr != nil { + panic(j.dexJarFileErr.Error()) + } return j.dexJarFile } @@ -2415,7 +2422,7 @@ func (j *Import) ShouldSupportSdkVersion(ctx android.BaseModuleContext, // java_sdk_library_import with the specified base module name requires to be exported from a // prebuilt_apex/apex_set. func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []string { - dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(name) + dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(name) // Add the dex implementation jar to the set of exported files. files := []string{ dexJarFileApexRootRelative, @@ -2426,9 +2433,9 @@ func requiredFilesFromPrebuiltApexForImport(name string, d *dexpreopter) []strin return files } -// apexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for +// ApexRootRelativePathToJavaLib returns the path, relative to the root of the apex's contents, for // the java library with the specified name. -func apexRootRelativePathToJavaLib(name string) string { +func ApexRootRelativePathToJavaLib(name string) string { return filepath.Join("javalib", name+".jar") } diff --git a/java/java_test.go b/java/java_test.go index e21018c39..b9dc453b3 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -618,8 +618,6 @@ func TestPrebuilts(t *testing.T) { android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_library", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) entries = android.AndroidMkEntriesForTest(t, ctx, barModule.Module())[0] android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) - entries = android.AndroidMkEntriesForTest(t, ctx, ctx.ModuleForTests("sdklib", "android_common").Module())[0] - android.AssertStringEquals(t, "unexpected LOCAL_SOONG_MODULE_TYPE", "java_sdk_library_import", entries.EntryMap["LOCAL_SOONG_MODULE_TYPE"][0]) } func assertDeepEquals(t *testing.T, message string, expected interface{}, actual interface{}) { @@ -2433,7 +2431,7 @@ func TestSdkLibraryProvidesSystemModulesToApiLibrary(t *testing.T) { manifest := m.Output("metalava.sbox.textproto") sboxProto := android.RuleBuilderSboxProtoForTests(t, result.TestContext, manifest) manifestCommand := sboxProto.Commands[0].GetCommand() - classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/.intermediates/bar/android_common/turbine-combined/bar.jar" + classPathFlag := "--classpath __SBOX_SANDBOX_DIR__/out/soong/.intermediates/bar/android_common/turbine-combined/bar.jar" android.AssertStringDoesContain(t, "command expected to contain classpath flag", manifestCommand, classPathFlag) } diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index 88d1ae8c0..4db426e0d 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -106,6 +106,9 @@ func (b *platformBootclasspathModule) OutputFiles(tag string) (android.Paths, er } func (b *platformBootclasspathModule) DepsMutator(ctx android.BottomUpMutatorContext) { + // Create a dependency on all_apex_contributions to determine the selected mainline module + ctx.AddDependency(ctx.Module(), apexContributionsMetadataDepTag, "all_apex_contributions") + b.hiddenAPIDepsMutator(ctx) if !dexpreopt.IsDex2oatNeeded(ctx) { @@ -130,6 +133,8 @@ func (b *platformBootclasspathModule) hiddenAPIDepsMutator(ctx android.BottomUpM func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.BottomUpMutatorContext) { // Add dependencies on all the ART jars. global := dexpreopt.GetGlobalConfig(ctx) + addDependenciesOntoSelectedBootImageApexes(ctx, "com.android.art") + // TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly addDependenciesOntoBootImageModules(ctx, global.ArtApexJars, platformBootclasspathArtBootJarDepTag) // Add dependencies on all the non-updatable jars, which are on the platform or in non-updatable @@ -138,6 +143,12 @@ func (b *platformBootclasspathModule) BootclasspathDepsMutator(ctx android.Botto // Add dependencies on all the updatable jars, except the ART jars. apexJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars + apexes := []string{} + for i := 0; i < apexJars.Len(); i++ { + apexes = append(apexes, apexJars.Apex(i)) + } + addDependenciesOntoSelectedBootImageApexes(ctx, android.FirstUniqueStrings(apexes)...) + // TODO: b/308174306 - Remove the mechanism of depending on the java_sdk_library(_import) directly addDependenciesOntoBootImageModules(ctx, apexJars, platformBootclasspathApexBootJarDepTag) // Add dependencies on all the fragments. diff --git a/java/sdk_library.go b/java/sdk_library.go index 0584281a5..ef34fb6cd 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2378,7 +2378,8 @@ type SdkLibraryImport struct { xmlPermissionsFileModule *sdkLibraryXml // Build path to the dex implementation jar obtained from the prebuilt_apex, if any. - dexJarFile OptionalDexJarPath + dexJarFile OptionalDexJarPath + dexJarFileErr error // Expected install file path of the source module(sdk_library) // or dex implementation jar obtained from the prebuilt_apex, if any. @@ -2591,14 +2592,6 @@ func (module *SdkLibraryImport) DepsMutator(ctx android.BottomUpMutatorContext) } } -func (module *SdkLibraryImport) AndroidMkEntries() []android.AndroidMkEntries { - // For an SDK library imported from a prebuilt APEX, we don't need a Make module for itself, as we - // don't need to install it. However, we need to add its dexpreopt outputs as sub-modules, if it - // is preopted. - dexpreoptEntries := module.dexpreopter.AndroidMkEntriesForApex() - return append(dexpreoptEntries, android.AndroidMkEntries{Disabled: true}) -} - var _ android.ApexModule = (*SdkLibraryImport)(nil) // Implements android.ApexModule @@ -2695,11 +2688,14 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo ai, _ := android.ModuleProvider(ctx, android.ApexInfoProvider) if ai.ForPrebuiltApex { // Get the path of the dex implementation jar from the `deapexer` module. - di := android.FindDeapexerProviderForModule(ctx) - if di == nil { - return // An error has been reported by FindDeapexerProviderForModule. + 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 + return } - dexJarFileApexRootRelative := apexRootRelativePathToJavaLib(module.BaseModuleName()) + dexJarFileApexRootRelative := ApexRootRelativePathToJavaLib(module.BaseModuleName()) if dexOutputPath := di.PrebuiltExportPath(dexJarFileApexRootRelative); dexOutputPath != nil { dexJarFile := makeDexJarPathFromPath(dexOutputPath) module.dexJarFile = dexJarFile @@ -2759,6 +2755,9 @@ func (module *SdkLibraryImport) SdkImplementationJars(ctx android.BaseModuleCont func (module *SdkLibraryImport) DexJarBuildPath() OptionalDexJarPath { // The dex implementation jar extracted from the .apex file should be used in preference to the // source. + if module.dexJarFileErr != nil { + panic(module.dexJarFileErr.Error()) + } if module.dexJarFile.IsSet() { return module.dexJarFile } diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 0965fc2c7..63419d6b1 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -950,6 +950,7 @@ func TestJavaSdkLibraryImport_WithSource(t *testing.T) { }) CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ + `all_apex_contributions`, `prebuilt_sdklib.stubs`, `sdklib.impl`, // This should be prebuilt_sdklib.stubs but is set to sdklib.stubs because the @@ -1022,6 +1023,7 @@ func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer an }) CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ + `all_apex_contributions`, `dex2oatd`, `prebuilt_sdklib.stubs`, `prebuilt_sdklib.stubs.source`, @@ -1085,9 +1087,6 @@ func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) { "prebuilt_sdklib.source_preferred_using_legacy_flags", ], } - all_apex_contributions { - name: "all_apex_contributions", - } java_sdk_library { name: "sdklib.prebuilt_preferred_using_legacy_flags", srcs: ["a.java"], @@ -1169,9 +1168,6 @@ func TestSdkLibraryImport_MetadataModuleSupersedesPreferred(t *testing.T) { prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("sdklib.source_preferred_using_legacy_flags", "sdklib.prebuilt_preferred_using_legacy_flags"), - android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) { - android.RegisterApexContributionsBuildComponents(ctx) - }), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { variables.BuildFlags = map[string]string{ "RELEASE_APEX_CONTRIBUTIONS_ADSERVICES": "my_mainline_module_contributions", diff --git a/java/system_modules.go b/java/system_modules.go index 1c7917109..f3446483b 100644 --- a/java/system_modules.go +++ b/java/system_modules.go @@ -55,7 +55,8 @@ var ( `${config.MergeZipsCmd} -j ${workDir}/module.jar ${workDir}/classes.jar $in && ` + // Note: The version of the java.base module created must match the version // of the jlink tool which consumes it. - `${config.JmodCmd} create --module-version ${config.JlinkVersion} --target-platform android ` + + // Use LINUX-OTHER to be compatible with JDK 21+ (b/294137077) + `${config.JmodCmd} create --module-version ${config.JlinkVersion} --target-platform LINUX-OTHER ` + ` --class-path ${workDir}/module.jar ${workDir}/jmod/java.base.jmod && ` + `${config.JlinkCmd} --module-path ${workDir}/jmod --add-modules java.base --output ${outDir} ` + // Note: The system-modules jlink plugin is disabled because (a) it is not diff --git a/java/test_spec_test.go b/java/test_spec_test.go index f628b4b74..4144dad69 100644 --- a/java/test_spec_test.go +++ b/java/test_spec_test.go @@ -29,12 +29,10 @@ func TestTestSpec(t *testing.T) { }` result := runTestSpecTest(t, android.FixtureExpectsNoErrors, bp) - module := result.ModuleForTests( - "module-name", "", - ).Module().(*soongTesting.TestSpecModule) + module := result.ModuleForTests("module-name", "") // Check that the provider has the right contents - data, _ := android.SingletonModuleProvider(result, module, soongTesting.TestSpecProviderKey) + data, _ := android.SingletonModuleProvider(result, module.Module(), soongTesting.TestSpecProviderKey) if !strings.HasSuffix( data.IntermediatePath.String(), "/intermediateTestSpecMetadata.pb", ) { @@ -44,13 +42,8 @@ func TestTestSpec(t *testing.T) { ) } - buildParamsSlice := module.BuildParamsForTests() - var metadata = "" - for _, params := range buildParamsSlice { - if params.Rule.String() == "android/soong/android.writeFile" { - metadata = params.Args["content"] - } - } + metadata := android.ContentFromFileRuleForTests(t, result.TestContext, + module.Output(data.IntermediatePath.String())) metadataList := make([]*test_spec_proto.TestSpec_OwnershipMetadata, 0, 2) teamId := "12345" @@ -70,9 +63,7 @@ func TestTestSpec(t *testing.T) { } testSpecMetadata := test_spec_proto.TestSpec{OwnershipMetadataList: metadataList} protoData, _ := proto.Marshal(&testSpecMetadata) - rawData := string(protoData) - formattedData := strings.ReplaceAll(rawData, "\n", "\\n") - expectedMetadata := "'" + formattedData + "\\n'" + expectedMetadata := string(protoData) if metadata != expectedMetadata { t.Errorf( diff --git a/java/testing.go b/java/testing.go index d55cffc40..5959c49e4 100644 --- a/java/testing.go +++ b/java/testing.go @@ -383,6 +383,7 @@ func registerRequiredBuildComponentsForTest(ctx android.RegistrationContext) { RegisterSystemModulesBuildComponents(ctx) registerSystemserverClasspathBuildComponents(ctx) registerLintBuildComponents(ctx) + android.RegisterApexContributionsBuildComponents(ctx) } // gatherRequiredDepsForTest gathers the module definitions used by @@ -570,6 +571,11 @@ func gatherRequiredDepsForTest() string { } ` + bp += ` + all_apex_contributions { + name: "all_apex_contributions", + } +` return bp } |