diff --git a/Android.bp b/Android.bp index b1db8e937..2c0ef4740 100644 --- a/Android.bp +++ b/Android.bp @@ -104,6 +104,7 @@ cc_genrule { // Instantiate the dex_bootjars singleton module. dex_bootjars { name: "dex_bootjars", + no_full_install: true, } // Pseudo-test that's run on checkbuilds to ensure that get_clang_version can diff --git a/java/dexpreopt.go b/java/dexpreopt.go index 4fe3664fe..57aaa1a2d 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -541,12 +541,21 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, libName string, dexJa // Use the path of the dex file to determine the library name isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(dexJarStem) + partition := d.installPath.Partition() for _, install := range dexpreoptRule.Installs() { // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT. installDir := strings.TrimPrefix(filepath.Dir(install.To), "/") + if strings.HasPrefix(installDir, partition+"/") { + installDir = strings.TrimPrefix(installDir, partition+"/") + } else { + // If the partition for the installDir is different from the install partition, set the + // partition empty to install the dexpreopt files to the desired partition. + // TODO(b/346439786): Define and use the dexpreopt module type to avoid this mismatch. + partition = "" + } installBase := filepath.Base(install.To) arch := filepath.Base(installDir) - installPath := android.PathForModuleInPartitionInstall(ctx, "", installDir) + installPath := android.PathForModuleInPartitionInstall(ctx, partition, installDir) isProfile := strings.HasSuffix(installBase, ".prof") if isProfile { @@ -580,6 +589,37 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, libName string, dexJa } } +func getModuleInstallPathInfo(ctx android.ModuleContext, fullInstallPath string) (android.InstallPath, string, string) { + installPath := android.PathForModuleInstall(ctx) + installDir, installBase := filepath.Split(strings.TrimPrefix(fullInstallPath, "/")) + + if !strings.HasPrefix(installDir, installPath.Partition()+"/") { + // Return empty filename if the install partition is not for the target image. + return installPath, "", "" + } + relDir, err := filepath.Rel(installPath.Partition(), installDir) + if err != nil { + panic(err) + } + return installPath, relDir, installBase +} + +// RuleBuilder.Install() adds output-to-install copy pairs to a list for Make. To share this +// information with PackagingSpec in soong, call PackageFile for them. +// The install path and the target install partition of the module must be the same. +func packageFile(ctx android.ModuleContext, install android.RuleBuilderInstall) { + installPath, relDir, name := getModuleInstallPathInfo(ctx, install.To) + // Empty name means the install partition is not for the target image. + // For the system image, files for "apex" and "system_other" are skipped here. + // The skipped "apex" files are for testing only, for example, + // "/apex/art_boot_images/javalib/x86/boot.vdex". + // TODO(b/320196894): Files for "system_other" are skipped because soong creates the system + // image only for now. + if name != "" { + ctx.PackageFile(installPath.Join(ctx, relDir), name, install.From) + } +} + func (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall { return d.builtInstalledForApex } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 7229ca02d..defa82c0c 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -612,6 +612,9 @@ func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContex profileInstalls: profileInstalls, profileLicenseMetadataFile: android.OptionalPathForPath(ctx.LicenseMetadataFile()), }) + for _, install := range profileInstalls { + packageFile(ctx, install) + } } } @@ -929,6 +932,35 @@ func getApexNameToApexExportsInfoMap(ctx android.ModuleContext) apexNameToApexEx return apexNameToApexExportsInfoMap } +func packageFileForTargetImage(ctx android.ModuleContext, image *bootImageVariant) { + if image.target.Os != ctx.Os() { + // This is not for the target device. + return + } + + for _, install := range image.installs { + packageFile(ctx, install) + } + + for _, install := range image.vdexInstalls { + if image.target.Arch.ArchType.Name != ctx.DeviceConfig().DeviceArch() { + // Note that the vdex files are identical between architectures. If the target image is + // not for the primary architecture create symlinks to share the vdex of the primary + // architecture with the other architectures. + // + // Assuming that the install path has the architecture name with it, replace the + // architecture name with the primary architecture name to find the source vdex file. + installPath, relDir, name := getModuleInstallPathInfo(ctx, install.To) + if name != "" { + srcRelDir := strings.Replace(relDir, image.target.Arch.ArchType.Name, ctx.DeviceConfig().DeviceArch(), 1) + ctx.InstallSymlink(installPath.Join(ctx, relDir), name, installPath.Join(ctx, srcRelDir, name)) + } + } else { + packageFile(ctx, install) + } + } +} + // Generate boot image build rules for a specific target. func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) bootImageVariantOutputs { @@ -1123,6 +1155,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p image.installs = rule.Installs() image.vdexInstalls = vdexInstalls image.unstrippedInstalls = unstrippedInstalls + packageFileForTargetImage(ctx, image) // Only set the licenseMetadataFile from the active module. if isActiveModule(ctx, ctx.Module()) {