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

Commit cf52e102 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes from topic "dex2oat-soong-dep"

* changes:
  Get the dex2oat host tool path from module dependency on the binary module.
  Move the Once cache for dexpreopt.GlobalConfig into the dexpreopt package.
  Separate dexpreopt.GlobalSoongConfig to allow independent caching of it.
parents a8c82cc2 335d5963
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ bootstrap_go_package {
    srcs: [
        "config.go",
        "dexpreopt.go",
        "testing.go",
    ],
    testSrcs: [
        "dexpreopt_test.go",
+200 −35
Original line number Diff line number Diff line
@@ -16,14 +16,16 @@ package dexpreopt

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/google/blueprint"

	"android/soong/android"
)

// GlobalConfig stores the configuration for dex preopting. The fields are set
// from product variables via dex_preopt_config.mk, except for SoongConfig
// which come from CreateGlobalSoongConfig.
// from product variables via dex_preopt_config.mk.
type GlobalConfig struct {
	DisablePreopt        bool     // disable preopt for all modules
	DisablePreoptModules []string // modules with preopt disabled by product-specific config
@@ -82,8 +84,6 @@ type GlobalConfig struct {
	BootFlags         string               // extra flags to pass to dex2oat for the boot image
	Dex2oatImageXmx   string               // max heap size for dex2oat for the boot image
	Dex2oatImageXms   string               // initial heap size for dex2oat for the boot image

	SoongConfig GlobalSoongConfig // settings read from dexpreopt_soong.config
}

// GlobalSoongConfig contains the global config that is generated from Soong,
@@ -179,12 +179,9 @@ func constructWritablePath(ctx android.PathContext, path string) android.Writabl
	return constructPath(ctx, path).(android.WritablePath)
}

// LoadGlobalConfig reads the global dexpreopt.config file into a GlobalConfig
// struct, except the SoongConfig field which is set from the provided
// soongConfig argument. LoadGlobalConfig is used directly in Soong and in
// dexpreopt_gen called from Make to read the $OUT/dexpreopt.config written by
// Make.
func LoadGlobalConfig(ctx android.PathContext, data []byte, soongConfig GlobalSoongConfig) (GlobalConfig, error) {
// ParseGlobalConfig parses the given data assumed to be read from the global
// dexpreopt.config file into a GlobalConfig struct.
func ParseGlobalConfig(ctx android.PathContext, data []byte) (GlobalConfig, error) {
	type GlobalJSONConfig struct {
		GlobalConfig

@@ -204,17 +201,68 @@ func LoadGlobalConfig(ctx android.PathContext, data []byte, soongConfig GlobalSo
	config.GlobalConfig.DirtyImageObjects = android.OptionalPathForPath(constructPath(ctx, config.DirtyImageObjects))
	config.GlobalConfig.BootImageProfiles = constructPaths(ctx, config.BootImageProfiles)

	// Set this here to force the caller to provide a value for this struct (from
	// either CreateGlobalSoongConfig or LoadGlobalSoongConfig).
	config.GlobalConfig.SoongConfig = soongConfig

	return config.GlobalConfig, nil
}

// LoadModuleConfig reads a per-module dexpreopt.config file into a ModuleConfig struct.  It is not used in Soong, which
// receives a ModuleConfig struct directly from java/dexpreopt.go.  It is used in dexpreopt_gen called from oMake to
// read the module dexpreopt.config written by Make.
func LoadModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) {
type globalConfigAndRaw struct {
	global GlobalConfig
	data   []byte
}

// GetGlobalConfig returns the global dexpreopt.config that's created in the
// make config phase. It is loaded once the first time it is called for any
// ctx.Config(), and returns the same data for all future calls with the same
// ctx.Config(). A value can be inserted for tests using
// setDexpreoptTestGlobalConfig.
func GetGlobalConfig(ctx android.PathContext) GlobalConfig {
	return getGlobalConfigRaw(ctx).global
}

// GetGlobalConfigRawData is the same as GetGlobalConfig, except that it returns
// the literal content of dexpreopt.config.
func GetGlobalConfigRawData(ctx android.PathContext) []byte {
	return getGlobalConfigRaw(ctx).data
}

var globalConfigOnceKey = android.NewOnceKey("DexpreoptGlobalConfig")
var testGlobalConfigOnceKey = android.NewOnceKey("TestDexpreoptGlobalConfig")

func getGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
	return ctx.Config().Once(globalConfigOnceKey, func() interface{} {
		if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
			panic(err)
		} else if data != nil {
			globalConfig, err := ParseGlobalConfig(ctx, data)
			if err != nil {
				panic(err)
			}
			return globalConfigAndRaw{globalConfig, data}
		}

		// No global config filename set, see if there is a test config set
		return ctx.Config().Once(testGlobalConfigOnceKey, func() interface{} {
			// Nope, return a config with preopting disabled
			return globalConfigAndRaw{GlobalConfig{
				DisablePreopt:          true,
				DisableGenerateProfile: true,
			}, nil}
		})
	}).(globalConfigAndRaw)
}

// SetTestGlobalConfig sets a GlobalConfig that future calls to GetGlobalConfig
// will return. It must be called before the first call to GetGlobalConfig for
// the config.
func SetTestGlobalConfig(config android.Config, globalConfig GlobalConfig) {
	config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} })
}

// ParseModuleConfig parses a per-module dexpreopt.config file into a
// ModuleConfig struct. It is not used in Soong, which receives a ModuleConfig
// struct directly from java/dexpreopt.go. It is used in dexpreopt_gen called
// from Make to read the module dexpreopt.config written in the Make config
// stage.
func ParseModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error) {
	type ModuleJSONConfig struct {
		ModuleConfig

@@ -253,21 +301,84 @@ func LoadModuleConfig(ctx android.PathContext, data []byte) (ModuleConfig, error
	return config.ModuleConfig, nil
}

// CreateGlobalSoongConfig creates a GlobalSoongConfig from the current context.
// Should not be used in dexpreopt_gen.
func CreateGlobalSoongConfig(ctx android.PathContext) GlobalSoongConfig {
	// Default to debug version to help find bugs.
// dex2oatModuleName returns the name of the module to use for the dex2oat host
// tool. It should be a binary module with public visibility that is compiled
// and installed for host.
func dex2oatModuleName(config android.Config) string {
	// Default to the debug variant of dex2oat to help find bugs.
	// Set USE_DEX2OAT_DEBUG to false for only building non-debug versions.
	var dex2oatBinary string
	if ctx.Config().Getenv("USE_DEX2OAT_DEBUG") == "false" {
		dex2oatBinary = "dex2oat"
	if config.Getenv("USE_DEX2OAT_DEBUG") == "false" {
		return "dex2oat"
	} else {
		dex2oatBinary = "dex2oatd"
		return "dex2oatd"
	}
}

var dex2oatDepTag = struct {
	blueprint.BaseDependencyTag
}{}

type DexPreoptModule interface {
	dexPreoptModuleSignature() // Not called - only for type detection.
}

// RegisterToolDepsMutator registers a mutator that adds the necessary
// dependencies to binary modules for tools that are required later when
// Get(Cached)GlobalSoongConfig is called. It should be passed to
// android.RegistrationContext.FinalDepsMutators, and module types that need
// dependencies also need to embed DexPreoptModule.
func RegisterToolDepsMutator(ctx android.RegisterMutatorsContext) {
	ctx.BottomUp("dexpreopt_tool_deps", toolDepsMutator).Parallel()
}

func toolDepsMutator(ctx android.BottomUpMutatorContext) {
	if GetGlobalConfig(ctx).DisablePreopt {
		// Only register dependencies if dexpreopting is enabled. Necessary to avoid
		// them in non-platform builds where dex2oat etc isn't available.
		//
		// It would be nice to not register this mutator at all then, but
		// RegisterMutatorsContext available at registration doesn't have the state
		// necessary to pass as PathContext to constructPath etc.
		return
	}
	if _, ok := ctx.Module().(DexPreoptModule); !ok {
		return
	}
	dex2oatBin := dex2oatModuleName(ctx.Config())
	v := ctx.Config().BuildOSTarget.Variations()
	ctx.AddFarVariationDependencies(v, dex2oatDepTag, dex2oatBin)
}

func dex2oatPathFromDep(ctx android.ModuleContext) android.Path {
	dex2oatBin := dex2oatModuleName(ctx.Config())

	dex2oatModule := ctx.GetDirectDepWithTag(dex2oatBin, dex2oatDepTag)
	if dex2oatModule == nil {
		// If this happens there's probably a missing call to AddToolDeps in DepsMutator.
		panic(fmt.Sprintf("Failed to lookup %s dependency", dex2oatBin))
	}

	dex2oatPath := dex2oatModule.(android.HostToolProvider).HostToolPath()
	if !dex2oatPath.Valid() {
		panic(fmt.Sprintf("Failed to find host tool path in %s", dex2oatModule))
	}

	return dex2oatPath.Path()
}

// createGlobalSoongConfig creates a GlobalSoongConfig from the current context.
// Should not be used in dexpreopt_gen.
func createGlobalSoongConfig(ctx android.ModuleContext) GlobalSoongConfig {
	if ctx.Config().TestProductVariables != nil {
		// If we're called in a test there'll be a confusing error from the path
		// functions below that gets reported without a stack trace, so let's panic
		// properly with a more helpful message.
		panic("This should not be called from tests. Please call GlobalSoongConfigForTests somewhere in the test setup.")
	}

	return GlobalSoongConfig{
		Profman:          ctx.Config().HostToolPath(ctx, "profman"),
		Dex2oat:          ctx.Config().HostToolPath(ctx, dex2oatBinary),
		Dex2oat:          dex2oatPathFromDep(ctx),
		Aapt:             ctx.Config().HostToolPath(ctx, "aapt"),
		SoongZip:         ctx.Config().HostToolPath(ctx, "soong_zip"),
		Zip2zip:          ctx.Config().HostToolPath(ctx, "zip2zip"),
@@ -276,6 +387,44 @@ func CreateGlobalSoongConfig(ctx android.PathContext) GlobalSoongConfig {
	}
}

// The main reason for this Once cache for GlobalSoongConfig is to make the
// dex2oat path available to singletons. In ordinary modules we get it through a
// dex2oatDepTag dependency, but in singletons there's no simple way to do the
// same thing and ensure the right variant is selected, hence this cache to make
// the resolved path available to singletons. This means we depend on there
// being at least one ordinary module with a dex2oatDepTag dependency.
//
// TODO(b/147613152): Implement a way to deal with dependencies from singletons,
// and then possibly remove this cache altogether (but the use in
// GlobalSoongConfigForTests also needs to be rethought).
var globalSoongConfigOnceKey = android.NewOnceKey("DexpreoptGlobalSoongConfig")

// GetGlobalSoongConfig creates a GlobalSoongConfig the first time it's called,
// and later returns the same cached instance.
func GetGlobalSoongConfig(ctx android.ModuleContext) GlobalSoongConfig {
	globalSoong := ctx.Config().Once(globalSoongConfigOnceKey, func() interface{} {
		return createGlobalSoongConfig(ctx)
	}).(GlobalSoongConfig)

	// Always resolve the tool path from the dependency, to ensure that every
	// module has the dependency added properly.
	myDex2oat := dex2oatPathFromDep(ctx)
	if myDex2oat != globalSoong.Dex2oat {
		panic(fmt.Sprintf("Inconsistent dex2oat path in cached config: expected %s, got %s", globalSoong.Dex2oat, myDex2oat))
	}

	return globalSoong
}

// GetCachedGlobalSoongConfig returns a cached GlobalSoongConfig created by an
// earlier GetGlobalSoongConfig call. This function works with any context
// compatible with a basic PathContext, since it doesn't try to create a
// GlobalSoongConfig (which requires a full ModuleContext). It will panic if
// called before the first GetGlobalSoongConfig call.
func GetCachedGlobalSoongConfig(ctx android.PathContext) GlobalSoongConfig {
	return ctx.Config().Get(globalSoongConfigOnceKey).(GlobalSoongConfig)
}

type globalJsonSoongConfig struct {
	Profman          string
	Dex2oat          string
@@ -286,9 +435,10 @@ type globalJsonSoongConfig struct {
	ConstructContext string
}

// LoadGlobalSoongConfig reads the dexpreopt_soong.config file into a
// GlobalSoongConfig struct. It is only used in dexpreopt_gen.
func LoadGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) {
// ParseGlobalSoongConfig parses the given data assumed to be read from the
// global dexpreopt_soong.config file into a GlobalSoongConfig struct. It is
// only used in dexpreopt_gen.
func ParseGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongConfig, error) {
	var jc globalJsonSoongConfig

	err := json.Unmarshal(data, &jc)
@@ -310,7 +460,11 @@ func LoadGlobalSoongConfig(ctx android.PathContext, data []byte) (GlobalSoongCon
}

func (s *globalSoongConfigSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	config := CreateGlobalSoongConfig(ctx)
	if GetGlobalConfig(ctx).DisablePreopt {
		return
	}

	config := GetCachedGlobalSoongConfig(ctx)
	jc := globalJsonSoongConfig{
		Profman:          config.Profman.String(),
		Dex2oat:          config.Dex2oat.String(),
@@ -337,7 +491,11 @@ func (s *globalSoongConfigSingleton) GenerateBuildActions(ctx android.SingletonC
}

func (s *globalSoongConfigSingleton) MakeVars(ctx android.MakeVarsContext) {
	config := CreateGlobalSoongConfig(ctx)
	if GetGlobalConfig(ctx).DisablePreopt {
		return
	}

	config := GetCachedGlobalSoongConfig(ctx)

	ctx.Strict("DEX2OAT", config.Dex2oat.String())
	ctx.Strict("DEXPREOPT_GEN_DEPS", strings.Join([]string{
@@ -390,7 +548,14 @@ func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
		BootFlags:                          "",
		Dex2oatImageXmx:                    "",
		Dex2oatImageXms:                    "",
		SoongConfig: GlobalSoongConfig{
	}
}

func GlobalSoongConfigForTests(config android.Config) GlobalSoongConfig {
	// Install the test GlobalSoongConfig in the Once cache so that later calls to
	// Get(Cached)GlobalSoongConfig returns it without trying to create a real one.
	return config.Once(globalSoongConfigOnceKey, func() interface{} {
		return GlobalSoongConfig{
			Profman:          android.PathForTesting("profman"),
			Dex2oat:          android.PathForTesting("dex2oat"),
			Aapt:             android.PathForTesting("aapt"),
@@ -398,6 +563,6 @@ func GlobalConfigForTests(ctx android.PathContext) GlobalConfig {
			Zip2zip:          android.PathForTesting("zip2zip"),
			ManifestCheck:    android.PathForTesting("manifest_check"),
			ConstructContext: android.PathForTesting("construct_context.sh"),
		},
		}
	}).(GlobalSoongConfig)
}
+18 −17
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ const SystemOtherPartition = "/system_other/"

// GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a
// ModuleConfig.  The produced files and their install locations will be available through rule.Installs().
func GenerateDexpreoptRule(ctx android.PathContext,
func GenerateDexpreoptRule(ctx android.PathContext, globalSoong GlobalSoongConfig,
	global GlobalConfig, module ModuleConfig) (rule *android.RuleBuilder, err error) {

	defer func() {
@@ -72,10 +72,10 @@ func GenerateDexpreoptRule(ctx android.PathContext,

	var profile android.WritablePath
	if generateProfile {
		profile = profileCommand(ctx, global, module, rule)
		profile = profileCommand(ctx, globalSoong, global, module, rule)
	}
	if generateBootProfile {
		bootProfileCommand(ctx, global, module, rule)
		bootProfileCommand(ctx, globalSoong, global, module, rule)
	}

	if !dexpreoptDisabled(global, module) {
@@ -87,7 +87,7 @@ func GenerateDexpreoptRule(ctx android.PathContext,
			generateDM := shouldGenerateDM(module, global)

			for archIdx, _ := range module.Archs {
				dexpreoptCommand(ctx, global, module, rule, archIdx, profile, appImage, generateDM)
				dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, profile, appImage, generateDM)
			}
		}
	}
@@ -119,8 +119,8 @@ func dexpreoptDisabled(global GlobalConfig, module ModuleConfig) bool {
	return false
}

func profileCommand(ctx android.PathContext, global GlobalConfig, module ModuleConfig,
	rule *android.RuleBuilder) android.WritablePath {
func profileCommand(ctx android.PathContext, globalSoong GlobalSoongConfig, global GlobalConfig,
	module ModuleConfig, rule *android.RuleBuilder) android.WritablePath {

	profilePath := module.BuildPath.InSameDir(ctx, "profile.prof")
	profileInstalledPath := module.DexLocation + ".prof"
@@ -131,7 +131,7 @@ func profileCommand(ctx android.PathContext, global GlobalConfig, module ModuleC

	cmd := rule.Command().
		Text(`ANDROID_LOG_TAGS="*:e"`).
		Tool(global.SoongConfig.Profman)
		Tool(globalSoong.Profman)

	if module.ProfileIsTextListing {
		// The profile is a test listing of classes (used for framework jars).
@@ -158,8 +158,8 @@ func profileCommand(ctx android.PathContext, global GlobalConfig, module ModuleC
	return profilePath
}

func bootProfileCommand(ctx android.PathContext, global GlobalConfig, module ModuleConfig,
	rule *android.RuleBuilder) android.WritablePath {
func bootProfileCommand(ctx android.PathContext, globalSoong GlobalSoongConfig, global GlobalConfig,
	module ModuleConfig, rule *android.RuleBuilder) android.WritablePath {

	profilePath := module.BuildPath.InSameDir(ctx, "profile.bprof")
	profileInstalledPath := module.DexLocation + ".bprof"
@@ -170,7 +170,7 @@ func bootProfileCommand(ctx android.PathContext, global GlobalConfig, module Mod

	cmd := rule.Command().
		Text(`ANDROID_LOG_TAGS="*:e"`).
		Tool(global.SoongConfig.Profman)
		Tool(globalSoong.Profman)

	// The profile is a test listing of methods.
	// We need to generate the actual binary profile.
@@ -190,8 +190,9 @@ func bootProfileCommand(ctx android.PathContext, global GlobalConfig, module Mod
	return profilePath
}

func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module ModuleConfig, rule *android.RuleBuilder,
	archIdx int, profile android.WritablePath, appImage bool, generateDM bool) {
func dexpreoptCommand(ctx android.PathContext, globalSoong GlobalSoongConfig, global GlobalConfig,
	module ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
	appImage bool, generateDM bool) {

	arch := module.Archs[archIdx]

@@ -299,14 +300,14 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
	if module.EnforceUsesLibraries {
		if module.ManifestPath != nil {
			rule.Command().Text(`target_sdk_version="$(`).
				Tool(global.SoongConfig.ManifestCheck).
				Tool(globalSoong.ManifestCheck).
				Flag("--extract-target-sdk-version").
				Input(module.ManifestPath).
				Text(`)"`)
		} else {
			// No manifest to extract targetSdkVersion from, hope that DexJar is an APK
			rule.Command().Text(`target_sdk_version="$(`).
				Tool(global.SoongConfig.Aapt).
				Tool(globalSoong.Aapt).
				Flag("dump badging").
				Input(module.DexPath).
				Text(`| grep "targetSdkVersion" | sed -n "s/targetSdkVersion:'\(.*\)'/\1/p"`).
@@ -327,7 +328,7 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
			Implicits(conditionalClassLoaderContextHost29)
		rule.Command().Textf(`conditional_target_libs_29="%s"`,
			strings.Join(conditionalClassLoaderContextTarget29, " "))
		rule.Command().Text("source").Tool(global.SoongConfig.ConstructContext).Input(module.DexPath)
		rule.Command().Text("source").Tool(globalSoong.ConstructContext).Input(module.DexPath)
	}

	// Devices that do not have a product partition use a symlink from /product to /system/product.
@@ -340,7 +341,7 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul

	cmd := rule.Command().
		Text(`ANDROID_LOG_TAGS="*:e"`).
		Tool(global.SoongConfig.Dex2oat).
		Tool(globalSoong.Dex2oat).
		Flag("--avoid-storing-invocation").
		FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath).
		Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatXms).
@@ -409,7 +410,7 @@ func dexpreoptCommand(ctx android.PathContext, global GlobalConfig, module Modul
		dmInstalledPath := pathtools.ReplaceExtension(module.DexLocation, "dm")
		tmpPath := module.BuildPath.InSameDir(ctx, "primary.vdex")
		rule.Command().Text("cp -f").Input(vdexPath).Output(tmpPath)
		rule.Command().Tool(global.SoongConfig.SoongZip).
		rule.Command().Tool(globalSoong.SoongZip).
			FlagWithArg("-L", "9").
			FlagWithOutput("-o", dmPath).
			Flag("-j").
+12 −12
Original line number Diff line number Diff line
@@ -80,13 +80,13 @@ func main() {

	globalSoongConfigData, err := ioutil.ReadFile(*globalSoongConfigPath)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error reading global config %q: %s\n", *globalSoongConfigPath, err)
		fmt.Fprintf(os.Stderr, "error reading global Soong config %q: %s\n", *globalSoongConfigPath, err)
		os.Exit(2)
	}

	globalSoongConfig, err := dexpreopt.LoadGlobalSoongConfig(ctx, globalSoongConfigData)
	globalSoongConfig, err := dexpreopt.ParseGlobalSoongConfig(ctx, globalSoongConfigData)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error loading global config %q: %s\n", *globalSoongConfigPath, err)
		fmt.Fprintf(os.Stderr, "error parsing global Soong config %q: %s\n", *globalSoongConfigPath, err)
		os.Exit(2)
	}

@@ -96,9 +96,9 @@ func main() {
		os.Exit(2)
	}

	globalConfig, err := dexpreopt.LoadGlobalConfig(ctx, globalConfigData, globalSoongConfig)
	globalConfig, err := dexpreopt.ParseGlobalConfig(ctx, globalConfigData)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error parse global config %q: %s\n", *globalConfigPath, err)
		fmt.Fprintf(os.Stderr, "error parsing global config %q: %s\n", *globalConfigPath, err)
		os.Exit(2)
	}

@@ -108,9 +108,9 @@ func main() {
		os.Exit(2)
	}

	moduleConfig, err := dexpreopt.LoadModuleConfig(ctx, moduleConfigData)
	moduleConfig, err := dexpreopt.ParseModuleConfig(ctx, moduleConfigData)
	if err != nil {
		fmt.Fprintf(os.Stderr, "error loading module config %q: %s\n", *moduleConfigPath, err)
		fmt.Fprintf(os.Stderr, "error parsing module config %q: %s\n", *moduleConfigPath, err)
		os.Exit(2)
	}

@@ -130,12 +130,12 @@ func main() {
		}
	}()

	writeScripts(ctx, globalConfig, moduleConfig, *dexpreoptScriptPath)
	writeScripts(ctx, globalSoongConfig, globalConfig, moduleConfig, *dexpreoptScriptPath)
}

func writeScripts(ctx android.PathContext, global dexpreopt.GlobalConfig, module dexpreopt.ModuleConfig,
	dexpreoptScriptPath string) {
	dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, global, module)
func writeScripts(ctx android.PathContext, globalSoong dexpreopt.GlobalSoongConfig,
	global dexpreopt.GlobalConfig, module dexpreopt.ModuleConfig, dexpreoptScriptPath string) {
	dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, globalSoong, global, module)
	if err != nil {
		panic(err)
	}
@@ -150,7 +150,7 @@ func writeScripts(ctx android.PathContext, global dexpreopt.GlobalConfig, module
		dexpreoptRule.Command().Text("mkdir -p").Flag(filepath.Dir(installPath.String()))
		dexpreoptRule.Command().Text("cp -f").Input(install.From).Output(installPath)
	}
	dexpreoptRule.Command().Tool(global.SoongConfig.SoongZip).
	dexpreoptRule.Command().Tool(globalSoong.SoongZip).
		FlagWithArg("-o ", "$2").
		FlagWithArg("-C ", installDir.String()).
		FlagWithArg("-D ", installDir.String())
+16 −8
Original line number Diff line number Diff line
@@ -61,10 +61,13 @@ func testModuleConfig(ctx android.PathContext, name, partition string) ModuleCon
}

func TestDexPreopt(t *testing.T) {
	ctx := android.PathContextForTesting(android.TestConfig("out", nil, "", nil))
	global, module := GlobalConfigForTests(ctx), testSystemModuleConfig(ctx, "test")
	config := android.TestConfig("out", nil, "", nil)
	ctx := android.PathContextForTesting(config)
	globalSoong := GlobalSoongConfigForTests(config)
	global := GlobalConfigForTests(ctx)
	module := testSystemModuleConfig(ctx, "test")

	rule, err := GenerateDexpreoptRule(ctx, global, module)
	rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module)
	if err != nil {
		t.Fatal(err)
	}
@@ -80,7 +83,9 @@ func TestDexPreopt(t *testing.T) {
}

func TestDexPreoptSystemOther(t *testing.T) {
	ctx := android.PathContextForTesting(android.TestConfig("out", nil, "", nil))
	config := android.TestConfig("out", nil, "", nil)
	ctx := android.PathContextForTesting(config)
	globalSoong := GlobalSoongConfigForTests(config)
	global := GlobalConfigForTests(ctx)
	systemModule := testSystemModuleConfig(ctx, "Stest")
	systemProductModule := testSystemProductModuleConfig(ctx, "SPtest")
@@ -118,7 +123,7 @@ func TestDexPreoptSystemOther(t *testing.T) {
	for _, test := range tests {
		global.PatternsOnSystemOther = test.patterns
		for _, mt := range test.moduleTests {
			rule, err := GenerateDexpreoptRule(ctx, global, mt.module)
			rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module)
			if err != nil {
				t.Fatal(err)
			}
@@ -138,12 +143,15 @@ func TestDexPreoptSystemOther(t *testing.T) {
}

func TestDexPreoptProfile(t *testing.T) {
	ctx := android.PathContextForTesting(android.TestConfig("out", nil, "", nil))
	global, module := GlobalConfigForTests(ctx), testSystemModuleConfig(ctx, "test")
	config := android.TestConfig("out", nil, "", nil)
	ctx := android.PathContextForTesting(config)
	globalSoong := GlobalSoongConfigForTests(config)
	global := GlobalConfigForTests(ctx)
	module := testSystemModuleConfig(ctx, "test")

	module.ProfileClassListing = android.OptionalPathForPath(android.PathForTesting("profile"))

	rule, err := GenerateDexpreoptRule(ctx, global, module)
	rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module)
	if err != nil {
		t.Fatal(err)
	}
Loading