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