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

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

Merge "Support generating prebuilt_* modules from 1:n mapping of PRODUCT_COPY_FILES" into main

parents e8d3e1c7 3a8759c2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -635,7 +635,7 @@ type PartitionVariables struct {
	BoardInfoFiles      []string `json:",omitempty"`
	BootLoaderBoardName string   `json:",omitempty"`

	ProductCopyFiles map[string]string `json:",omitempty"`
	ProductCopyFiles []string `json:",omitempty"`

	BuildingSystemDlkmImage   bool     `json:",omitempty"`
	SystemKernelModules       []string `json:",omitempty"`
+11 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package fsgen
import (
	"fmt"
	"slices"
	"strings"
	"sync"

	"android/soong/android"
@@ -327,12 +328,21 @@ func removeOverriddenDeps(mctx android.BottomUpMutatorContext) {

var HighPriorityDeps = []string{}

func isHighPriorityDep(depName string) bool {
	for _, highPriorityDeps := range HighPriorityDeps {
		if strings.HasPrefix(depName, highPriorityDeps) {
			return true
		}
	}
	return false
}

func generateDepStruct(deps map[string]*depCandidateProps) *packagingPropsStruct {
	depsStruct := packagingPropsStruct{}
	for depName, depProps := range deps {
		bitness := getBitness(depProps.Arch)
		fullyQualifiedDepName := fullyQualifiedModuleName(depName, depProps.Namespace)
		if android.InList(depName, HighPriorityDeps) {
		if isHighPriorityDep(depName) {
			depsStruct.High_priority_deps = append(depsStruct.High_priority_deps, fullyQualifiedDepName)
		} else if android.InList("32", bitness) && android.InList("64", bitness) {
			// If both 32 and 64 bit variants are enabled for this module
+102 −57
Original line number Diff line number Diff line
@@ -85,15 +85,25 @@ func appendIfCorrectInstallPartition(partitionToInstallPathList []partitionToIns
	}
}

func uniqueExistingProductCopyFileMap(ctx android.LoadHookContext) map[string]string {
// Create a map of source files to the list of destination files from PRODUCT_COPY_FILES entries.
// Note that the value of the map is a list of string, given that a single source file can be
// copied to multiple files.
// This function also checks the existence of the source files, and validates that there is no
// multiple source files copying to the same dest file.
func uniqueExistingProductCopyFileMap(ctx android.LoadHookContext) map[string][]string {
	seen := make(map[string]bool)
	filtered := make(map[string]string)
	filtered := make(map[string][]string)

	for src, dest := range ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles {
	for _, copyFilePair := range ctx.Config().ProductVariables().PartitionVarsForSoongMigrationOnlyDoNotUse.ProductCopyFiles {
		srcDestList := strings.Split(copyFilePair, ":")
		if len(srcDestList) < 2 {
			ctx.ModuleErrorf("PRODUCT_COPY_FILES must follow the format \"src:dest\", got: %s", copyFilePair)
		}
		src, dest := srcDestList[0], srcDestList[1]
		if _, ok := seen[dest]; !ok {
			if optionalPath := android.ExistentPathForSource(ctx, src); optionalPath.Valid() {
				seen[dest] = true
				filtered[src] = dest
				filtered[src] = append(filtered[src], dest)
			}
		}
	}
@@ -121,13 +131,15 @@ func processProductCopyFiles(ctx android.LoadHookContext) map[string]*prebuiltSr

	groupedSources := map[string]*prebuiltSrcGroupByInstallPartition{}
	for _, src := range android.SortedKeys(productCopyFileMap) {
		dest := productCopyFileMap[src]
		destFiles := productCopyFileMap[src]
		srcFileDir := filepath.Dir(src)
		if _, ok := groupedSources[srcFileDir]; !ok {
			groupedSources[srcFileDir] = newPrebuiltSrcGroupByInstallPartition()
		}
		for _, dest := range destFiles {
			appendIfCorrectInstallPartition(partitionToInstallPathList, dest, filepath.Base(src), groupedSources[srcFileDir])
		}
	}

	return groupedSources
}
@@ -195,12 +207,9 @@ var (
	}
)

func createPrebuiltEtcModule(ctx android.LoadHookContext, partition, srcDir, destDir string, destFiles []srcBaseFileInstallBaseFileTuple) string {
	moduleProps := &prebuiltModuleProperties{}
	propsList := []interface{}{moduleProps}

func generatedPrebuiltEtcModuleName(partition, srcDir, destDir string, count int) string {
	// generated module name follows the pattern:
	// <install partition>-<src file path>-<relative install path from partition root>-<install file extension>
	// <install partition>-<src file path>-<relative install path from partition root>-<number>
	// Note that all path separators are replaced with "_" in the name
	moduleName := partition
	if !android.InList(srcDir, []string{"", "."}) {
@@ -209,23 +218,48 @@ func createPrebuiltEtcModule(ctx android.LoadHookContext, partition, srcDir, des
	if !android.InList(destDir, []string{"", "."}) {
		moduleName += fmt.Sprintf("-%s", strings.ReplaceAll(destDir, string(filepath.Separator), "_"))
	}
	if len(destFiles) > 0 {
		if ext := filepath.Ext(destFiles[0].srcBaseFile); ext != "" {
			moduleName += fmt.Sprintf("-%s", strings.TrimPrefix(ext, "."))
	moduleName += fmt.Sprintf("-%d", count)

	return moduleName
}

func groupDestFilesBySrc(destFiles []srcBaseFileInstallBaseFileTuple) (ret map[string][]srcBaseFileInstallBaseFileTuple, maxLen int) {
	ret = map[string][]srcBaseFileInstallBaseFileTuple{}
	maxLen = 0
	for _, tuple := range destFiles {
		if _, ok := ret[tuple.srcBaseFile]; !ok {
			ret[tuple.srcBaseFile] = []srcBaseFileInstallBaseFileTuple{}
		}
		ret[tuple.srcBaseFile] = append(ret[tuple.srcBaseFile], tuple)
		maxLen = max(maxLen, len(ret[tuple.srcBaseFile]))
	}
	return ret, maxLen
}

func prebuiltEtcModuleProps(moduleName, partition string) prebuiltModuleProperties {
	moduleProps := prebuiltModuleProperties{}
	moduleProps.Name = proptools.StringPtr(moduleName)

	allCopyFileNamesUnchanged := true
	var srcBaseFiles, installBaseFiles []string
	for _, tuple := range destFiles {
		if tuple.srcBaseFile != tuple.installBaseFile {
			allCopyFileNamesUnchanged = false
	// Set partition specific properties
	switch partition {
	case "system_ext":
		moduleProps.System_ext_specific = proptools.BoolPtr(true)
	case "product":
		moduleProps.Product_specific = proptools.BoolPtr(true)
	case "vendor":
		moduleProps.Soc_specific = proptools.BoolPtr(true)
	}
		srcBaseFiles = append(srcBaseFiles, tuple.srcBaseFile)
		installBaseFiles = append(installBaseFiles, tuple.installBaseFile)

	moduleProps.No_full_install = proptools.BoolPtr(true)
	moduleProps.NamespaceExportedToMake = true
	moduleProps.Visibility = []string{"//visibility:public"}

	return moduleProps
}

func createPrebuiltEtcModulesInDirectory(ctx android.LoadHookContext, partition, srcDir, destDir string, destFiles []srcBaseFileInstallBaseFileTuple) (moduleNames []string) {
	groupedDestFiles, maxLen := groupDestFilesBySrc(destFiles)

	// Find out the most appropriate module type to generate
	var etcInstallPathKey string
	for _, etcInstallPath := range android.SortedKeys(etcInstallPathToFactoryList) {
@@ -235,51 +269,62 @@ func createPrebuiltEtcModule(ctx android.LoadHookContext, partition, srcDir, des
			etcInstallPathKey = etcInstallPath
		}
	}
	destDir, _ = filepath.Rel(etcInstallPathKey, destDir)
	relDestDirFromInstallDirBase, _ := filepath.Rel(etcInstallPathKey, destDir)

	// Set partition specific properties
	switch partition {
	case "system_ext":
		moduleProps.System_ext_specific = proptools.BoolPtr(true)
	case "product":
		moduleProps.Product_specific = proptools.BoolPtr(true)
	case "vendor":
		moduleProps.Soc_specific = proptools.BoolPtr(true)
	for fileIndex := range maxLen {
		srcTuple := []srcBaseFileInstallBaseFileTuple{}
		for _, groupedDestFile := range groupedDestFiles {
			if len(groupedDestFile) > fileIndex {
				srcTuple = append(srcTuple, groupedDestFile[fileIndex])
			}
		}

		moduleName := generatedPrebuiltEtcModuleName(partition, srcDir, destDir, fileIndex)
		moduleProps := prebuiltEtcModuleProps(moduleName, partition)
		modulePropsPtr := &moduleProps
		propsList := []interface{}{modulePropsPtr}

		allCopyFileNamesUnchanged := true
		var srcBaseFiles, installBaseFiles []string
		for _, tuple := range srcTuple {
			if tuple.srcBaseFile != tuple.installBaseFile {
				allCopyFileNamesUnchanged = false
			}
			srcBaseFiles = append(srcBaseFiles, tuple.srcBaseFile)
			installBaseFiles = append(installBaseFiles, tuple.installBaseFile)
		}

		// Set appropriate srcs, dsts, and releative_install_path based on
		// the source and install file names
		if allCopyFileNamesUnchanged {
		moduleProps.Srcs = srcBaseFiles
			modulePropsPtr.Srcs = srcBaseFiles

			// Specify relative_install_path if it is not installed in the root directory of the
			// partition
		if !android.InList(destDir, []string{"", "."}) {
			if !android.InList(relDestDirFromInstallDirBase, []string{"", "."}) {
				propsList = append(propsList, &prebuiltSubdirProperties{
				Relative_install_path: proptools.StringPtr(destDir),
					Relative_install_path: proptools.StringPtr(relDestDirFromInstallDirBase),
				})
			}
		} else {
		moduleProps.Srcs = srcBaseFiles
			modulePropsPtr.Srcs = srcBaseFiles
			dsts := []string{}
			for _, installBaseFile := range installBaseFiles {
			dsts = append(dsts, filepath.Join(destDir, installBaseFile))
				dsts = append(dsts, filepath.Join(relDestDirFromInstallDirBase, installBaseFile))
			}
		moduleProps.Dsts = dsts
			modulePropsPtr.Dsts = dsts
		}

	moduleProps.No_full_install = proptools.BoolPtr(true)
	moduleProps.NamespaceExportedToMake = true
	moduleProps.Visibility = []string{"//visibility:public"}

		ctx.CreateModuleInDirectory(etcInstallPathToFactoryList[etcInstallPathKey], srcDir, propsList...)
		moduleNames = append(moduleNames, moduleName)
	}

	return moduleName
	return moduleNames
}

func createPrebuiltEtcModulesForPartition(ctx android.LoadHookContext, partition, srcDir string, destDirFilesMap map[string][]srcBaseFileInstallBaseFileTuple) (ret []string) {
	for _, destDir := range android.SortedKeys(destDirFilesMap) {
		ret = append(ret, createPrebuiltEtcModule(ctx, partition, srcDir, destDir, destDirFilesMap[destDir]))
		ret = append(ret, createPrebuiltEtcModulesInDirectory(ctx, partition, srcDir, destDir, destDirFilesMap[destDir])...)
	}
	return ret
}