summaryrefslogtreecommitdiff
path: root/filesystem/filesystem.go
diff options
context:
space:
mode:
Diffstat (limited to 'filesystem/filesystem.go')
-rw-r--r--filesystem/filesystem.go196
1 files changed, 96 insertions, 100 deletions
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 469fd9efa..822ba43ad 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -173,12 +173,6 @@ type FilesystemProperties struct {
// Mount point for this image. Default is "/"
Mount_point *string
- // If set to the name of a partition ("system", "vendor", etc), this filesystem module
- // will also include the contents of the make-built staging directories. If any soong
- // modules would be installed to the same location as a make module, they will overwrite
- // the make version.
- Include_make_built_files string
-
// When set, builds etc/event-log-tags file by merging logtags from all dependencies.
// Default is false
Build_logtags *bool
@@ -363,15 +357,34 @@ func (fs fsType) IsUnknown() bool {
type FilesystemInfo struct {
// The built filesystem image
Output android.Path
+ // An additional hermetic filesystem image.
+ // e.g. this will contain inodes with pinned timestamps.
+ // This will be copied to target_files.zip
+ OutputHermetic android.Path
// A text file containing the list of paths installed on the partition.
FileListFile android.Path
// The root staging directory used to build the output filesystem. If consuming this, make sure
// to add a dependency on the Output file, as you cannot add dependencies on directories
// in ninja.
RootDir android.Path
+ // The rebased staging directory used to build the output filesystem. If consuming this, make
+ // sure to add a dependency on the Output file, as you cannot add dependencies on directories
+ // in ninja. In many cases this is the same as RootDir, only in the system partition is it
+ // different. There, it points to the "system" sub-directory of RootDir.
+ RebasedDir android.Path
// A text file with block data of the .img file
// This is an implicit output of `build_image`
MapFile android.Path
+ // Name of the module that produced this FilesystemInfo origionally. (though it may be
+ // re-exported by super images or boot images)
+ ModuleName string
+ // The property file generated by this module and passed to build_image.
+ // It's exported here so that system_other can reuse system's property file.
+ BuildImagePropFile android.Path
+ // Paths to all the tools referenced inside of the build image property file.
+ BuildImagePropFileDeps android.Paths
+ // Packaging specs to be installed on the system_other image, for the initial boot's dexpreopt.
+ SpecsForSystemOther map[string]android.PackagingSpec
}
var FilesystemProvider = blueprint.NewProvider[FilesystemInfo]()
@@ -458,16 +471,36 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.PropertyErrorf("include_files_of", "include_files_of is only supported for cpio and compressed cpio filesystem types.")
}
- var rootDir android.OutputPath
+ rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
+ rebasedDir := rootDir
+ if f.properties.Base_dir != nil {
+ rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
+ }
+ builder := android.NewRuleBuilder(pctx, ctx)
+
+ // 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.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir)
+
+ f.buildNonDepsFiles(ctx, builder, rootDir)
+ f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
+ f.buildEventLogtagsFile(ctx, builder, rebasedDir)
+ f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir)
+ f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir)
+
var mapFile android.Path
+ var outputHermetic android.Path
+ var buildImagePropFile android.Path
+ var buildImagePropFileDeps android.Paths
switch f.fsType(ctx) {
case ext4Type, erofsType, f2fsType:
- f.output, rootDir = f.buildImageUsingBuildImage(ctx)
+ f.output, outputHermetic, buildImagePropFile, buildImagePropFileDeps = f.buildImageUsingBuildImage(ctx, builder, rootDir, rebasedDir)
mapFile = f.getMapFile(ctx)
case compressedCpioType:
- f.output, rootDir = f.buildCpioImage(ctx, true)
+ f.output = f.buildCpioImage(ctx, builder, rootDir, true)
case cpioType:
- f.output, rootDir = f.buildCpioImage(ctx, false)
+ f.output = f.buildCpioImage(ctx, builder, rootDir, false)
default:
return
}
@@ -484,12 +517,16 @@ func (f *filesystem) GenerateAndroidBuildActions(ctx android.ModuleContext) {
android.WriteFileRule(ctx, fileListFile, f.installedFilesList())
fsInfo := FilesystemInfo{
- Output: f.output,
- FileListFile: fileListFile,
- RootDir: rootDir,
- }
- if mapFile != nil {
- fsInfo.MapFile = mapFile
+ Output: f.output,
+ OutputHermetic: outputHermetic,
+ FileListFile: fileListFile,
+ RootDir: rootDir,
+ RebasedDir: rebasedDir,
+ MapFile: mapFile,
+ ModuleName: ctx.ModuleName(),
+ BuildImagePropFile: buildImagePropFile,
+ BuildImagePropFileDeps: buildImagePropFileDeps,
+ SpecsForSystemOther: f.systemOtherFiles(ctx),
}
android.SetProvider(ctx, FilesystemProvider, fsInfo)
@@ -632,43 +669,16 @@ func (f *filesystem) copyPackagingSpecs(ctx android.ModuleContext, builder *andr
return f.CopySpecsToDirs(ctx, builder, dirsToSpecs)
}
-func (f *filesystem) copyFilesToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
- if !(f.Name() == ctx.Config().SoongDefinedSystemImage() || proptools.Bool(f.properties.Is_auto_generated)) {
- return
- }
- installPath := android.PathForModuleInPartitionInstall(ctx, f.partitionName())
- builder.Command().Textf("rsync --checksum %s %s", rebasedDir, installPath)
-}
-
-func copyImageFileToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, partition string, output android.Path) {
- copyDir := android.PathForModuleInPartitionInstall(ctx, "").Join(ctx, fmt.Sprintf("%s.img", partition))
- builder.Command().Textf("rsync -a %s %s", output, copyDir)
-}
-
func (f *filesystem) rootDirString() string {
return f.partitionName()
}
-func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) (android.Path, android.OutputPath) {
- rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
- rebasedDir := rootDir
- if f.properties.Base_dir != nil {
- rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
- }
- builder := android.NewRuleBuilder(pctx, ctx)
- // 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.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir)
-
- f.buildNonDepsFiles(ctx, builder, rootDir)
- f.addMakeBuiltFiles(ctx, builder, rootDir)
- f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
- f.buildEventLogtagsFile(ctx, builder, rebasedDir)
- f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir)
- f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir)
- f.copyFilesToProductOut(ctx, builder, rebasedDir)
-
+func (f *filesystem) buildImageUsingBuildImage(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ rootDir android.OutputPath,
+ rebasedDir android.OutputPath,
+) (android.Path, android.Path, android.Path, android.Paths) {
// run host_init_verifier
// Ideally we should have a concept of pluggable linters that verify the generated image.
// While such concept is not implement this will do.
@@ -697,9 +707,20 @@ func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) (andro
Output(output).
Text(rootDir.String()) // directory where to find fs_config_files|dirs
- if !ctx.Config().KatiEnabled() {
- copyImageFileToProductOut(ctx, builder, f.partitionName(), output)
- }
+ // Add an additional cmd to create a hermetic img file. This will contain pinned timestamps e.g.
+ propFilePinnedTimestamp := android.PathForModuleOut(ctx, "for_target_files", "prop")
+ builder.Command().Textf("cat").Input(propFile).Flag(">").Output(propFilePinnedTimestamp).Textf(" && echo use_fixed_timestamp=true >> %s", propFilePinnedTimestamp)
+
+ outputHermetic := android.PathForModuleOut(ctx, "for_target_files", f.installFileName())
+ builder.Command().
+ Textf("PATH=%s:$PATH", strings.Join(pathToolDirs, ":")).
+ BuiltTool("build_image").
+ Text(rootDir.String()). // input directory
+ Flag(propFilePinnedTimestamp.String()).
+ Implicits(toolDeps).
+ Implicit(fec).
+ Output(outputHermetic).
+ Text(rootDir.String()) // directory where to find fs_config_files|dirs
if f.properties.Partition_size != nil {
assertMaxImageSize(builder, output, *f.properties.Partition_size, false)
@@ -708,7 +729,7 @@ func (f *filesystem) buildImageUsingBuildImage(ctx android.ModuleContext) (andro
// rootDir is not deleted. Might be useful for quick inspection.
builder.Build("build_filesystem_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
- return output, rootDir
+ return output, outputHermetic, propFile, toolDeps
}
func (f *filesystem) buildFileContexts(ctx android.ModuleContext) android.Path {
@@ -902,7 +923,12 @@ func includeFilesRootDir(ctx android.ModuleContext) (rootDirs android.Paths, par
return rootDirs, partitions
}
-func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool) (android.Path, android.OutputPath) {
+func (f *filesystem) buildCpioImage(
+ ctx android.ModuleContext,
+ builder *android.RuleBuilder,
+ rootDir android.OutputPath,
+ compressed bool,
+) android.Path {
if proptools.Bool(f.properties.Use_avb) {
ctx.PropertyErrorf("use_avb", "signing compresed cpio image using avbtool is not supported."+
"Consider adding this to bootimg module and signing the entire boot image.")
@@ -912,28 +938,6 @@ func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool)
ctx.PropertyErrorf("file_contexts", "file_contexts is not supported for compressed cpio image.")
}
- if f.properties.Include_make_built_files != "" {
- ctx.PropertyErrorf("include_make_built_files", "include_make_built_files is not supported for compressed cpio image.")
- }
-
- rootDir := android.PathForModuleOut(ctx, f.rootDirString()).OutputPath
- rebasedDir := rootDir
- if f.properties.Base_dir != nil {
- rebasedDir = rootDir.Join(ctx, *f.properties.Base_dir)
- }
- builder := android.NewRuleBuilder(pctx, ctx)
- // 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.copyPackagingSpecs(ctx, builder, specs, rootDir, rebasedDir)
-
- f.buildNonDepsFiles(ctx, builder, rootDir)
- f.buildFsverityMetadataFiles(ctx, builder, specs, rootDir, rebasedDir)
- f.buildEventLogtagsFile(ctx, builder, rebasedDir)
- f.buildAconfigFlagsFiles(ctx, builder, specs, rebasedDir)
- f.filesystemBuilder.BuildLinkerConfigFile(ctx, builder, rebasedDir)
- f.copyFilesToProductOut(ctx, builder, rebasedDir)
-
rootDirs, partitions := includeFilesRootDir(ctx)
output := android.PathForModuleOut(ctx, f.installFileName())
@@ -963,7 +967,7 @@ func (f *filesystem) buildCpioImage(ctx android.ModuleContext, compressed bool)
// rootDir is not deleted. Might be useful for quick inspection.
builder.Build("build_cpio_image", fmt.Sprintf("Creating filesystem %s", f.BaseModuleName()))
- return output, rootDir
+ return output
}
var validPartitions = []string{
@@ -983,27 +987,6 @@ var validPartitions = []string{
"recovery",
}
-func (f *filesystem) addMakeBuiltFiles(ctx android.ModuleContext, builder *android.RuleBuilder, rootDir android.Path) {
- partition := f.properties.Include_make_built_files
- if partition == "" {
- return
- }
- if !slices.Contains(validPartitions, partition) {
- ctx.PropertyErrorf("include_make_built_files", "Expected one of %#v, found %q", validPartitions, partition)
- return
- }
- stampFile := fmt.Sprintf("target/product/%s/obj/PACKAGING/%s_intermediates/staging_dir.stamp", ctx.Config().DeviceName(), partition)
- fileListFile := fmt.Sprintf("target/product/%s/obj/PACKAGING/%s_intermediates/file_list.txt", ctx.Config().DeviceName(), partition)
- stagingDir := fmt.Sprintf("target/product/%s/%s", ctx.Config().DeviceName(), partition)
-
- builder.Command().BuiltTool("merge_directories").
- Implicit(android.PathForArbitraryOutput(ctx, stampFile)).
- Text("--ignore-duplicates").
- FlagWithInput("--file-list", android.PathForArbitraryOutput(ctx, fileListFile)).
- Text(rootDir.String()).
- Text(android.PathForArbitraryOutput(ctx, stagingDir).String())
-}
-
func (f *filesystem) buildEventLogtagsFile(ctx android.ModuleContext, builder *android.RuleBuilder, rebasedDir android.OutputPath) {
if !proptools.Bool(f.properties.Build_logtags) {
return
@@ -1090,8 +1073,21 @@ func (f *filesystem) SignedOutputPath() android.Path {
// Note that "apex" module installs its contents to "apex"(fake partition) as well
// for symbol lookup by imitating "activated" paths.
func (f *filesystem) gatherFilteredPackagingSpecs(ctx android.ModuleContext) map[string]android.PackagingSpec {
- specs := f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec)
- return specs
+ return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, f.filesystemBuilder.FilterPackagingSpec, f.filesystemBuilder.ModifyPackagingSpec)
+}
+
+// Dexpreopt files are installed to system_other. Collect the packaingSpecs for the dexpreopt files
+// from this partition to export to the system_other partition later.
+func (f *filesystem) systemOtherFiles(ctx android.ModuleContext) map[string]android.PackagingSpec {
+ filter := func(spec android.PackagingSpec) bool {
+ // For some reason system_other packaging specs don't set the partition field.
+ return strings.HasPrefix(spec.RelPathInPackage(), "system_other/")
+ }
+ modifier := func(spec *android.PackagingSpec) {
+ spec.SetRelPathInPackage(strings.TrimPrefix(spec.RelPathInPackage(), "system_other/"))
+ spec.SetPartition("system_other")
+ }
+ return f.PackagingBase.GatherPackagingSpecsWithFilterAndModifier(ctx, filter, modifier)
}
func sha1sum(values []string) string {