From 5b88fe36b5ce34055b28cd904a845bb87709a860 Mon Sep 17 00:00:00 2001 From: Ulya Trafimovich Date: Wed, 11 Mar 2020 11:19:26 +0000 Subject: [PATCH] Share vdex files in the ART apex between architectures (via symlinks). Test: aosp_walleye-userdebug boots. Test: Check symlinks to *.vdex files in the ART apex: $ adb shell 'find /apex/com.android.art -name '*.vdex' | xargs ls -l' lrw-r--r-- 1 system system 23 1970-01-01 01:00 /apex/com.android.art/javalib/arm/boot-apache-xml.vdex -> ../boot-apache-xml.vdex lrw-r--r-- 1 system system 25 1970-01-01 01:00 /apex/com.android.art/javalib/arm/boot-bouncycastle.vdex -> ../boot-bouncycastle.vdex lrw-r--r-- 1 system system 23 1970-01-01 01:00 /apex/com.android.art/javalib/arm/boot-core-icu4j.vdex -> ../boot-core-icu4j.vdex lrw-r--r-- 1 system system 24 1970-01-01 01:00 /apex/com.android.art/javalib/arm/boot-core-libart.vdex -> ../boot-core-libart.vdex lrw-r--r-- 1 system system 19 1970-01-01 01:00 /apex/com.android.art/javalib/arm/boot-okhttp.vdex -> ../boot-okhttp.vdex lrw-r--r-- 1 system system 12 1970-01-01 01:00 /apex/com.android.art/javalib/arm/boot.vdex -> ../boot.vdex lrw-r--r-- 1 system system 23 1970-01-01 01:00 /apex/com.android.art/javalib/arm64/boot-apache-xml.vdex -> ../boot-apache-xml.vdex lrw-r--r-- 1 system system 25 1970-01-01 01:00 /apex/com.android.art/javalib/arm64/boot-bouncycastle.vdex -> ../boot-bouncycastle.vdex lrw-r--r-- 1 system system 23 1970-01-01 01:00 /apex/com.android.art/javalib/arm64/boot-core-icu4j.vdex -> ../boot-core-icu4j.vdex lrw-r--r-- 1 system system 24 1970-01-01 01:00 /apex/com.android.art/javalib/arm64/boot-core-libart.vdex -> ../boot-core-libart.vdex lrw-r--r-- 1 system system 19 1970-01-01 01:00 /apex/com.android.art/javalib/arm64/boot-okhttp.vdex -> ../boot-okhttp.vdex lrw-r--r-- 1 system system 12 1970-01-01 01:00 /apex/com.android.art/javalib/arm64/boot.vdex -> ../boot.vdex -rw-r--r-- 1 system system 1229 1970-01-01 01:00 /apex/com.android.art/javalib/boot-apache-xml.vdex -rw-r--r-- 1 system system 2043 1970-01-01 01:00 /apex/com.android.art/javalib/boot-bouncycastle.vdex -rw-r--r-- 1 system system 2883 1970-01-01 01:00 /apex/com.android.art/javalib/boot-core-icu4j.vdex -rw-r--r-- 1 system system 865 1970-01-01 01:00 /apex/com.android.art/javalib/boot-core-libart.vdex -rw-r--r-- 1 system system 395 1970-01-01 01:00 /apex/com.android.art/javalib/boot-okhttp.vdex -rw-r--r-- 1 system system 7125 1970-01-01 01:00 /apex/com.android.art/javalib/boot.vdex Bug: 150934453 Change-Id: Ifbceb845749f4c218693f4118e8b35b59ff26de1 --- apex/apex.go | 17 ++++++++++++++++- apex/builder.go | 10 +++++++++- java/dexpreopt_bootjars.go | 28 ++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index cddd72b3c..ab6ceff10 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2315,7 +2315,10 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Build rules are generated by the dexpreopt singleton, and here we access build artifacts // via the global boot image config. if a.artApex { - for arch, files := range java.DexpreoptedArtApexJars(ctx) { + artAndOatFiles, vdexFiles := java.DexpreoptedArtApexJars(ctx) + + // Copy *.art and *.oat files to arch-specific subdirectories. + for arch, files := range artAndOatFiles { dirInApex := filepath.Join("javalib", arch.String()) for _, f := range files { localModule := "javalib_" + arch.String() + "_" + filepath.Base(f.String()) @@ -2323,6 +2326,18 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { filesInfo = append(filesInfo, af) } } + + // Copy *.vdex files to a common subdirectory. + for _, file := range vdexFiles { + dirInApex := "javalib" + localModule := "javalib_" + filepath.Base(file.String()) + af := newApexFile(ctx, file, localModule, dirInApex, etc, nil) + // Add a symlink to the *.vdex file for each arch-specific subdirectory. + for arch := range artAndOatFiles { + af.symlinks = append(af.symlinks, filepath.Join(arch.String(), filepath.Base(file.String()))) + } + filesInfo = append(filesInfo, af) + } } if a.private_key_file == nil { diff --git a/apex/builder.go b/apex/builder.go index 464d84377..97be852ce 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -335,6 +335,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { for _, fi := range a.filesInfo { destPath := android.PathForModuleOut(ctx, "image"+suffix, fi.Path()).String() copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(destPath)) + if a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() { // TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here pathOnDevice := filepath.Join("/system", fi.Path()) @@ -343,10 +344,16 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath) implicitInputs = append(implicitInputs, fi.builtFile) } + // create additional symlinks pointing the file inside the APEX for _, symlinkPath := range fi.SymlinkPaths() { symlinkDest := android.PathForModuleOut(ctx, "image"+suffix, symlinkPath).String() - copyCommands = append(copyCommands, "ln -sfn "+filepath.Base(destPath)+" "+symlinkDest) + symlinkTarget, err := filepath.Rel(filepath.Dir(symlinkDest), destPath) + if err != nil { + panic("Cannot compute relative path from " + destPath + " to " + filepath.Dir(symlinkDest)) + } + copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(symlinkDest)) + copyCommands = append(copyCommands, "ln -sfn "+symlinkTarget+" "+symlinkDest) } } @@ -409,6 +416,7 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { } } else { readOnlyPaths = append(readOnlyPaths, pathInApex) + readOnlyPaths = append(readOnlyPaths, f.SymlinkPaths()...) } dir := f.installDir for !android.InList(dir, executablePaths) && dir != "" { diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 7ccf82828..3b6f357d7 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -187,19 +187,31 @@ type dexpreoptBootJars struct { } // Accessor function for the apex package. Returns nil if dexpreopt is disabled. -func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]android.OutputPaths { +func DexpreoptedArtApexJars(ctx android.BuilderContext) (map[android.ArchType]android.OutputPaths, android.OutputPaths) { if skipDexpreoptBootJars(ctx) { - return nil + return nil, nil } - // Include dexpreopt files for the primary boot image. - files := map[android.ArchType]android.OutputPaths{} - for _, variant := range artBootImageConfig(ctx).variants { + + image := artBootImageConfig(ctx) + + // Target-independent boot image files (*.vdex). + anyTarget := image.variants[0].target + vdexDir := image.dir.Join(ctx, anyTarget.Os.String(), image.installSubdir, anyTarget.Arch.ArchType.String()) + vdexFiles := image.moduleFiles(ctx, vdexDir, ".vdex") + + // Target-specific boot image files (*.oat, *.art). + artAndOatFiles := map[android.ArchType]android.OutputPaths{} + for _, variant := range image.variants { // We also generate boot images for host (for testing), but we don't need those in the apex. - if variant.target.Os == android.Android { - files[variant.target.Arch.ArchType] = variant.imagesDeps + os := variant.target.Os + if os == android.Android { + arch := variant.target.Arch.ArchType + archDir := image.dir.Join(ctx, os.String(), image.installSubdir, arch.String()) + artAndOatFiles[arch] = image.moduleFiles(ctx, archDir, ".art", ".oat") } } - return files + + return artAndOatFiles, vdexFiles } // dexpreoptBoot singleton rules