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 <map> 10 #include <memory> 11 12 #include "base/macros.h" 13 #include "gn/builder_record.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 private: 64 bool TargetDefined(BuilderRecord* record, Err* err); 65 bool ConfigDefined(BuilderRecord* record, Err* err); 66 bool ToolchainDefined(BuilderRecord* record, Err* err); 67 68 // Returns the record associated with the given label. This function checks 69 // that if we already have references for it, the type matches. If no record 70 // exists yet, a new one will be created. 71 // 72 // If any of the conditions fail, the return value will be null and the error 73 // will be set. request_from is used as the source of the error. 74 BuilderRecord* GetOrCreateRecordOfType(const Label& label, 75 const ParseNode* request_from, 76 BuilderRecord::ItemType type, 77 Err* err); 78 79 // Returns the record associated with the given label. This function checks 80 // that it's already been resolved to the correct type. 81 // 82 // If any of the conditions fail, the return value will be null and the error 83 // will be set. request_from is used as the source of the error. 84 BuilderRecord* GetResolvedRecordOfType(const Label& label, 85 const ParseNode* request_from, 86 BuilderRecord::ItemType type, 87 Err* err); 88 89 bool AddDeps(BuilderRecord* record, 90 const LabelConfigVector& configs, 91 Err* err); 92 bool AddDeps(BuilderRecord* record, 93 const UniqueVector<LabelConfigPair>& configs, 94 Err* err); 95 bool AddDeps(BuilderRecord* record, 96 const LabelTargetVector& targets, 97 Err* err); 98 bool AddActionValuesDep(BuilderRecord* record, 99 const ActionValues& action_values, 100 Err* err); 101 bool AddToolchainDep(BuilderRecord* record, const Target* target, Err* err); 102 103 // Given a target, sets the "should generate" bit and pushes it through the 104 // dependency tree. Any time the bit it set, we ensure that the given item is 105 // scheduled to be loaded. 106 // 107 // If the force flag is set, we'll ignore the current state of the record's 108 // should_generate flag, and set it on the dependents every time. This is 109 // used when defining a target: the "should generate" may have been set 110 // before the item was defined (if it is required by something that is 111 // required). In this case, we need to re-push the "should generate" flag 112 // to the item's dependencies. 113 void RecursiveSetShouldGenerate(BuilderRecord* record, bool force); 114 115 void ScheduleItemLoadIfNecessary(BuilderRecord* record); 116 117 // This takes a BuilderRecord with resolved depdencies, and fills in the 118 // target's Label*Vectors with the resolved pointers. 119 bool ResolveItem(BuilderRecord* record, Err* err); 120 121 // Fills in the pointers in the given vector based on the labels. We assume 122 // that everything should be resolved by this point, so will return an error 123 // if anything isn't found or if the type doesn't match. 124 bool ResolveDeps(LabelTargetVector* deps, Err* err); 125 bool ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err); 126 bool ResolveActionValues(ActionValues* action_values, Err* err); 127 bool ResolveToolchain(Target* target, Err* err); 128 bool ResolvePools(Toolchain* toolchain, Err* err); 129 130 // Given a list of unresolved records, tries to find any circular 131 // dependencies and returns the string describing the problem. If no circular 132 // deps were found, returns the empty string. 133 std::string CheckForCircularDependencies( 134 const std::vector<const BuilderRecord*>& bad_records) const; 135 136 // Non owning pointer. 137 Loader* loader_; 138 139 std::map<Label, std::unique_ptr<BuilderRecord>> records_; 140 141 ResolvedGeneratedCallback resolved_and_generated_callback_; 142 143 DISALLOW_COPY_AND_ASSIGN(Builder); 144 }; 145 146 #endif // TOOLS_GN_BUILDER_H_ 147