ecf9e5489f633b24bc58acb560395f702dd33829
[platform/upstream/ninja.git] / src / graph.h
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef NINJA_GRAPH_H_
16 #define NINJA_GRAPH_H_
17
18 #include <string>
19 #include <vector>
20 using namespace std;
21
22 #include "eval_env.h"
23
24 struct DiskInterface;
25
26 struct Node;
27 struct FileStat {
28   FileStat(const string& path) : path_(path), mtime_(-1), node_(NULL) {}
29
30   // Return true if the file exists (mtime_ got a value).
31   bool Stat(DiskInterface* disk_interface);
32
33   // Return true if we needed to stat.
34   bool StatIfNecessary(DiskInterface* disk_interface) {
35     if (status_known())
36       return false;
37     Stat(disk_interface);
38     return true;
39   }
40
41   bool exists() const {
42     return mtime_ != 0;
43   }
44
45   bool status_known() const {
46     return mtime_ != -1;
47   }
48
49   string path_;
50   // Possible values of mtime_:
51   //   -1: file hasn't been examined
52   //   0:  we looked, and file doesn't exist
53   //   >0: actual file's mtime
54   time_t mtime_;
55   Node* node_;
56 };
57
58 struct Edge;
59 struct Node {
60   Node(FileStat* file) : file_(file), dirty_(false), in_edge_(NULL) {}
61
62   bool dirty() const { return dirty_; }
63
64   FileStat* file_;
65   bool dirty_;
66   Edge* in_edge_;
67   vector<Edge*> out_edges_;
68 };
69
70 struct Rule {
71   Rule(const string& name) : name_(name) { }
72
73   bool ParseCommand(const string& command, string* err) {
74     return command_.Parse(command, err);
75   }
76   string name_;
77   EvalString command_;
78   EvalString description_;
79   EvalString depfile_;
80 };
81
82 struct State;
83 struct Edge {
84   Edge() : rule_(NULL), env_(NULL), implicit_deps_(0), order_only_deps_(0) {}
85
86   bool RecomputeDirty(State* state, DiskInterface* disk_interface, string* err);
87   string EvaluateCommand();  // XXX move to env, take env ptr
88   string GetDescription();
89   bool LoadDepFile(State* state, DiskInterface* disk_interface, string* err);
90
91   void Dump();
92
93   const Rule* rule_;
94   vector<Node*> inputs_;
95   vector<Node*> outputs_;
96   Env* env_;
97
98   // XXX There are three types of inputs.
99   // 1) explicit deps, which show up as $in on the command line;
100   // 2) implicit deps, which the target depends on implicitly (e.g. C headers),
101   //                   and changes in them cause the target to rebuild;
102   // 3) order-only deps, which are needed before the target builds but which
103   //                     don't cause the target to rebuild.
104   // Currently we stuff all of these into inputs_ and keep counts of #2 and #3
105   // when we need to compute subsets.  This is suboptimal; should think of a
106   // better representation.  (Could make each pointer into a pair of a pointer
107   // and a type of input, or if memory matters could use the low bits of the
108   // pointer...)
109   int implicit_deps_;
110   int order_only_deps_;
111   bool is_implicit(int index) {
112     return index >= ((int)inputs_.size()) - order_only_deps_ - implicit_deps_ &&
113         !is_order_only(index);
114   }
115   bool is_order_only(int index) {
116     return index >= ((int)inputs_.size()) - order_only_deps_;
117   }
118
119   bool is_phony() const;
120 };
121
122 // Exposed for testing.
123 bool CanonicalizePath(string* path, string* err);
124
125 #endif  // NINJA_GRAPH_H_