diff --git a/android/packaging.go b/android/packaging.go index ae412e1bb..c247ed2a4 100644 --- a/android/packaging.go +++ b/android/packaging.go @@ -17,6 +17,7 @@ package android import ( "fmt" "path/filepath" + "sort" "strings" "github.com/google/blueprint" @@ -377,31 +378,59 @@ func (p *PackagingBase) GatherPackagingSpecs(ctx ModuleContext) map[string]Packa // CopySpecsToDir is a helper that will add commands to the rule builder to copy the PackagingSpec // entries into the specified directory. func (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, specs map[string]PackagingSpec, dir WritablePath) (entries []string) { - if len(specs) == 0 { + dirsToSpecs := make(map[WritablePath]map[string]PackagingSpec) + dirsToSpecs[dir] = specs + return p.CopySpecsToDirs(ctx, builder, dirsToSpecs) +} + +// CopySpecsToDirs is a helper that will add commands to the rule builder to copy the PackagingSpec +// entries into corresponding directories. +func (p *PackagingBase) CopySpecsToDirs(ctx ModuleContext, builder *RuleBuilder, dirsToSpecs map[WritablePath]map[string]PackagingSpec) (entries []string) { + empty := true + for _, specs := range dirsToSpecs { + if len(specs) > 0 { + empty = false + break + } + } + if empty { return entries } + seenDir := make(map[string]bool) preparerPath := PathForModuleOut(ctx, "preparer.sh") cmd := builder.Command().Tool(preparerPath) var sb strings.Builder sb.WriteString("set -e\n") - for _, k := range SortedKeys(specs) { - ps := specs[k] - destPath := filepath.Join(dir.String(), ps.relPathInPackage) - destDir := filepath.Dir(destPath) - entries = append(entries, ps.relPathInPackage) - if _, ok := seenDir[destDir]; !ok { - seenDir[destDir] = true - sb.WriteString(fmt.Sprintf("mkdir -p %s\n", destDir)) - } - if ps.symlinkTarget == "" { - cmd.Implicit(ps.srcPath) - sb.WriteString(fmt.Sprintf("cp %s %s\n", ps.srcPath, destPath)) - } else { - sb.WriteString(fmt.Sprintf("ln -sf %s %s\n", ps.symlinkTarget, destPath)) - } - if ps.executable { - sb.WriteString(fmt.Sprintf("chmod a+x %s\n", destPath)) + + dirs := make([]WritablePath, 0, len(dirsToSpecs)) + for dir, _ := range dirsToSpecs { + dirs = append(dirs, dir) + } + sort.Slice(dirs, func(i, j int) bool { + return dirs[i].String() < dirs[j].String() + }) + + for _, dir := range dirs { + specs := dirsToSpecs[dir] + for _, k := range SortedKeys(specs) { + ps := specs[k] + destPath := filepath.Join(dir.String(), ps.relPathInPackage) + destDir := filepath.Dir(destPath) + entries = append(entries, ps.relPathInPackage) + if _, ok := seenDir[destDir]; !ok { + seenDir[destDir] = true + sb.WriteString(fmt.Sprintf("mkdir -p %s\n", destDir)) + } + if ps.symlinkTarget == "" { + cmd.Implicit(ps.srcPath) + sb.WriteString(fmt.Sprintf("cp %s %s\n", ps.srcPath, destPath)) + } else { + sb.WriteString(fmt.Sprintf("ln -sf %s %s\n", ps.symlinkTarget, destPath)) + } + if ps.executable { + sb.WriteString(fmt.Sprintf("chmod a+x %s\n", destPath)) + } } } diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index 5add95441..5c7ef434f 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -312,6 +312,25 @@ func (f *filesystem) buildNonDepsFiles(ctx android.ModuleContext, builder *andro } } +func (f *filesystem) copyPackagingSpecs(ctx android.ModuleContext, builder *android.RuleBuilder, specs map[string]android.PackagingSpec, rootDir, rebasedDir android.WritablePath) []string { + rootDirSpecs := make(map[string]android.PackagingSpec) + rebasedDirSpecs := make(map[string]android.PackagingSpec) + + for rel, spec := range specs { + if spec.Partition() == "root" { + rootDirSpecs[rel] = spec + } else { + rebasedDirSpecs[rel] = spec + } + } + + dirsToSpecs := make(map[android.WritablePath]map[string]android.PackagingSpec) + dirsToSpecs[rootDir] = rootDirSpecs + dirsToSpecs[rebasedDir] = rebasedDirSpecs + + return f.CopySpecsToDirs(ctx, builder, dirsToSpecs) +} + func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) android.OutputPath { rootDir := android.PathForModuleOut(ctx, "root").OutputPath rebasedDir := rootDir @@ -322,7 +341,7 @@ func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) androi // Wipe the root dir to get rid of leftover files from prior builds builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir) specs := f.gatherFilteredPackagingSpecs(ctx) - f.entries = f.CopySpecsToDir(ctx, builder, specs, rebasedDir) + f.entries = f.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir) f.buildNonDepsFiles(ctx, builder, rootDir) f.addMakeBuiltFiles(ctx, builder, rootDir) @@ -465,7 +484,7 @@ func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) // Wipe the root dir to get rid of leftover files from prior builds builder.Command().Textf("rm -rf %s && mkdir -p %s", rootDir, rootDir) specs := f.gatherFilteredPackagingSpecs(ctx) - f.entries = f.CopySpecsToDir(ctx, builder, specs, rebasedDir) + f.entries = f.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir) f.buildNonDepsFiles(ctx, builder, rootDir) f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir) diff --git a/filesystem/system_image.go b/filesystem/system_image.go index 15cacfb4f..69d922df9 100644 --- a/filesystem/system_image.go +++ b/filesystem/system_image.go @@ -94,9 +94,10 @@ func (s *systemImage) buildLinkerConfigFile(ctx android.ModuleContext, root andr return output } -// Filter the result of GatherPackagingSpecs to discard items targeting outside "system" partition. -// Note that "apex" module installs its contents to "apex"(fake partition) as well +// Filter the result of GatherPackagingSpecs to discard items targeting outside "system" / "root" +// partition. Note that "apex" module installs its contents to "apex"(fake partition) as well // for symbol lookup by imitating "activated" paths. func (s *systemImage) filterPackagingSpec(ps android.PackagingSpec) bool { - return s.filesystem.filterInstallablePackagingSpec(ps) && ps.Partition() == "system" + return s.filesystem.filterInstallablePackagingSpec(ps) && + (ps.Partition() == "system" || ps.Partition() == "root") }