diff options
Diffstat (limited to 'build2/algorithm.cxx')
-rw-r--r-- | build2/algorithm.cxx | 89 |
1 files changed, 55 insertions, 34 deletions
diff --git a/build2/algorithm.cxx b/build2/algorithm.cxx index a22837f..17768e3 100644 --- a/build2/algorithm.cxx +++ b/build2/algorithm.cxx @@ -478,60 +478,81 @@ namespace build2 } target_state - perform_clean (action a, target& t) + clean_extra (action a, file& ft, initializer_list<const char*> es) { - // The reverse order of update: first remove the file, then clean - // prerequisites. + // Clean the extras first and don't print the commands at verbosity level + // below 3. // - file& ft (dynamic_cast<file&> (t)); + target_state er (target_state::unchanged); + path ef; // First extra file that actually got removed (see below). - target_state r (rmfile (ft.path (), ft) - ? target_state::changed - : target_state::unchanged); + for (const char* e: es) + { + if (e == nullptr) + continue; - // Update timestamp in case there are operations after us that - // could use the information. - // - ft.mtime (timestamp_nonexistent); + path f; + if (*e == '+') + f = ft.path () + ++e; + else + f = ft.path ().base () + e; - // Clean prerequisites. - // - r |= reverse_execute_prerequisites (a, t); + target_state r (rmfile (f, false) + ? target_state::changed + : target_state::unchanged); - return r; - } + if (r == target_state::changed && ef.empty ()) + { + ef = move (f); + } - target_state - perform_clean_depdb (action a, target& t) - { - // Normally the .d file is created/updated before the target so remove it - // first. Also, don't print the command at verbosity level below 3. - // - file& ft (dynamic_cast<file&> (t)); + er |= r; + } - path df (ft.path () + ".d"); - target_state dr (rmfile (df, false) + // Now clean the primary target and its prerequisited in the reverse order + // of update: first remove the file, then clean the prerequisites. + // + target_state tr (rmfile (ft.path (), ft) ? target_state::changed : target_state::unchanged); - // Factor the result of removing the .d file into the target state. While - // strictly speaking removing it doesn't change the target state, if we - // don't do this, then we may end up removing the file but still saying - // that everything is clean (e.g., if someone removes the target file but - // leaves .d laying around). That would be confusing. + // Update timestamp in case there are operations after us that could use + // the information. + // + ft.mtime (timestamp_nonexistent); + + // Clean prerequisites. // - target_state tr (perform_clean (a, t)); + tr |= reverse_execute_prerequisites (a, ft); + // Factor the result of removing the extra files into the target state. + // While strictly speaking removing them doesn't change the target state, + // if we don't do this, then we may end up removing the file but still + // saying that everything is clean (e.g., if someone removes the target + // file but leaves the extra laying around). That would be confusing. + // // What would also be confusing is if we didn't print any commands in // this case. // - if (tr == target_state::unchanged && dr == target_state::changed) + if (tr != target_state::changed && er == target_state::changed) { if (verb > 0 && verb < 3) - text << "rm " << df; + text << "rm " << ef; } - tr |= dr; + tr |= er; return tr; } + + target_state + perform_clean (action a, target& t) + { + return clean_extra (a, dynamic_cast<file&> (t), {}); + } + + target_state + perform_clean_depdb (action a, target& t) + { + return clean_extra (a, dynamic_cast<file&> (t), {"+.d"}); + } } |