aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2017-08-04 07:28:30 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2017-08-04 07:28:30 +0200
commit760658054c5d7545f4e25fa339c4633d88800f94 (patch)
tree447225d234cb731f552bb72565518b9e40638d9c
parente6bdc9158d1951e6c29a024568c2d5a285d1bd65 (diff)
Make file_rule match mtime_targets that have valid timestamp
This can be used to handle installed target groups like lib{}.
-rw-r--r--build2/config/init.cxx2
-rw-r--r--build2/context.cxx4
-rw-r--r--build2/rule.cxx60
3 files changed, 35 insertions, 31 deletions
diff --git a/build2/config/init.cxx b/build2/config/init.cxx
index 889285d..040aeca 100644
--- a/build2/config/init.cxx
+++ b/build2/config/init.cxx
@@ -137,7 +137,7 @@ namespace build2
// libraries imported from /usr/lib). Registring it on the global
// scope smells a bit but seems harmless.
//
- rs.global ().rules.insert<file> (
+ rs.global ().rules.insert<mtime_target> (
configure_id, 0, "config.file", file_rule::instance);
auto& r (rs.rules);
diff --git a/build2/context.cxx b/build2/context.cxx
index d979f92..11c2c63 100644
--- a/build2/context.cxx
+++ b/build2/context.cxx
@@ -550,8 +550,8 @@ namespace build2
r.insert<fsdir> (perform_update_id, "fsdir", fsdir_rule::instance);
r.insert<fsdir> (perform_clean_id, "fsdir", fsdir_rule::instance);
- r.insert<file> (perform_update_id, "file", file_rule::instance);
- r.insert<file> (perform_clean_id, "file", file_rule::instance);
+ r.insert<mtime_target> (perform_update_id, "file", file_rule::instance);
+ r.insert<mtime_target> (perform_clean_id, "file", file_rule::instance);
}
return vos;
diff --git a/build2/rule.cxx b/build2/rule.cxx
index 91a111d..690833a 100644
--- a/build2/rule.cxx
+++ b/build2/rule.cxx
@@ -34,60 +34,64 @@ namespace build2
// for every action (because that's the condition for us matching),
// for some actions this is clearly a waste. Say, perform_clean: we
// are not doing anything for this action so not checking if the file
- // exists seems harmless. So the overall guideline seems to be this:
- // if we don't do anything for the action (other than performing it
- // on the prerequisites), then we match.
+ // exists seems harmless.
//
switch (a)
{
- case perform_update_id:
+ case perform_clean_id:
+ return true;
+ default:
{
// While normally we shouldn't do any of this in match(), no other
// rule should ever be ambiguous with the fallback one and path/mtime
// access is atomic. In other words, we know what we are doing but
// don't do this in normal rules.
- path_target& pt (t.as<path_target> ());
-
// First check the timestamp. This takes care of the special "trust
// me, this file exists" situations (used, for example, for installed
// stuff where we know it's there, just not exactly where).
//
- timestamp ts (pt.mtime ());
+ mtime_target& mt (t.as<mtime_target> ());
- if (ts == timestamp_unknown)
- {
- const path* p (&pt.path ());
+ timestamp ts (mt.mtime ());
- // Assign the path.
+ if (ts != timestamp_unknown && ts != timestamp_nonexistent)
+ return true;
+
+ // Otherwise, if this is not a path_target, then we don't match.
+ //
+ path_target* pt (mt.is_a<path_target> ());
+ if (pt == nullptr)
+ return false;
+
+ const path* p (&pt->path ());
+
+ // Assign the path.
+ //
+ if (p->empty ())
+ {
+ // Since we cannot come up with an extension, ask the target's
+ // derivation function to treat this as prerequisite (just like in
+ // search_existing_file()).
//
- if (p->empty ())
+ if (pt->derive_extension (true) == nullptr)
{
- // Since we cannot come up with an extension, ask the target's
- // derivation function to treat this as prerequisite (just like
- // in search_existing_file()).
- //
- if (pt.derive_extension (true) == nullptr)
- {
- l4 ([&]{trace << "no default extension for target " << pt;});
- return false;
- }
-
- p = &pt.derive_path ();
+ l4 ([&]{trace << "no default extension for target " << *pt;});
+ return false;
}
- ts = file_mtime (*p);
- pt.mtime (ts);
+ p = &pt->derive_path ();
}
+ ts = file_mtime (*p);
+ pt->mtime (ts);
+
if (ts != timestamp_unknown && ts != timestamp_nonexistent)
return true;
- l4 ([&]{trace << "no existing file for target " << t;});
+ l4 ([&]{trace << "no existing file for target " << *pt;});
return false;
}
- default:
- return true;
}
}