1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file. 4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef TOOLS_GN_BUILDER_H_ 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define TOOLS_GN_BUILDER_H_ 7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/basictypes.h" 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/callback.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/containers/hash_tables.h" 11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/memory/ref_counted.h" 12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "tools/gn/builder_record.h" 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "tools/gn/label.h" 14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "tools/gn/label_ptr.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "tools/gn/unique_vector.h" 16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Config; 18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Err; 19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Loader; 20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ParseNode; 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class Builder : public base::RefCountedThreadSafe<Builder> { 23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public: 24e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch typedef base::Callback<void(const BuilderRecord*)> ResolvedCallback; 25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Builder(Loader* loader); 27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // The resolved callback is called whenever a target has been resolved. This 29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // will be executed only on the main thread. 30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void set_resolved_callback(const ResolvedCallback& cb) { 31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) resolved_callback_ = cb; 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Loader* loader() const { return loader_; } 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void ItemDefined(scoped_ptr<Item> item); 37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Returns NULL if there is not a thing with the corresponding label. 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Item* GetItem(const Label& label) const; 40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Toolchain* GetToolchain(const Label& label) const; 41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<const BuilderRecord*> GetAllRecords() const; 43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Returns targets which should be generated and which are defined. 45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<const Target*> GetAllResolvedTargets() const; 46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Returns the record for the given label, or NULL if it doesn't exist. 48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Mostly used for unit tests. 49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const BuilderRecord* GetRecord(const Label& label) const; 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BuilderRecord* GetRecord(const Label& label); 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If there are any undefined references, returns false and sets the error. 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool CheckForBadItems(Err* err) const; 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) private: 56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) friend class base::RefCountedThreadSafe<Builder>; 57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) virtual ~Builder(); 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool TargetDefined(BuilderRecord* record, Err* err); 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool ToolchainDefined(BuilderRecord* record, Err* err); 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Returns the record associated with the given label. This function checks 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // that if we already have references for it, the type matches. If no record 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // exists yet, a new one will be created. 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If any of the conditions fail, the return value will be null and the error 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // will be set. request_from is used as the source of the error. 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BuilderRecord* GetOrCreateRecordOfType(const Label& label, 70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ParseNode* request_from, 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BuilderRecord::ItemType type, 72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Err* err); 73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Returns the record associated with the given label. This function checks 75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // that it's already been resolved to the correct type. 76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If any of the conditions fail, the return value will be null and the error 78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // will be set. request_from is used as the source of the error. 79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BuilderRecord* GetResolvedRecordOfType(const Label& label, 80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const ParseNode* request_from, 81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BuilderRecord::ItemType type, 82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Err* err); 83f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool AddDeps(BuilderRecord* record, 85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const LabelConfigVector& configs, 86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Err* err); 87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool AddDeps(BuilderRecord* record, 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const UniqueVector<LabelConfigPair>& configs, 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Err* err); 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool AddDeps(BuilderRecord* record, 91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const LabelTargetVector& targets, 92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Err* err); 93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool AddToolchainDep(BuilderRecord* record, 94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const Target* target, 95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Err* err); 96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Given a target, sets the "should generate" bit and pushes it through the 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // dependency tree. Any time the bit it set, we ensure that the given item is 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // scheduled to be loaded. 100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // 101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If the force flag is set, we'll ignore the current state of the record's 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // should_generate flag, and set it on the dependents every time. This is 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // used when defining a target: the "should generate" may have been set 104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // before the item was defined (if it is required by something that is 105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // required). In this case, we need to re-push the "should generate" flag 106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // to the item's dependencies. 107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void RecursiveSetShouldGenerate(BuilderRecord* record, bool force); 108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) void ScheduleItemLoadIfNecessary(BuilderRecord* record); 110f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // This takes a BuilderRecord with resolved depdencies, and fills in the 112f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // target's Label*Vectors with the resolved pointers. 113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool ResolveItem(BuilderRecord* record, Err* err); 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Fills in the pointers in the given vector based on the labels. We assume 116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // that everything should be resolved by this point, so will return an error 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // if anything isn't found or if the type doesn't match. 118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool ResolveDeps(LabelTargetVector* deps, Err* err); 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool ResolveConfigs(UniqueVector<LabelConfigPair>* configs, Err* err); 120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool ResolveForwardDependentConfigs(Target* target, Err* err); 12103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) bool ResolveToolchain(Target* target, Err* err); 122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 123f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Given a list of unresolved records, tries to find any circular 124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // dependencies and returns the string describing the problem. If no circular 125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // deps were found, returns the empty string. 126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string CheckForCircularDependencies( 127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::vector<const BuilderRecord*>& bad_records) const; 128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 129f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Non owning pointer. 130f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Loader* loader_; 131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Owning pointers. 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) typedef base::hash_map<Label, BuilderRecord*> RecordMap; 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) RecordMap records_; 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ResolvedCallback resolved_callback_; 137f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 138f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Builder); 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}; 140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 141f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif // TOOLS_GN_BUILDER_H_ 142