class State;
struct Edge {
- Edge() : rule_(NULL), env_(NULL) {}
+ Edge() : rule_(NULL), env_(NULL), implicit_deps_(0) {}
void MarkDirty(Node* node);
bool RecomputeDirty(State* state, DiskInterface* disk_interface, string* err);
string EvaluateCommand(); // XXX move to env, take env ptr
bool LoadDepFile(State* state, DiskInterface* disk_interface, string* err);
- Rule* rule_;
enum InOut { IN, OUT };
+
+ Rule* rule_;
vector<Node*> inputs_;
vector<Node*> outputs_;
EvalString::Env* env_;
+ int implicit_deps_; // Count on the end of the inputs list.
};
void FileStat::Touch(int mtime) {
virtual string Evaluate(const string& var) {
string result;
if (var == "@in") {
+ int explicit_deps = edge_->inputs_.size() - edge_->implicit_deps_;
for (vector<Node*>::iterator i = edge_->inputs_.begin();
- i != edge_->inputs_.end(); ++i) {
+ i != edge_->inputs_.end() && explicit_deps; ++i, --explicit_deps) {
if (!result.empty())
result.push_back(' ');
result.append((*i)->file_->path_);
if (node) {
inputs_.push_back(node);
node->out_edges_.push_back(this);
+ ++implicit_deps_;
}
}
// Expect our edge to now have three inputs: foo.c and two headers.
ASSERT_EQ(orig_edges + 1, state_.edges_.size());
- ASSERT_EQ(3, state_.edges_.back()->inputs_.size());
+ Edge* edge = state_.edges_.back();
+ ASSERT_EQ(3, edge->inputs_.size());
+
+ // Expect the command line we generate to only use the original input.
+ ASSERT_EQ("cc foo.c", edge->EvaluateCommand());
}
TEST_F(BuildTest, DepFileParseError) {