• 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 AddActionValuesDep(BuilderRecord* record,
105                           const ActionValues& action_values,
106                           Err* err);
107   bool AddToolchainDep(BuilderRecord* record, const Target* target, Err* err);
108 
109   // Given a target, sets the "should generate" bit and pushes it through the
110   // dependency tree. Any time the bit it set, we ensure that the given item is
111   // scheduled to be loaded.
112   //
113   // If the force flag is set, we'll ignore the current state of the record's
114   // should_generate flag, and set it on the dependents every time. This is
115   // used when defining a target: the "should generate" may have been set
116   // before the item was defined (if it is required by something that is
117   // required). In this case, we need to re-push the "should generate" flag
118   // to the item's dependencies.
119   void RecursiveSetShouldGenerate(BuilderRecord* record, bool force);
120 
121   void ScheduleItemLoadIfNecessary(BuilderRecord* record);
122 
123   // This takes a BuilderRecord with resolved dependencies, and fills in the
124   // target's Label*Vectors with the resolved pointers.
125   bool ResolveItem(BuilderRecord* record, Err* err);
126 
127   // Fills in the pointers in the given vector based on the labels. We assume
128   // that everything should be resolved by this point, so will return an error
129   // if anything isn't found or if the type doesn't match.
130   bool ResolveDeps(LabelTargetVector* deps, Err* err);
131   bool ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err);
132   bool ResolveActionValues(ActionValues* action_values, Err* err);
133   bool ResolveToolchain(Target* target, Err* err);
134   bool ResolvePools(Toolchain* toolchain, Err* err);
135 
136   // Given a list of unresolved records, tries to find any circular
137   // dependencies and returns the string describing the problem. If no circular
138   // deps were found, returns the empty string.
139   std::string CheckForCircularDependencies(
140       const std::vector<const BuilderRecord*>& bad_records) const;
141 
142   // Non owning pointer.
143   Loader* loader_;
144 
145   BuilderRecordMap records_;
146 
147   ResolvedGeneratedCallback resolved_and_generated_callback_;
148 
149   Builder(const Builder&) = delete;
150   Builder& operator=(const Builder&) = delete;
151 };
152 
153 #endif  // TOOLS_GN_BUILDER_H_
154