diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2017-08-04 07:28:30 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2017-08-04 07:28:30 +0200 |
commit | 760658054c5d7545f4e25fa339c4633d88800f94 (patch) | |
tree | 447225d234cb731f552bb72565518b9e40638d9c | |
parent | e6bdc9158d1951e6c29a024568c2d5a285d1bd65 (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.cxx | 2 | ||||
-rw-r--r-- | build2/context.cxx | 4 | ||||
-rw-r--r-- | build2/rule.cxx | 60 |
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; } } |