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