diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2019-04-10 14:16:21 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2019-04-10 15:16:32 +0200 |
commit | 9bd1a1619e282c585b3f202d84790f8811d1e4d6 (patch) | |
tree | 50d7660f772c123b4f24d06119821215d7497718 | |
parent | 47ee9b8274cba0014afe59019d76613da8bb45d6 (diff) |
Always use cached mtime if available
Besides other things, this is required for "logical clean" in the try-run
mode to work properly:
$ b -vn clean update
-rw-r--r-- | build2/cc/compile-rule.cxx | 22 | ||||
-rw-r--r-- | build2/context.hxx | 4 | ||||
-rw-r--r-- | build2/rule.cxx | 6 |
3 files changed, 26 insertions, 6 deletions
diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx index 3050a37..92ba32d 100644 --- a/build2/cc/compile-rule.cxx +++ b/build2/cc/compile-rule.cxx @@ -823,8 +823,22 @@ namespace build2 // compiler, options, or source file) or if the depdb is newer than // the target (interrupted update), then do unconditional update. // + // Note that load_mtime() can only be used in the execute phase so we + // have to check for a cached value manually. + // + bool u; timestamp mt; - bool u (dd.writing () || dd.mtime > (mt = mtime (tp))); + + if (dd.writing ()) + u = true; + else + { + if ((mt = t.mtime ()) == timestamp_unknown) + t.mtime (mt = mtime (tp)); // Cache. + + u = dd.mtime > mt; + } + if (u) mt = timestamp_nonexistent; // Treat as if it doesn't exist. @@ -1045,6 +1059,9 @@ namespace build2 // store the first in the target file (so we do touch it) and the // second in depdb (which is never newer that the target). // + // Perhaps when we start keeping the partially preprocessed this will + // fall away? Yes, please. + // md.mt = u ? timestamp_nonexistent : dd.mtime; } @@ -4319,10 +4336,11 @@ namespace build2 if (md.touch) { touch (tp, false, 2); + t.mtime (system_clock::now ()); skip_count.fetch_add (1, memory_order_relaxed); } + // Note: else mtime should be cached. - t.mtime (md.mt); return *pr.first; } diff --git a/build2/context.hxx b/build2/context.hxx index a8d6833..5799eef 100644 --- a/build2/context.hxx +++ b/build2/context.hxx @@ -420,7 +420,9 @@ namespace build2 // Note that for this mode to function properly we have to use fake mtimes. // Specifically, a rule that pretends to update a target must set its mtime // to system_clock::now() and everyone else must use this cached value. In - // other words, there should be no mtime re-query from the filesystem. + // other words, there should be no mtime re-query from the filesystem. The + // same is required for "logical clean" (i.e., dry-run 'clean update' in + // order to see all the command lines). // // At first, it may seem like we should also "dry-run" changes to depdb. But // that would be both problematic (some rules update it in apply() during diff --git a/build2/rule.cxx b/build2/rule.cxx index 79b91b3..a09e28b 100644 --- a/build2/rule.cxx +++ b/build2/rule.cxx @@ -55,8 +55,8 @@ namespace build2 timestamp ts (mt.mtime ()); - if (ts != timestamp_unknown && ts != timestamp_nonexistent) - return true; + if (ts != timestamp_unknown) + return ts != timestamp_nonexistent; // Otherwise, if this is not a path_target, then we don't match. // @@ -86,7 +86,7 @@ namespace build2 ts = mtime (*p); pt->mtime (ts); - if (ts != timestamp_unknown && ts != timestamp_nonexistent) + if (ts != timestamp_nonexistent) return true; l4 ([&]{trace << "no existing file for target " << *pt;}); |