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.
5 #ifndef TOOLS_GN_BUILDER_H_
6 #define TOOLS_GN_BUILDER_H_
8 #include "base/basictypes.h"
9 #include "base/callback.h"
10 #include "base/containers/hash_tables.h"
11 #include "base/memory/ref_counted.h"
12 #include "tools/gn/builder_record.h"
13 #include "tools/gn/label.h"
14 #include "tools/gn/label_ptr.h"
15 #include "tools/gn/unique_vector.h"
22 class Builder
: public base::RefCountedThreadSafe
<Builder
> {
24 typedef base::Callback
<void(const BuilderRecord
*)> ResolvedCallback
;
26 Builder(Loader
* loader
);
28 // The resolved callback is called whenever a target has been resolved. This
29 // will be executed only on the main thread.
30 void set_resolved_callback(const ResolvedCallback
& cb
) {
31 resolved_callback_
= cb
;
34 Loader
* loader() const { return loader_
; }
36 void ItemDefined(scoped_ptr
<Item
> item
);
38 // Returns NULL if there is not a thing with the corresponding label.
39 const Item
* GetItem(const Label
& label
) const;
40 const Toolchain
* GetToolchain(const Label
& label
) const;
42 std::vector
<const BuilderRecord
*> GetAllRecords() const;
44 // Returns targets which should be generated and which are defined.
45 std::vector
<const Target
*> GetAllResolvedTargets() const;
47 // Returns the record for the given label, or NULL if it doesn't exist.
48 // Mostly used for unit tests.
49 const BuilderRecord
* GetRecord(const Label
& label
) const;
50 BuilderRecord
* GetRecord(const Label
& label
);
52 // If there are any undefined references, returns false and sets the error.
53 bool CheckForBadItems(Err
* err
) const;
56 friend class base::RefCountedThreadSafe
<Builder
>;
60 bool TargetDefined(BuilderRecord
* record
, Err
* err
);
61 bool ToolchainDefined(BuilderRecord
* record
, Err
* err
);
63 // Returns the record associated with the given label. This function checks
64 // that if we already have references for it, the type matches. If no record
65 // exists yet, a new one will be created.
67 // If any of the conditions fail, the return value will be null and the error
68 // will be set. request_from is used as the source of the error.
69 BuilderRecord
* GetOrCreateRecordOfType(const Label
& label
,
70 const ParseNode
* request_from
,
71 BuilderRecord::ItemType type
,
74 // Returns the record associated with the given label. This function checks
75 // that it's already been resolved to the correct type.
77 // If any of the conditions fail, the return value will be null and the error
78 // will be set. request_from is used as the source of the error.
79 BuilderRecord
* GetResolvedRecordOfType(const Label
& label
,
80 const ParseNode
* request_from
,
81 BuilderRecord::ItemType type
,
84 bool AddDeps(BuilderRecord
* record
,
85 const LabelConfigVector
& configs
,
87 bool AddDeps(BuilderRecord
* record
,
88 const UniqueVector
<LabelConfigPair
>& configs
,
90 bool AddDeps(BuilderRecord
* record
,
91 const LabelTargetVector
& targets
,
93 bool AddToolchainDep(BuilderRecord
* record
,
97 // Given a target, sets the "should generate" bit and pushes it through the
98 // dependency tree. Any time the bit it set, we ensure that the given item is
99 // scheduled to be loaded.
101 // If the force flag is set, we'll ignore the current state of the record's
102 // should_generate flag, and set it on the dependents every time. This is
103 // used when defining a target: the "should generate" may have been set
104 // before the item was defined (if it is required by something that is
105 // required). In this case, we need to re-push the "should generate" flag
106 // to the item's dependencies.
107 void RecursiveSetShouldGenerate(BuilderRecord
* record
, bool force
);
109 void ScheduleItemLoadIfNecessary(BuilderRecord
* record
);
111 // This takes a BuilderRecord with resolved depdencies, and fills in the
112 // target's Label*Vectors with the resolved pointers.
113 bool ResolveItem(BuilderRecord
* record
, Err
* err
);
115 // Fills in the pointers in the given vector based on the labels. We assume
116 // that everything should be resolved by this point, so will return an error
117 // if anything isn't found or if the type doesn't match.
118 bool ResolveDeps(LabelTargetVector
* deps
, Err
* err
);
119 bool ResolveConfigs(UniqueVector
<LabelConfigPair
>* configs
, Err
* err
);
120 bool ResolveForwardDependentConfigs(Target
* target
, Err
* err
);
121 bool ResolveToolchain(Target
* target
, Err
* err
);
123 // Given a list of unresolved records, tries to find any circular
124 // dependencies and returns the string describing the problem. If no circular
125 // deps were found, returns the empty string.
126 std::string
CheckForCircularDependencies(
127 const std::vector
<const BuilderRecord
*>& bad_records
) const;
129 // Non owning pointer.
133 typedef base::hash_map
<Label
, BuilderRecord
*> RecordMap
;
136 ResolvedCallback resolved_callback_
;
138 DISALLOW_COPY_AND_ASSIGN(Builder
);
141 #endif // TOOLS_GN_BUILDER_H_