aboutsummaryrefslogtreecommitdiff
path: root/build2/cc
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-01-18 13:50:58 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-01-18 13:50:58 +0200
commitd402bc96297c6ed3dd6ee883dcff8cc39bd01030 (patch)
tree634d397f48022935926e26123c13ab8adad6796e /build2/cc
parent34be21a72a396240642acf3050eead875d3ed4b4 (diff)
Ignore prerequisite mtimes that are not linker inputs
This makes sure, for example, that we don't unnecessarily re-link an executable when its testscript prerequisite is changes.
Diffstat (limited to 'build2/cc')
-rw-r--r--build2/cc/compile.cxx25
-rw-r--r--build2/cc/link.cxx26
2 files changed, 30 insertions, 21 deletions
diff --git a/build2/cc/compile.cxx b/build2/cc/compile.cxx
index 6fd64c2..3318f21 100644
--- a/build2/cc/compile.cxx
+++ b/build2/cc/compile.cxx
@@ -888,16 +888,7 @@ namespace build2
}
}
- if (ts != timestamp_unknown)
- {
- timestamp mt (pt.mtime ());
-
- // See execute_prerequisites() for rationale behind the equal part.
- //
- return ts < mt || (ts == mt && pt.state () != target_state::changed);
- }
-
- return false;
+ return ts != timestamp_unknown ? pt.newer (ts) : false;
};
// Update and add a header file to the list of prerequisite targets.
@@ -1394,10 +1385,18 @@ namespace build2
perform_update (action a, target& xt) const
{
file& t (static_cast<file&> (xt));
- file* s (execute_prerequisites<file> (x_src, a, t, t.mtime ()));
- if (s == nullptr)
- return target_state::unchanged;
+ // Update prerequisites and determine if any relevant ones render us
+ // out-of-date. Note that currently we treat all the prerequisites
+ // as potentially affecting the result (for simplicity/performance).
+ //
+ file* s;
+ {
+ auto p (execute_prerequisites<file> (x_src, a, t, t.mtime ()));
+
+ if ((s = p.first) == nullptr)
+ return p.second;
+ }
scope& bs (t.base_scope ());
scope& rs (*bs.root_scope ());
diff --git a/build2/cc/link.cxx b/build2/cc/link.cxx
index 9dbfa36..a6b67d5 100644
--- a/build2/cc/link.cxx
+++ b/build2/cc/link.cxx
@@ -890,9 +890,12 @@ namespace build2
otype lt (link_type (t));
lorder lo (link_order (bs, lt));
- // Update prerequisites.
+ // Update prerequisites. We determine if any relevant ones render us
+ // out-of-date manually below.
//
- bool update (execute_prerequisites (a, t, t.mtime ()));
+ bool update (false);
+ timestamp mt (t.mtime ());
+ target_state ts (execute_prerequisites (a, t));
// If targeting Windows, take care of the manifest.
//
@@ -913,7 +916,7 @@ namespace build2
t,
rpath_timestamp != timestamp_nonexistent));
- timestamp mt (file_mtime (mf));
+ timestamp mf_mt (file_mtime (mf));
if (tsys == "mingw32")
{
@@ -923,7 +926,7 @@ namespace build2
//
manifest = mf + ".o";
- if (mt > file_mtime (manifest))
+ if (mf_mt > file_mtime (manifest))
{
path of (relative (manifest));
@@ -998,7 +1001,7 @@ namespace build2
{
manifest = move (mf); // Save for link.exe's /MANIFESTINPUT.
- if (mt > t.mtime ())
+ if (mf_mt > mt)
update = true; // Manifest changed, force update.
}
}
@@ -1204,9 +1207,16 @@ namespace build2
else
cs.append (f->path ().string ());
}
+ else
+ f = pt->is_a<exe> (); // Consider executable mtime (e.g., linker).
+
+ // Check if this input renders us out-of-date.
+ //
+ if (f != nullptr)
+ update = update || f->newer (mt);
}
- // Treat it as input for both MinGW and VC.
+ // Treat it as input for both MinGW and VC (mtime checked above).
//
if (!manifest.empty ())
cs.append (manifest.string ());
@@ -1229,7 +1239,7 @@ namespace build2
// this situation in the "from scratch" flag.
//
bool scratch (false);
- if (dd.writing () || dd.mtime () > t.mtime ())
+ if (dd.writing () || dd.mtime () > mt)
scratch = update = true;
dd.close ();
@@ -1237,7 +1247,7 @@ namespace build2
// If nothing changed, then we are done.
//
if (!update)
- return target_state::unchanged;
+ return ts;
// Ok, so we are updating. Finish building the command line.
//