aboutsummaryrefslogtreecommitdiff
path: root/build2
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2019-04-10 14:16:21 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2019-04-10 15:16:32 +0200
commit9bd1a1619e282c585b3f202d84790f8811d1e4d6 (patch)
tree50d7660f772c123b4f24d06119821215d7497718 /build2
parent47ee9b8274cba0014afe59019d76613da8bb45d6 (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
Diffstat (limited to 'build2')
-rw-r--r--build2/cc/compile-rule.cxx22
-rw-r--r--build2/context.hxx4
-rw-r--r--build2/rule.cxx6
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;});