diff --git a/android/androidmk.go b/android/androidmk.go
index fc628cb..2185e45 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -806,15 +806,21 @@
 
 	// Additional cases here require review for correct license propagation to make.
 	var err error
-	switch x := mod.(type) {
-	case AndroidMkDataProvider:
-		err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x)
-	case bootstrap.GoBinaryTool:
-		err = translateGoBinaryModule(ctx, w, mod, x)
-	case AndroidMkEntriesProvider:
-		err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x)
-	default:
-		// Not exported to make so no make variables to set.
+
+	if info, ok := ctx.otherModuleProvider(mod, AndroidMkInfoProvider); ok {
+		androidMkEntriesInfos := info.(*AndroidMkProviderInfo)
+		err = translateAndroidMkEntriesInfoModule(ctx, w, moduleInfoJSONs, mod, androidMkEntriesInfos)
+	} else {
+		switch x := mod.(type) {
+		case AndroidMkDataProvider:
+			err = translateAndroidModule(ctx, w, moduleInfoJSONs, mod, x)
+		case bootstrap.GoBinaryTool:
+			err = translateGoBinaryModule(ctx, w, mod, x)
+		case AndroidMkEntriesProvider:
+			err = translateAndroidMkEntriesModule(ctx, w, moduleInfoJSONs, mod, x)
+		default:
+			// Not exported to make so no make variables to set.
+		}
 	}
 
 	if err != nil {
@@ -1063,3 +1069,564 @@
 	}
 	fmt.Fprintln(w)
 }
+
+type AndroidMkProviderInfo struct {
+	PrimaryInfo AndroidMkInfo
+	ExtraInfo   []AndroidMkInfo
+}
+
+type AndroidMkInfo struct {
+	// Android.mk class string, e.g. EXECUTABLES, JAVA_LIBRARIES, ETC
+	Class string
+	// Optional suffix to append to the module name. Useful when a module wants to return multiple
+	// AndroidMkEntries objects. For example, when a java_library returns an additional entry for
+	// its hostdex sub-module, this SubName field is set to "-hostdex" so that it can have a
+	// different name than the parent's.
+	SubName string
+	// If set, this value overrides the base module name. SubName is still appended.
+	OverrideName string
+	// Dist files to output
+	DistFiles TaggedDistFiles
+	// The output file for Kati to process and/or install. If absent, the module is skipped.
+	OutputFile OptionalPath
+	// If true, the module is skipped and does not appear on the final Android-<product name>.mk
+	// file. Useful when a module needs to be skipped conditionally.
+	Disabled bool
+	// The postprocessing mk file to include, e.g. $(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk
+	// If not set, $(BUILD_SYSTEM)/prebuilt.mk is used.
+	Include string
+	// Required modules that need to be built and included in the final build output when building
+	// this module.
+	Required []string
+	// Required host modules that need to be built and included in the final build output when
+	// building this module.
+	Host_required []string
+	// Required device modules that need to be built and included in the final build output when
+	// building this module.
+	Target_required []string
+
+	HeaderStrings []string
+	FooterStrings []string
+
+	// A map that holds the up-to-date Make variable values. Can be accessed from tests.
+	EntryMap map[string][]string
+	// A list of EntryMap keys in insertion order. This serves a few purposes:
+	// 1. Prevents churns. Golang map doesn't provide consistent iteration order, so without this,
+	// the outputted Android-*.mk file may change even though there have been no content changes.
+	// 2. Allows modules to refer to other variables, like LOCAL_BAR_VAR := $(LOCAL_FOO_VAR),
+	// without worrying about the variables being mixed up in the actual mk file.
+	// 3. Makes troubleshooting and spotting errors easier.
+	EntryOrder []string
+}
+
+// TODO: rename it to AndroidMkEntriesProvider after AndroidMkEntriesProvider interface is gone.
+var AndroidMkInfoProvider = blueprint.NewProvider[*AndroidMkProviderInfo]()
+
+func translateAndroidMkEntriesInfoModule(ctx SingletonContext, w io.Writer, moduleInfoJSONs *[]*ModuleInfoJSON,
+	mod blueprint.Module, providerInfo *AndroidMkProviderInfo) error {
+	if shouldSkipAndroidMkProcessing(ctx, mod.(Module).base()) {
+		return nil
+	}
+
+	// Deep copy the provider info since we need to modify the info later
+	info := deepCopyAndroidMkProviderInfo(providerInfo)
+
+	aconfigUpdateAndroidMkInfos(ctx, mod.(Module), &info)
+
+	// Any new or special cases here need review to verify correct propagation of license information.
+	info.PrimaryInfo.fillInEntries(ctx, mod)
+	info.PrimaryInfo.write(w)
+	if len(info.ExtraInfo) > 0 {
+		for _, ei := range info.ExtraInfo {
+			ei.fillInEntries(ctx, mod)
+			ei.write(w)
+		}
+	}
+
+	if !info.PrimaryInfo.disabled() {
+		if moduleInfoJSON, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+			*moduleInfoJSONs = append(*moduleInfoJSONs, moduleInfoJSON)
+		}
+	}
+
+	return nil
+}
+
+// Utility funcs to manipulate Android.mk variable entries.
+
+// SetString sets a Make variable with the given name to the given value.
+func (a *AndroidMkInfo) SetString(name, value string) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = []string{value}
+}
+
+// SetPath sets a Make variable with the given name to the given path string.
+func (a *AndroidMkInfo) SetPath(name string, path Path) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = []string{path.String()}
+}
+
+// SetOptionalPath sets a Make variable with the given name to the given path string if it is valid.
+// It is a no-op if the given path is invalid.
+func (a *AndroidMkInfo) SetOptionalPath(name string, path OptionalPath) {
+	if path.Valid() {
+		a.SetPath(name, path.Path())
+	}
+}
+
+// AddPath appends the given path string to a Make variable with the given name.
+func (a *AndroidMkInfo) AddPath(name string, path Path) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = append(a.EntryMap[name], path.String())
+}
+
+// AddOptionalPath appends the given path string to a Make variable with the given name if it is
+// valid. It is a no-op if the given path is invalid.
+func (a *AndroidMkInfo) AddOptionalPath(name string, path OptionalPath) {
+	if path.Valid() {
+		a.AddPath(name, path.Path())
+	}
+}
+
+// SetPaths sets a Make variable with the given name to a slice of the given path strings.
+func (a *AndroidMkInfo) SetPaths(name string, paths Paths) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = paths.Strings()
+}
+
+// SetOptionalPaths sets a Make variable with the given name to a slice of the given path strings
+// only if there are a non-zero amount of paths.
+func (a *AndroidMkInfo) SetOptionalPaths(name string, paths Paths) {
+	if len(paths) > 0 {
+		a.SetPaths(name, paths)
+	}
+}
+
+// AddPaths appends the given path strings to a Make variable with the given name.
+func (a *AndroidMkInfo) AddPaths(name string, paths Paths) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = append(a.EntryMap[name], paths.Strings()...)
+}
+
+// SetBoolIfTrue sets a Make variable with the given name to true if the given flag is true.
+// It is a no-op if the given flag is false.
+func (a *AndroidMkInfo) SetBoolIfTrue(name string, flag bool) {
+	if flag {
+		if _, ok := a.EntryMap[name]; !ok {
+			a.EntryOrder = append(a.EntryOrder, name)
+		}
+		a.EntryMap[name] = []string{"true"}
+	}
+}
+
+// SetBool sets a Make variable with the given name to if the given bool flag value.
+func (a *AndroidMkInfo) SetBool(name string, flag bool) {
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	if flag {
+		a.EntryMap[name] = []string{"true"}
+	} else {
+		a.EntryMap[name] = []string{"false"}
+	}
+}
+
+// AddStrings appends the given strings to a Make variable with the given name.
+func (a *AndroidMkInfo) AddStrings(name string, value ...string) {
+	if len(value) == 0 {
+		return
+	}
+	if _, ok := a.EntryMap[name]; !ok {
+		a.EntryOrder = append(a.EntryOrder, name)
+	}
+	a.EntryMap[name] = append(a.EntryMap[name], value...)
+}
+
+// AddCompatibilityTestSuites adds the supplied test suites to the EntryMap, with special handling
+// for partial MTS and MCTS test suites.
+func (a *AndroidMkInfo) AddCompatibilityTestSuites(suites ...string) {
+	// M(C)TS supports a full test suite and partial per-module MTS test suites, with naming mts-${MODULE}.
+	// To reduce repetition, if we find a partial M(C)TS test suite without an full M(C)TS test suite,
+	// we add the full test suite to our list.
+	if PrefixInList(suites, "mts-") && !InList("mts", suites) {
+		suites = append(suites, "mts")
+	}
+	if PrefixInList(suites, "mcts-") && !InList("mcts", suites) {
+		suites = append(suites, "mcts")
+	}
+	a.AddStrings("LOCAL_COMPATIBILITY_SUITE", suites...)
+}
+
+func (a *AndroidMkInfo) fillInEntries(ctx fillInEntriesContext, mod blueprint.Module) {
+	helperInfo := AndroidMkInfo{
+		EntryMap: make(map[string][]string),
+	}
+
+	amod := mod.(Module)
+	base := amod.base()
+	name := base.BaseModuleName()
+	if a.OverrideName != "" {
+		name = a.OverrideName
+	}
+
+	if a.Include == "" {
+		a.Include = "$(BUILD_PREBUILT)"
+	}
+	a.Required = append(a.Required, amod.RequiredModuleNames(ctx)...)
+	a.Required = append(a.Required, amod.VintfFragmentModuleNames(ctx)...)
+	a.Host_required = append(a.Host_required, amod.HostRequiredModuleNames()...)
+	a.Target_required = append(a.Target_required, amod.TargetRequiredModuleNames()...)
+
+	for _, distString := range a.GetDistForGoals(ctx, mod) {
+		a.HeaderStrings = append(a.HeaderStrings, distString)
+	}
+
+	a.HeaderStrings = append(a.HeaderStrings, fmt.Sprintf("\ninclude $(CLEAR_VARS)  # type: %s, name: %s, variant: %s\n", ctx.ModuleType(mod), base.BaseModuleName(), ctx.ModuleSubDir(mod)))
+
+	// Collect make variable assignment entries.
+	helperInfo.SetString("LOCAL_PATH", ctx.ModuleDir(mod))
+	helperInfo.SetString("LOCAL_MODULE", name+a.SubName)
+	helperInfo.SetString("LOCAL_MODULE_CLASS", a.Class)
+	helperInfo.SetString("LOCAL_PREBUILT_MODULE_FILE", a.OutputFile.String())
+	helperInfo.AddStrings("LOCAL_REQUIRED_MODULES", a.Required...)
+	helperInfo.AddStrings("LOCAL_HOST_REQUIRED_MODULES", a.Host_required...)
+	helperInfo.AddStrings("LOCAL_TARGET_REQUIRED_MODULES", a.Target_required...)
+	helperInfo.AddStrings("LOCAL_SOONG_MODULE_TYPE", ctx.ModuleType(amod))
+
+	// If the install rule was generated by Soong tell Make about it.
+	info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
+	if len(info.KatiInstalls) > 0 {
+		// Assume the primary install file is last since it probably needs to depend on any other
+		// installed files.  If that is not the case we can add a method to specify the primary
+		// installed file.
+		helperInfo.SetPath("LOCAL_SOONG_INSTALLED_MODULE", info.KatiInstalls[len(info.KatiInstalls)-1].to)
+		helperInfo.SetString("LOCAL_SOONG_INSTALL_PAIRS", info.KatiInstalls.BuiltInstalled())
+		helperInfo.SetPaths("LOCAL_SOONG_INSTALL_SYMLINKS", info.KatiSymlinks.InstallPaths().Paths())
+	} else {
+		// Soong may not have generated the install rule also when `no_full_install: true`.
+		// Mark this module as uninstallable in order to prevent Make from creating an
+		// install rule there.
+		helperInfo.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", proptools.Bool(base.commonProperties.No_full_install))
+	}
+
+	if len(info.TestData) > 0 {
+		helperInfo.AddStrings("LOCAL_TEST_DATA", androidMkDataPaths(info.TestData)...)
+	}
+
+	if am, ok := mod.(ApexModule); ok {
+		helperInfo.SetBoolIfTrue("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", am.NotAvailableForPlatform())
+	}
+
+	archStr := base.Arch().ArchType.String()
+	host := false
+	switch base.Os().Class {
+	case Host:
+		if base.Target().HostCross {
+			// Make cannot identify LOCAL_MODULE_HOST_CROSS_ARCH:= common.
+			if base.Arch().ArchType != Common {
+				helperInfo.SetString("LOCAL_MODULE_HOST_CROSS_ARCH", archStr)
+			}
+		} else {
+			// Make cannot identify LOCAL_MODULE_HOST_ARCH:= common.
+			if base.Arch().ArchType != Common {
+				helperInfo.SetString("LOCAL_MODULE_HOST_ARCH", archStr)
+			}
+		}
+		host = true
+	case Device:
+		// Make cannot identify LOCAL_MODULE_TARGET_ARCH:= common.
+		if base.Arch().ArchType != Common {
+			if base.Target().NativeBridge {
+				hostArchStr := base.Target().NativeBridgeHostArchName
+				if hostArchStr != "" {
+					helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", hostArchStr)
+				}
+			} else {
+				helperInfo.SetString("LOCAL_MODULE_TARGET_ARCH", archStr)
+			}
+		}
+
+		if !base.InVendorRamdisk() {
+			helperInfo.AddPaths("LOCAL_FULL_INIT_RC", info.InitRcPaths)
+		}
+		if len(info.VintfFragmentsPaths) > 0 {
+			helperInfo.AddPaths("LOCAL_FULL_VINTF_FRAGMENTS", info.VintfFragmentsPaths)
+		}
+		helperInfo.SetBoolIfTrue("LOCAL_PROPRIETARY_MODULE", Bool(base.commonProperties.Proprietary))
+		if Bool(base.commonProperties.Vendor) || Bool(base.commonProperties.Soc_specific) {
+			helperInfo.SetString("LOCAL_VENDOR_MODULE", "true")
+		}
+		helperInfo.SetBoolIfTrue("LOCAL_ODM_MODULE", Bool(base.commonProperties.Device_specific))
+		helperInfo.SetBoolIfTrue("LOCAL_PRODUCT_MODULE", Bool(base.commonProperties.Product_specific))
+		helperInfo.SetBoolIfTrue("LOCAL_SYSTEM_EXT_MODULE", Bool(base.commonProperties.System_ext_specific))
+		if base.commonProperties.Owner != nil {
+			helperInfo.SetString("LOCAL_MODULE_OWNER", *base.commonProperties.Owner)
+		}
+	}
+
+	if host {
+		makeOs := base.Os().String()
+		if base.Os() == Linux || base.Os() == LinuxBionic || base.Os() == LinuxMusl {
+			makeOs = "linux"
+		}
+		helperInfo.SetString("LOCAL_MODULE_HOST_OS", makeOs)
+		helperInfo.SetString("LOCAL_IS_HOST_MODULE", "true")
+	}
+
+	prefix := ""
+	if base.ArchSpecific() {
+		switch base.Os().Class {
+		case Host:
+			if base.Target().HostCross {
+				prefix = "HOST_CROSS_"
+			} else {
+				prefix = "HOST_"
+			}
+		case Device:
+			prefix = "TARGET_"
+
+		}
+
+		if base.Arch().ArchType != ctx.Config().Targets[base.Os()][0].Arch.ArchType {
+			prefix = "2ND_" + prefix
+		}
+	}
+
+	if licenseMetadata, ok := OtherModuleProvider(ctx, mod, LicenseMetadataProvider); ok {
+		helperInfo.SetPath("LOCAL_SOONG_LICENSE_METADATA", licenseMetadata.LicenseMetadataPath)
+	}
+
+	if _, ok := OtherModuleProvider(ctx, mod, ModuleInfoJSONProvider); ok {
+		helperInfo.SetBool("LOCAL_SOONG_MODULE_INFO_JSON", true)
+	}
+
+	a.mergeEntries(&helperInfo)
+
+	// Write to footer.
+	a.FooterStrings = append([]string{"include " + a.Include}, a.FooterStrings...)
+}
+
+// This method merges the entries to helperInfo, then replaces a's EntryMap and
+// EntryOrder with helperInfo's
+func (a *AndroidMkInfo) mergeEntries(helperInfo *AndroidMkInfo) {
+	for _, extraEntry := range a.EntryOrder {
+		if v, ok := helperInfo.EntryMap[extraEntry]; ok {
+			v = append(v, a.EntryMap[extraEntry]...)
+		} else {
+			helperInfo.EntryMap[extraEntry] = a.EntryMap[extraEntry]
+			helperInfo.EntryOrder = append(helperInfo.EntryOrder, extraEntry)
+		}
+	}
+	a.EntryOrder = helperInfo.EntryOrder
+	a.EntryMap = helperInfo.EntryMap
+}
+
+func (a *AndroidMkInfo) disabled() bool {
+	return a.Disabled || !a.OutputFile.Valid()
+}
+
+// write  flushes the AndroidMkEntries's in-struct data populated by AndroidMkEntries into the
+// given Writer object.
+func (a *AndroidMkInfo) write(w io.Writer) {
+	if a.disabled() {
+		return
+	}
+
+	combinedHeaderString := strings.Join(a.HeaderStrings, "\n")
+	combinedFooterString := strings.Join(a.FooterStrings, "\n")
+	w.Write([]byte(combinedHeaderString))
+	for _, name := range a.EntryOrder {
+		AndroidMkEmitAssignList(w, name, a.EntryMap[name])
+	}
+	w.Write([]byte(combinedFooterString))
+}
+
+// Compute the list of Make strings to declare phony goals and dist-for-goals
+// calls from the module's dist and dists properties.
+func (a *AndroidMkInfo) GetDistForGoals(ctx fillInEntriesContext, mod blueprint.Module) []string {
+	distContributions := a.getDistContributions(ctx, mod)
+	if distContributions == nil {
+		return nil
+	}
+
+	return generateDistContributionsForMake(distContributions)
+}
+
+// Compute the contributions that the module makes to the dist.
+func (a *AndroidMkInfo) getDistContributions(ctx fillInEntriesContext, mod blueprint.Module) *distContributions {
+	amod := mod.(Module).base()
+	name := amod.BaseModuleName()
+
+	// Collate the set of associated tag/paths available for copying to the dist.
+	// Start with an empty (nil) set.
+	var availableTaggedDists TaggedDistFiles
+
+	// Then merge in any that are provided explicitly by the module.
+	if a.DistFiles != nil {
+		// Merge the DistFiles into the set.
+		availableTaggedDists = availableTaggedDists.merge(a.DistFiles)
+	}
+
+	// If no paths have been provided for the DefaultDistTag and the output file is
+	// valid then add that as the default dist path.
+	if _, ok := availableTaggedDists[DefaultDistTag]; !ok && a.OutputFile.Valid() {
+		availableTaggedDists = availableTaggedDists.addPathsForTag(DefaultDistTag, a.OutputFile.Path())
+	}
+
+	info := OtherModuleProviderOrDefault(ctx, mod, InstallFilesProvider)
+	// If the distFiles created by GenerateTaggedDistFiles contains paths for the
+	// DefaultDistTag then that takes priority so delete any existing paths.
+	if _, ok := info.DistFiles[DefaultDistTag]; ok {
+		delete(availableTaggedDists, DefaultDistTag)
+	}
+
+	// Finally, merge the distFiles created by GenerateTaggedDistFiles.
+	availableTaggedDists = availableTaggedDists.merge(info.DistFiles)
+
+	if len(availableTaggedDists) == 0 {
+		// Nothing dist-able for this module.
+		return nil
+	}
+
+	// Collate the contributions this module makes to the dist.
+	distContributions := &distContributions{}
+
+	if !exemptFromRequiredApplicableLicensesProperty(mod.(Module)) {
+		distContributions.licenseMetadataFile = info.LicenseMetadataFile
+	}
+
+	// Iterate over this module's dist structs, merged from the dist and dists properties.
+	for _, dist := range amod.Dists() {
+		// Get the list of goals this dist should be enabled for. e.g. sdk, droidcore
+		goals := strings.Join(dist.Targets, " ")
+
+		// Get the tag representing the output files to be dist'd. e.g. ".jar", ".proguard_map"
+		var tag string
+		if dist.Tag == nil {
+			// If the dist struct does not specify a tag, use the default output files tag.
+			tag = DefaultDistTag
+		} else {
+			tag = *dist.Tag
+		}
+
+		// Get the paths of the output files to be dist'd, represented by the tag.
+		// Can be an empty list.
+		tagPaths := availableTaggedDists[tag]
+		if len(tagPaths) == 0 {
+			// Nothing to dist for this tag, continue to the next dist.
+			continue
+		}
+
+		if len(tagPaths) > 1 && (dist.Dest != nil || dist.Suffix != nil) {
+			errorMessage := "%s: Cannot apply dest/suffix for more than one dist " +
+				"file for %q goals tag %q in module %s. The list of dist files, " +
+				"which should have a single element, is:\n%s"
+			panic(fmt.Errorf(errorMessage, mod, goals, tag, name, tagPaths))
+		}
+
+		copiesForGoals := distContributions.getCopiesForGoals(goals)
+
+		// Iterate over each path adding a copy instruction to copiesForGoals
+		for _, path := range tagPaths {
+			// It's possible that the Path is nil from errant modules. Be defensive here.
+			if path == nil {
+				tagName := "default" // for error message readability
+				if dist.Tag != nil {
+					tagName = *dist.Tag
+				}
+				panic(fmt.Errorf("Dist file should not be nil for the %s tag in %s", tagName, name))
+			}
+
+			dest := filepath.Base(path.String())
+
+			if dist.Dest != nil {
+				var err error
+				if dest, err = validateSafePath(*dist.Dest); err != nil {
+					// This was checked in ModuleBase.GenerateBuildActions
+					panic(err)
+				}
+			}
+
+			ext := filepath.Ext(dest)
+			suffix := ""
+			if dist.Suffix != nil {
+				suffix = *dist.Suffix
+			}
+
+			productString := ""
+			if dist.Append_artifact_with_product != nil && *dist.Append_artifact_with_product {
+				productString = fmt.Sprintf("_%s", ctx.Config().DeviceProduct())
+			}
+
+			if suffix != "" || productString != "" {
+				dest = strings.TrimSuffix(dest, ext) + suffix + productString + ext
+			}
+
+			if dist.Dir != nil {
+				var err error
+				if dest, err = validateSafePath(*dist.Dir, dest); err != nil {
+					// This was checked in ModuleBase.GenerateBuildActions
+					panic(err)
+				}
+			}
+
+			copiesForGoals.addCopyInstruction(path, dest)
+		}
+	}
+
+	return distContributions
+}
+
+func deepCopyAndroidMkProviderInfo(providerInfo *AndroidMkProviderInfo) AndroidMkProviderInfo {
+	info := AndroidMkProviderInfo{
+		PrimaryInfo: deepCopyAndroidMkInfo(&providerInfo.PrimaryInfo),
+	}
+	if len(providerInfo.ExtraInfo) > 0 {
+		for _, i := range providerInfo.ExtraInfo {
+			info.ExtraInfo = append(info.ExtraInfo, deepCopyAndroidMkInfo(&i))
+		}
+	}
+	return info
+}
+
+func deepCopyAndroidMkInfo(mkinfo *AndroidMkInfo) AndroidMkInfo {
+	info := AndroidMkInfo{
+		Class:        mkinfo.Class,
+		SubName:      mkinfo.SubName,
+		OverrideName: mkinfo.OverrideName,
+		// There is no modification on DistFiles or OutputFile, so no need to
+		// make their deep copy.
+		DistFiles:       mkinfo.DistFiles,
+		OutputFile:      mkinfo.OutputFile,
+		Disabled:        mkinfo.Disabled,
+		Include:         mkinfo.Include,
+		Required:        deepCopyStringSlice(mkinfo.Required),
+		Host_required:   deepCopyStringSlice(mkinfo.Host_required),
+		Target_required: deepCopyStringSlice(mkinfo.Target_required),
+		HeaderStrings:   deepCopyStringSlice(mkinfo.HeaderStrings),
+		FooterStrings:   deepCopyStringSlice(mkinfo.FooterStrings),
+		EntryOrder:      deepCopyStringSlice(mkinfo.EntryOrder),
+	}
+	info.EntryMap = make(map[string][]string)
+	for k, v := range mkinfo.EntryMap {
+		info.EntryMap[k] = deepCopyStringSlice(v)
+	}
+
+	return info
+}
+
+func deepCopyStringSlice(original []string) []string {
+	result := make([]string, len(original))
+	copy(result, original)
+	return result
+}
