From 760658054c5d7545f4e25fa339c4633d88800f94 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 4 Aug 2017 07:28:30 +0200 Subject: Make file_rule match mtime_targets that have valid timestamp This can be used to handle installed target groups like lib{}. --- build2/rule.cxx | 60 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 32 insertions(+), 28 deletions(-) (limited to 'build2/rule.cxx') 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 ()); - // 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 ()); - 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 ()); + 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; } } -- cgit v1.1