summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Cole Faust <colefaust@google.com> 2025-02-13 12:45:35 -0800
committer Cole Faust <colefaust@google.com> 2025-02-13 12:55:10 -0800
commite3845057836c42e197c117815088dfac0fe38d2c (patch)
tree144b9539bb4950cd4eb44815d1604b7ca74f750b
parentc0a00df42e8f63caa3070c80a1e40db22bc574cc (diff)
Make soong-only builds adb-sync compatible
Historically, the build has put the staging directories for partitions in out/target/product. But in soong-only builds, the main staging directory is in the out/soong/.intermediates path for the filesystem modules, and then later also replicated in out/target/product for backwards compatibility with tools like adb sync. However, adb sync determines which files to push by if they have a different timestamp than on device. Since the device images were built using a different staging directory than the one adb sync is looking at, the have different timestamps, and adb sync syncs all files on the device the first time it's run. To work around this, ensure the files in both staging directories have the same timestamp by preserving the timestamp from their source file with the `cp -p` flag. This cl only does that change for real files right now, not symlinks. We could also do it for symlinks in the future, but they're more complicated and I didn't want to deal with that right now. This means the first adb sync will resync all symlinks on the device, but there are relatively few of them and they're small so it's not that big of an issue. Long term, we should rewrite adb sync to not depend on staging directories. If it looks at the actual module intermediates files, it will see a more consistent timestamp. Bug: 396466053 Test: Manually ran m sync workflows. Also testing togging soong-only on and off and rebuilding Change-Id: Ia0076a2f8e58404c5c3a0bf0d33b09b6846e95bd
-rw-r--r--android/module_context.go13
-rw-r--r--android/packaging.go10
-rw-r--r--filesystem/android_device_product_out.go6
-rw-r--r--filesystem/filesystem.go4
4 files changed, 28 insertions, 5 deletions
diff --git a/android/module_context.go b/android/module_context.go
index 45a8e5c7a..706ead766 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -713,6 +713,17 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
implicitDeps = append(implicitDeps, extraZip.zip)
}
+ var cpFlags = "-f"
+
+ // If this is a device file, copy while preserving timestamps. This is to support
+ // adb sync in soong-only builds. Because soong-only builds have 2 different staging
+ // directories, the out/target/product one and the out/soong/.intermediates one,
+ // we need to ensure the files in them have the same timestamps so that adb sync doesn't
+ // update the files on device.
+ if strings.Contains(fullInstallPath.String(), "target/product") {
+ cpFlags += " -p"
+ }
+
m.Build(pctx, BuildParams{
Rule: rule,
Description: "install " + fullInstallPath.Base(),
@@ -722,7 +733,7 @@ func (m *moduleContext) installFile(installPath InstallPath, name string, srcPat
OrderOnly: orderOnlyDeps,
Args: map[string]string{
"extraCmds": extraCmds,
- "cpFlags": "-f",
+ "cpFlags": cpFlags,
},
})
}
diff --git a/android/packaging.go b/android/packaging.go
index d216c0c18..551fd4c3f 100644
--- a/android/packaging.go
+++ b/android/packaging.go
@@ -598,12 +598,12 @@ func (p *PackagingBase) GatherPackagingSpecs(ctx ModuleContext) map[string]Packa
func (p *PackagingBase) CopySpecsToDir(ctx ModuleContext, builder *RuleBuilder, specs map[string]PackagingSpec, dir WritablePath) (entries []string) {
dirsToSpecs := make(map[WritablePath]map[string]PackagingSpec)
dirsToSpecs[dir] = specs
- return p.CopySpecsToDirs(ctx, builder, dirsToSpecs)
+ return p.CopySpecsToDirs(ctx, builder, dirsToSpecs, false)
}
// 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) {
+func (p *PackagingBase) CopySpecsToDirs(ctx ModuleContext, builder *RuleBuilder, dirsToSpecs map[WritablePath]map[string]PackagingSpec, preserveTimestamps bool) (entries []string) {
empty := true
for _, specs := range dirsToSpecs {
if len(specs) > 0 {
@@ -637,7 +637,11 @@ func (p *PackagingBase) CopySpecsToDirs(ctx ModuleContext, builder *RuleBuilder,
builder.Command().Textf("mkdir -p %s", destDir)
}
if ps.symlinkTarget == "" {
- builder.Command().Text("cp").Input(ps.srcPath).Text(destPath)
+ cmd := builder.Command().Text("cp")
+ if preserveTimestamps {
+ cmd.Flag("-p")
+ }
+ cmd.Input(ps.srcPath).Text(destPath)
} else {
builder.Command().Textf("ln -sf %s %s", ps.symlinkTarget, destPath)
}
diff --git a/filesystem/android_device_product_out.go b/filesystem/android_device_product_out.go
index 2c8cad6c0..7d37f1ee7 100644
--- a/filesystem/android_device_product_out.go
+++ b/filesystem/android_device_product_out.go
@@ -73,6 +73,12 @@ func (a *androidDevice) copyFilesToProductOutForSoongOnly(ctx android.ModuleCont
Rule: android.CpWithBash,
Input: fip.SourcePath,
Output: fip.FullInstallPath,
+ Args: map[string]string{
+ // Preserve timestamps for adb sync, so that this installed file's
+ // timestamp matches the timestamp in the filesystem's intermediate
+ // staging dir
+ "cpFlags": "-p",
+ },
})
} else {
ctx.Build(pctx, android.BuildParams{
diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go
index 0381951ca..979dba5a1 100644
--- a/filesystem/filesystem.go
+++ b/filesystem/filesystem.go
@@ -868,7 +868,9 @@ func (f *filesystem) copyPackagingSpecs(ctx android.ModuleContext, builder *andr
dirsToSpecs[rootDir] = rootDirSpecs
dirsToSpecs[rebasedDir] = rebasedDirSpecs
- return f.CopySpecsToDirs(ctx, builder, dirsToSpecs)
+ // Preserve timestamps for adb sync, so that this staging dir file matches the timestamp in the
+ // out/target/product staging directory.
+ return f.CopySpecsToDirs(ctx, builder, dirsToSpecs, true)
}
func (f *filesystem) rootDirString() string {