Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4dda75e7 authored by Jeongik Cha's avatar Jeongik Cha
Browse files

Add usesTargetFiles option in dexpreopt_gen

For running dex2oat on the target_files, the paths should be use the
device install path instead of the path starting with $(OUT).
So add usesTargetFiles option and basePath option which indicates
extracted path. With those options, the path is replaced with
$(basePath)/$(device path)

And also, add DexPreoptImageDeviceLocations in the config which refers
to the boot image path(without arch) on the device. Because
DexPreoptImage related device path was missing.

Bug: 158843648
Test: dexpreopt_gen -usesTargetFiles -basePath (extract path) and then
check if paths in the generated shell script are based on on-device
path.

Change-Id: I9667fadbf3b7c6f770e0d1bcbee5d67c1ecd8a3d
parent 015a0afe
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -132,7 +132,9 @@ type ModuleConfig struct {

	Archs               []android.ArchType
	DexPreoptImagesDeps []android.OutputPaths

	DexPreoptImageLocationsOnHost   []string // boot image location on host (file path without the arch subdirectory)
	DexPreoptImageLocationsOnDevice []string // boot image location on device (file path without the arch subdirectory)

	PreoptBootClassPathDexFiles     android.Paths // file paths of boot class path files
	PreoptBootClassPathDexLocations []string      // virtual locations of boot class path files
+7 −2
Original line number Diff line number Diff line
@@ -499,11 +499,16 @@ func odexOnSystemOther(module *ModuleConfig, global *GlobalConfig) bool {

// PathToLocation converts .../system/framework/arm64/boot.art to .../system/framework/boot.art
func PathToLocation(path android.Path, arch android.ArchType) string {
	pathArch := filepath.Base(filepath.Dir(path.String()))
	return PathStringToLocation(path.String(), arch)
}

// PathStringToLocation converts .../system/framework/arm64/boot.art to .../system/framework/boot.art
func PathStringToLocation(path string, arch android.ArchType) string {
	pathArch := filepath.Base(filepath.Dir(path))
	if pathArch != arch.String() {
		panic(fmt.Errorf("last directory in %q must be %q", path, arch.String()))
	}
	return filepath.Join(filepath.Dir(filepath.Dir(path.String())), filepath.Base(path.String()))
	return filepath.Join(filepath.Dir(filepath.Dir(path)), filepath.Base(path))
}

func makefileMatch(pattern, s string) bool {
+47 −21
Original line number Diff line number Diff line
@@ -37,6 +37,12 @@ var (
	globalConfigPath      = flag.String("global", "", "path to global configuration file")
	moduleConfigPath      = flag.String("module", "", "path to module configuration file")
	outDir                = flag.String("out_dir", "", "path to output directory")
	// If uses_target_files is true, dexpreopt_gen will be running on extracted target_files.zip files.
	// In this case, the tool replace output file path with $(basePath)/$(on-device file path).
	// The flag is useful when running dex2oat on system image and vendor image which are built separately.
	usesTargetFiles = flag.Bool("uses_target_files", false, "whether or not dexpreopt is running on target_files")
	// basePath indicates the path where target_files.zip is extracted.
	basePath = flag.String("base_path", ".", "base path where images and tools are extracted")
)

type builderContext struct {
@@ -134,32 +140,28 @@ func main() {
			}
		}
	}()

	if *usesTargetFiles {
		moduleConfig.ManifestPath = android.OptionalPath{}
		prefix := "dex2oat_result"
		moduleConfig.BuildPath = android.PathForOutput(ctx, filepath.Join(prefix, moduleConfig.DexLocation))
		for i, location := range moduleConfig.PreoptBootClassPathDexLocations {
			moduleConfig.PreoptBootClassPathDexFiles[i] = android.PathForSource(ctx, *basePath+location)
		}
		for i := range moduleConfig.ClassLoaderContexts {
			for _, v := range moduleConfig.ClassLoaderContexts[i] {
				v.Host = android.PathForSource(ctx, *basePath+v.Device)
			}
		}
		moduleConfig.EnforceUsesLibraries = false
		for i, location := range moduleConfig.DexPreoptImageLocationsOnDevice {
			moduleConfig.DexPreoptImageLocationsOnHost[i] = *basePath + location
		}
	}
	writeScripts(ctx, globalSoongConfig, globalConfig, moduleConfig, *dexpreoptScriptPath)
}

func writeScripts(ctx android.BuilderContext, globalSoong *dexpreopt.GlobalSoongConfig,
	global *dexpreopt.GlobalConfig, module *dexpreopt.ModuleConfig, dexpreoptScriptPath string) {
	dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, globalSoong, global, module)
	if err != nil {
		panic(err)
	}

	installDir := module.BuildPath.InSameDir(ctx, "dexpreopt_install")

	dexpreoptRule.Command().FlagWithArg("rm -rf ", installDir.String())
	dexpreoptRule.Command().FlagWithArg("mkdir -p ", installDir.String())

	for _, install := range dexpreoptRule.Installs() {
		installPath := installDir.Join(ctx, strings.TrimPrefix(install.To, "/"))
		dexpreoptRule.Command().Text("mkdir -p").Flag(filepath.Dir(installPath.String()))
		dexpreoptRule.Command().Text("cp -f").Input(install.From).Output(installPath)
	}
	dexpreoptRule.Command().Tool(globalSoong.SoongZip).
		FlagWithArg("-o ", "$2").
		FlagWithArg("-C ", installDir.String()).
		FlagWithArg("-D ", installDir.String())

	write := func(rule *android.RuleBuilder, file string) {
		script := &bytes.Buffer{}
		script.WriteString(scriptHeader)
@@ -195,6 +197,30 @@ func writeScripts(ctx android.BuilderContext, globalSoong *dexpreopt.GlobalSoong
			panic(err)
		}
	}
	dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, globalSoong, global, module)
	if err != nil {
		panic(err)
	}
	// When usesTargetFiles is true, only odex/vdex files are necessary.
	// So skip redunant processes(such as copying the result to the artifact path, and zipping, and so on.)
	if *usesTargetFiles {
		write(dexpreoptRule, dexpreoptScriptPath)
		return
	}
	installDir := module.BuildPath.InSameDir(ctx, "dexpreopt_install")

	dexpreoptRule.Command().FlagWithArg("rm -rf ", installDir.String())
	dexpreoptRule.Command().FlagWithArg("mkdir -p ", installDir.String())

	for _, install := range dexpreoptRule.Installs() {
		installPath := installDir.Join(ctx, strings.TrimPrefix(install.To, "/"))
		dexpreoptRule.Command().Text("mkdir -p").Flag(filepath.Dir(installPath.String()))
		dexpreoptRule.Command().Text("cp -f").Input(install.From).Output(installPath)
	}
	dexpreoptRule.Command().Tool(globalSoong.SoongZip).
		FlagWithArg("-o ", "$2").
		FlagWithArg("-C ", installDir.String()).
		FlagWithArg("-D ", installDir.String())

	// The written scripts will assume the input is $1 and the output is $2
	if module.DexPath.String() != "$1" {
+5 −4
Original line number Diff line number Diff line
@@ -184,7 +184,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
		imagesDeps = append(imagesDeps, variant.imagesDeps)
	}
	// The image locations for all Android variants are identical.
	hostImageLocations := bootImage.getAnyAndroidVariant().imageLocations()
	hostImageLocations, deviceImageLocations := bootImage.getAnyAndroidVariant().imageLocations()

	var profileClassListing android.OptionalPath
	var profileBootListing android.OptionalPath
@@ -227,6 +227,7 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr
		Archs:                           archs,
		DexPreoptImagesDeps:             imagesDeps,
		DexPreoptImageLocationsOnHost:   hostImageLocations,
		DexPreoptImageLocationsOnDevice: deviceImageLocations,

		PreoptBootClassPathDexFiles:     dexFiles.Paths(),
		PreoptBootClassPathDexLocations: dexLocations,
+14 −8
Original line number Diff line number Diff line
@@ -244,6 +244,9 @@ type bootImageConfig struct {
	// Subdirectory where the image files are installed.
	installDirOnHost string

	// Subdirectory where the image files on device are installed.
	installDirOnDevice string

	// A list of (location, jar) pairs for the Java modules in this image.
	modules android.ConfiguredJarList

@@ -273,7 +276,8 @@ type bootImageVariant struct {
	dexLocationsDeps []string // for the dependency images and in this image

	// Paths to image files.
	imagePathOnHost android.OutputPath  // first image file
	imagePathOnHost   android.OutputPath  // first image file path on host
	imagePathOnDevice string              // first image file path on device
	imagesDeps        android.OutputPaths // all files

	// Only for extensions, paths to the primary boot images.
@@ -361,11 +365,12 @@ func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.Ou
// The location is passed as an argument to the ART tools like dex2oat instead of the real path.
// ART tools will then reconstruct the architecture-specific real path.
//
func (image *bootImageVariant) imageLocations() (imageLocations []string) {
func (image *bootImageVariant) imageLocations() (imageLocationsOnHost []string, imageLocationsOnDevice []string) {
	if image.extends != nil {
		imageLocations = image.extends.getVariant(image.target).imageLocations()
		imageLocationsOnHost, imageLocationsOnDevice = image.extends.getVariant(image.target).imageLocations()
	}
	return append(imageLocations, dexpreopt.PathToLocation(image.imagePathOnHost, image.target.Arch.ArchType))
	return append(imageLocationsOnHost, dexpreopt.PathToLocation(image.imagePathOnHost, image.target.Arch.ArchType)),
		append(imageLocationsOnDevice, dexpreopt.PathStringToLocation(image.imagePathOnDevice, image.target.Arch.ArchType))
}

func dexpreoptBootJarsFactory() android.SingletonModule {
@@ -873,12 +878,13 @@ func dumpOatRules(ctx android.ModuleContext, image *bootImageConfig) {
		// Create a rule to call oatdump.
		output := android.PathForOutput(ctx, "boot."+suffix+".oatdump.txt")
		rule := android.NewRuleBuilder(pctx, ctx)
		imageLocationsOnHost, _ := image.imageLocations()
		rule.Command().
			// TODO: for now, use the debug version for better error reporting
			BuiltTool("oatdumpd").
			FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":").
			FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":").
			FlagWithArg("--image=", strings.Join(image.imageLocations(), ":")).Implicits(image.imagesDeps.Paths()).
			FlagWithArg("--image=", strings.Join(imageLocationsOnHost, ":")).Implicits(image.imagesDeps.Paths()).
			FlagWithOutput("--output=", output).
			FlagWithArg("--instruction-set=", arch.String())
		rule.Build("dump-oat-boot-"+suffix, "dump oat boot "+arch.String())
@@ -948,8 +954,8 @@ func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) {
				ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, variant.installs.String())
				ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, variant.unstrippedInstalls.String())
			}
			imageLocations := current.getAnyAndroidVariant().imageLocations()
			ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(imageLocations, ":"))
			imageLocationsOnHost, _ := current.getAnyAndroidVariant().imageLocations()
			ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_"+current.name, strings.Join(imageLocationsOnHost, ":"))
			ctx.Strict("DEXPREOPT_IMAGE_ZIP_"+current.name, current.zip.String())
		}
		ctx.Strict("DEXPREOPT_IMAGE_NAMES", strings.Join(imageNames, " "))
Loading