• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef TOOLS_GN_BUILDER_H_
6 #define TOOLS_GN_BUILDER_H_
7 
8 #include <functional>
9 #include <memory>
10 #include <unordered_map>
11 
12 #include "gn/builder_record.h"
13 #include "gn/builder_record_map.h"
14 #include "gn/label.h"
15 #include "gn/label_ptr.h"
16 #include "gn/unique_vector.h"
17 
18 class ActionValues;
19 class Err;
20 class Loader;
21 class ParseNode;
22 
23 // The builder assembles the dependency tree. It is not threadsafe and runs on
24 // the main thread only. See also BuilderRecord.
25 class Builder {
26  public:
27   using ResolvedGeneratedCallback = std::function<void(const BuilderRecord*)>;
28 
29   explicit Builder(Loader* loader);
30   ~Builder();
31 
32   // The resolved callback is called when a target has been both resolved and
33   // marked generated. This will be executed only on the main thread.
set_resolved_and_generated_callback(const ResolvedGeneratedCallback & cb)34   void set_resolved_and_generated_callback(
35       const ResolvedGeneratedCallback& cb) {
36     resolved_and_generated_callback_ = cb;
37   }
38 
loader()39   Loader* loader() const { return loader_; }
40 
41   void ItemDefined(std::unique_ptr<Item> item);
42 
43   // Returns NULL if there is not a thing with the corresponding label.
44   const Item* GetItem(const Label& label) const;
45   const Toolchain* GetToolchain(const Label& label) const;
46 
47   std::vector<const BuilderRecord*> GetAllRecords() const;
48 
49   // Returns items which should be generated and which are defined.
50   std::vector<const Item*> GetAllResolvedItems() const;
51 
52   // Returns targets which should be generated and which are defined.
53   std::vector<const Target*> GetAllResolvedTargets() const;
54 
55   // Returns the record for the given label, or NULL if it doesn't exist.
56   // Mostly used for unit tests.
57   const BuilderRecord* GetRecord(const Label& label) const;
58   BuilderRecord* GetRecord(const Label& label);
59 
60   // If there are any undefined references, returns false and sets the error.
61   bool CheckForBadItems(Err* err) const;
62 
63   // Get or create an empty record for unit-testing.
64   BuilderRecord* GetOrCreateRecordForTesting(const Label& label);
65 
66  private:
67   bool TargetDefined(BuilderRecord* record, Err* err);
68   bool ConfigDefined(BuilderRecord* record, Err* err);
69   bool ToolchainDefined(BuilderRecord* record, Err* err);
70 
71   // Returns the record associated with the given label. This function checks
72   // that if we already have references for it, the type matches. If no record
73   // exists yet, a new one will be created.
74   //
75   // If any of the conditions fail, the return value will be null and the error
76   // will be set. request_from is used as the source of the error.
77   BuilderRecord* GetOrCreateRecordOfType(const Label& label,
78                                          const ParseNode* request_from,
79                                          BuilderRecord::ItemType type,
80                                          Err* err);
81 
82   // Returns the record associated with the given label. This function checks
83   // that it's already been resolved to the correct type.
84   //
85   // If any of the conditions fail, the return value will be null and the error
86   // will be set. request_from is used as the source of the error.
87   BuilderRecord* GetResolvedRecordOfType(const Label& label,
88                                          const ParseNode* request_from,
89                                          BuilderRecord::ItemType type,
90                                          Err* err);
91 
92   bool AddDeps(BuilderRecord* record,
93                const LabelConfigVector& configs,
94                Err* err);
95   bool AddDeps(BuilderRecord* record,
96                const UniqueVector<LabelConfigPair>& configs,
97                Err* err);
98   bool AddDeps(BuilderRecord* record,
99                const LabelTargetVector& targets,
100                Err* err);
101   bool AddGenDeps(BuilderRecord* record,
102                   const LabelTargetVector& targets,
103                   Err* err);
104   bool AddPoolDep(BuilderRecord* record, const Target* target, Err* err);
105   bool AddToolchainDep(BuilderRecord* record, const Target* target, Err* err);
106 
107   // Given a target, sets the "should generate" bit and pushes it through the
108   // dependency tree. Any time the bit it set, we ensure that the given item is
109   // scheduled to be loaded.
110   //
111   // If the force flag is set, we'll ignore the current state of the record's
112   // should_generate flag, and set it on the dependents every time. This is
113   // used when defining a target: the "should generate" may have been set
114   // before the item was defined (if it is required by something that is
115   // required). In this case, we need to re-push the "should generate" flag
116   // to the item's dependencies.
117   void RecursiveSetShouldGenerate(BuilderRecord* record, bool force);
118 
119   void ScheduleItemLoadIfNecessary(BuilderRecord* record);
120 
121   // This takes a BuilderRecord with resolved dependencies, and fills in the
122   // target's Label*Vectors with the resolved pointers.
123   bool ResolveItem(BuilderRecord* record, Err* err);
124 
125   // Fills in the pointers in the given vector based on the labels. We assume
126   // that everything should be resolved by this point, so will return an error
127   // if anything isn't found or if the type doesn't match.
128   bool ResolveDeps(LabelTargetVector* deps, Err* err);
129   bool ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err);
130   bool ResolvePool(Target* target, Err* err);
131   bool ResolveToolchain(Target* target, Err* err);
132   bool ResolvePools(Toolchain* toolchain, Err* err);
133 
134   // Given a list of unresolved records, tries to find any circular
135   // dependencies and returns the string describing the problem. If no circular
136   // deps were found, returns the empty string.
137   std::string CheckForCircularDependencies(
138       const std::vector<const BuilderRecord*>& bad_records) const;
139 
140   // Non owning pointer.
141   Loader* loader_;
142 
143   BuilderRecordMap records_;
144 
145   ResolvedGeneratedCallback resolved_and_generated_callback_;
146 
147   Builder(const Builder&) = delete;
148   Builder& operator=(const Builder&) = delete;
149 };
150 
151 #endif  // TOOLS_GN_BUILDER_H_
152