mirror of
https://github.com/reactos/ninja.git
synced 2025-02-22 20:52:24 +00:00
clean: remove outputs specified by dyndep files
Some outputs may not be known in the main build manifest and are instead discovered through a dyndep binding. Load dyndep files that are available during cleaning so that we can clean these outputs too.
This commit is contained in:
parent
c21f3f2a1d
commit
a3cbb4d4dd
19
src/clean.cc
19
src/clean.cc
@ -27,6 +27,7 @@ Cleaner::Cleaner(State* state,
|
||||
DiskInterface* disk_interface)
|
||||
: state_(state),
|
||||
config_(config),
|
||||
dyndep_loader_(state, disk_interface),
|
||||
removed_(),
|
||||
cleaned_(),
|
||||
cleaned_files_count_(0),
|
||||
@ -103,6 +104,7 @@ void Cleaner::PrintFooter() {
|
||||
int Cleaner::CleanAll(bool generator) {
|
||||
Reset();
|
||||
PrintHeader();
|
||||
LoadDyndeps();
|
||||
for (vector<Edge*>::iterator e = state_->edges_.begin();
|
||||
e != state_->edges_.end(); ++e) {
|
||||
// Do not try to remove phony targets
|
||||
@ -148,6 +150,7 @@ int Cleaner::CleanTarget(Node* target) {
|
||||
|
||||
Reset();
|
||||
PrintHeader();
|
||||
LoadDyndeps();
|
||||
DoCleanTarget(target);
|
||||
PrintFooter();
|
||||
return status_;
|
||||
@ -170,6 +173,7 @@ int Cleaner::CleanTarget(const char* target) {
|
||||
int Cleaner::CleanTargets(int target_count, char* targets[]) {
|
||||
Reset();
|
||||
PrintHeader();
|
||||
LoadDyndeps();
|
||||
for (int i = 0; i < target_count; ++i) {
|
||||
string target_name = targets[i];
|
||||
uint64_t slash_bits;
|
||||
@ -213,6 +217,7 @@ int Cleaner::CleanRule(const Rule* rule) {
|
||||
|
||||
Reset();
|
||||
PrintHeader();
|
||||
LoadDyndeps();
|
||||
DoCleanRule(rule);
|
||||
PrintFooter();
|
||||
return status_;
|
||||
@ -237,6 +242,7 @@ int Cleaner::CleanRules(int rule_count, char* rules[]) {
|
||||
|
||||
Reset();
|
||||
PrintHeader();
|
||||
LoadDyndeps();
|
||||
for (int i = 0; i < rule_count; ++i) {
|
||||
const char* rule_name = rules[i];
|
||||
const Rule* rule = state_->bindings_.LookupRule(rule_name);
|
||||
@ -259,3 +265,16 @@ void Cleaner::Reset() {
|
||||
removed_.clear();
|
||||
cleaned_.clear();
|
||||
}
|
||||
|
||||
void Cleaner::LoadDyndeps() {
|
||||
// Load dyndep files that exist, before they are cleaned.
|
||||
for (vector<Edge*>::iterator e = state_->edges_.begin();
|
||||
e != state_->edges_.end(); ++e) {
|
||||
if (Node* dyndep = (*e)->dyndep_) {
|
||||
// Capture and ignore errors loading the dyndep file.
|
||||
// We clean as much of the graph as we know.
|
||||
std::string err;
|
||||
dyndep_loader_.LoadDyndeps(dyndep, &err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "build.h"
|
||||
#include "dyndep.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -91,8 +92,12 @@ struct Cleaner {
|
||||
void DoCleanRule(const Rule* rule);
|
||||
void Reset();
|
||||
|
||||
/// Load dependencies from dyndep bindings.
|
||||
void LoadDyndeps();
|
||||
|
||||
State* state_;
|
||||
const BuildConfig& config_;
|
||||
DyndepLoader dyndep_loader_;
|
||||
set<string> removed_;
|
||||
set<Node*> cleaned_;
|
||||
int cleaned_files_count_;
|
||||
|
@ -285,6 +285,55 @@ TEST_F(CleanTest, CleanDepFileOnCleanRule) {
|
||||
EXPECT_EQ(2u, fs_.files_removed_.size());
|
||||
}
|
||||
|
||||
TEST_F(CleanTest, CleanDyndep) {
|
||||
// Verify that a dyndep file can be loaded to discover a new output
|
||||
// to be cleaned.
|
||||
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
|
||||
"build out: cat in || dd\n"
|
||||
" dyndep = dd\n"
|
||||
));
|
||||
fs_.Create("in", "");
|
||||
fs_.Create("dd",
|
||||
"ninja_dyndep_version = 1\n"
|
||||
"build out | out.imp: dyndep\n"
|
||||
);
|
||||
fs_.Create("out", "");
|
||||
fs_.Create("out.imp", "");
|
||||
|
||||
Cleaner cleaner(&state_, config_, &fs_);
|
||||
|
||||
ASSERT_EQ(0, cleaner.cleaned_files_count());
|
||||
EXPECT_EQ(0, cleaner.CleanAll());
|
||||
EXPECT_EQ(2, cleaner.cleaned_files_count());
|
||||
EXPECT_EQ(2u, fs_.files_removed_.size());
|
||||
|
||||
string err;
|
||||
EXPECT_EQ(0, fs_.Stat("out", &err));
|
||||
EXPECT_EQ(0, fs_.Stat("out.imp", &err));
|
||||
}
|
||||
|
||||
TEST_F(CleanTest, CleanDyndepMissing) {
|
||||
// Verify that a missing dyndep file is tolerated.
|
||||
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
|
||||
"build out: cat in || dd\n"
|
||||
" dyndep = dd\n"
|
||||
));
|
||||
fs_.Create("in", "");
|
||||
fs_.Create("out", "");
|
||||
fs_.Create("out.imp", "");
|
||||
|
||||
Cleaner cleaner(&state_, config_, &fs_);
|
||||
|
||||
ASSERT_EQ(0, cleaner.cleaned_files_count());
|
||||
EXPECT_EQ(0, cleaner.CleanAll());
|
||||
EXPECT_EQ(1, cleaner.cleaned_files_count());
|
||||
EXPECT_EQ(1u, fs_.files_removed_.size());
|
||||
|
||||
string err;
|
||||
EXPECT_EQ(0, fs_.Stat("out", &err));
|
||||
EXPECT_EQ(1, fs_.Stat("out.imp", &err));
|
||||
}
|
||||
|
||||
TEST_F(CleanTest, CleanRspFile) {
|
||||
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
|
||||
"rule cc\n"
|
||||
|
Loading…
x
Reference in New Issue
Block a user