OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "tools/gn/target.h" | 5 #include "tools/gn/target.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "tools/gn/config_values_extractors.h" | 8 #include "tools/gn/config_values_extractors.h" |
9 #include "tools/gn/scheduler.h" | 9 #include "tools/gn/scheduler.h" |
10 | 10 |
11 namespace { | 11 namespace { |
12 | 12 |
13 typedef std::set<const Config*> ConfigSet; | 13 typedef std::set<const Config*> ConfigSet; |
14 | 14 |
15 // Merges the dependent configs from the given target to the given config list. | 15 // Merges the dependent configs from the given target to the given config list. |
16 // The unique_configs list is used for de-duping so values already added will | |
17 // not be added again. | |
18 void MergeDirectDependentConfigsFrom(const Target* from_target, | 16 void MergeDirectDependentConfigsFrom(const Target* from_target, |
19 ConfigSet* unique_configs, | 17 UniqueVector<LabelConfigPair>* dest) { |
20 LabelConfigVector* dest) { | 18 const UniqueVector<LabelConfigPair>& direct = |
21 const LabelConfigVector& direct = from_target->direct_dependent_configs(); | 19 from_target->direct_dependent_configs(); |
22 for (size_t i = 0; i < direct.size(); i++) { | 20 for (size_t i = 0; i < direct.size(); i++) |
23 if (unique_configs->find(direct[i].ptr) == unique_configs->end()) { | 21 dest->push_back(direct[i]); |
24 unique_configs->insert(direct[i].ptr); | |
25 dest->push_back(direct[i]); | |
26 } | |
27 } | |
28 } | 22 } |
29 | 23 |
30 // Like MergeDirectDependentConfigsFrom above except does the "all dependent" | 24 // Like MergeDirectDependentConfigsFrom above except does the "all dependent" |
31 // ones. This additionally adds all configs to the all_dependent_configs_ of | 25 // ones. This additionally adds all configs to the all_dependent_configs_ of |
32 // the dest target given in *all_dest. | 26 // the dest target given in *all_dest. |
33 void MergeAllDependentConfigsFrom(const Target* from_target, | 27 void MergeAllDependentConfigsFrom(const Target* from_target, |
34 ConfigSet* unique_configs, | 28 UniqueVector<LabelConfigPair>* dest, |
35 LabelConfigVector* dest, | 29 UniqueVector<LabelConfigPair>* all_dest) { |
36 LabelConfigVector* all_dest) { | 30 const UniqueVector<LabelConfigPair>& all = |
37 const LabelConfigVector& all = from_target->all_dependent_configs(); | 31 from_target->all_dependent_configs(); |
38 for (size_t i = 0; i < all.size(); i++) { | 32 for (size_t i = 0; i < all.size(); i++) { |
39 // Always add it to all_dependent_configs_ since it might not be in that | |
40 // list even if we've seen it applied to this target before. This may | |
41 // introduce some duplicates in all_dependent_configs_, but those will | |
42 // we removed when they're actually applied to a target. | |
43 all_dest->push_back(all[i]); | 33 all_dest->push_back(all[i]); |
44 if (unique_configs->find(all[i].ptr) == unique_configs->end()) { | 34 dest->push_back(all[i]); |
45 // One we haven't seen yet, also apply it to ourselves. | |
46 dest->push_back(all[i]); | |
47 unique_configs->insert(all[i].ptr); | |
48 } | |
49 } | 35 } |
50 } | 36 } |
51 | 37 |
52 } // namespace | 38 } // namespace |
53 | 39 |
54 Target::Target(const Settings* settings, const Label& label) | 40 Target::Target(const Settings* settings, const Label& label) |
55 : Item(settings, label), | 41 : Item(settings, label), |
56 output_type_(UNKNOWN), | 42 output_type_(UNKNOWN), |
57 all_headers_public_(true), | 43 all_headers_public_(true), |
58 hard_dep_(false) { | 44 hard_dep_(false) { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 // the ordering is preserved. We need to keep the original group so that any | 89 // the ordering is preserved. We need to keep the original group so that any |
104 // flags, etc. that it specifies itself are applied to us. | 90 // flags, etc. that it specifies itself are applied to us. |
105 for (size_t i = 0; i < deps_.size(); i++) { | 91 for (size_t i = 0; i < deps_.size(); i++) { |
106 const Target* dep = deps_[i].ptr; | 92 const Target* dep = deps_[i].ptr; |
107 if (dep->output_type_ == GROUP) { | 93 if (dep->output_type_ == GROUP) { |
108 deps_.insert(deps_.begin() + i + 1, dep->deps_.begin(), dep->deps_.end()); | 94 deps_.insert(deps_.begin() + i + 1, dep->deps_.begin(), dep->deps_.end()); |
109 i += dep->deps_.size(); | 95 i += dep->deps_.size(); |
110 } | 96 } |
111 } | 97 } |
112 | 98 |
113 // Only add each config once. First remember the target's configs. | |
114 ConfigSet unique_configs; | |
115 for (size_t i = 0; i < configs_.size(); i++) | |
116 unique_configs.insert(configs_[i].ptr); | |
117 | |
118 // Copy our own dependent configs to the list of configs applying to us. | 99 // Copy our own dependent configs to the list of configs applying to us. |
119 for (size_t i = 0; i < all_dependent_configs_.size(); i++) { | 100 configs_.Append(all_dependent_configs_.begin(), all_dependent_configs_.end()); |
120 if (unique_configs.find(all_dependent_configs_[i].ptr) == | 101 configs_.Append(direct_dependent_configs_.begin(), |
121 unique_configs.end()) { | 102 direct_dependent_configs_.end()); |
122 unique_configs.insert(all_dependent_configs_[i].ptr); | |
123 configs_.push_back(all_dependent_configs_[i]); | |
124 } | |
125 } | |
126 for (size_t i = 0; i < direct_dependent_configs_.size(); i++) { | |
127 if (unique_configs.find(direct_dependent_configs_[i].ptr) == | |
128 unique_configs.end()) { | |
129 unique_configs.insert(direct_dependent_configs_[i].ptr); | |
130 configs_.push_back(direct_dependent_configs_[i]); | |
131 } | |
132 } | |
133 | 103 |
134 // Copy our own libs and lib_dirs to the final set. This will be from our | 104 // Copy our own libs and lib_dirs to the final set. This will be from our |
135 // target and all of our configs. We do this specially since these must be | 105 // target and all of our configs. We do this specially since these must be |
136 // inherited through the dependency tree (other flags don't work this way). | 106 // inherited through the dependency tree (other flags don't work this way). |
137 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) { | 107 for (ConfigValuesIterator iter(this); !iter.done(); iter.Next()) { |
138 const ConfigValues& cur = iter.cur(); | 108 const ConfigValues& cur = iter.cur(); |
139 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end()); | 109 all_lib_dirs_.append(cur.lib_dirs().begin(), cur.lib_dirs().end()); |
140 all_libs_.append(cur.libs().begin(), cur.libs().end()); | 110 all_libs_.append(cur.libs().begin(), cur.libs().end()); |
141 } | 111 } |
142 | 112 |
143 if (output_type_ != GROUP) { | 113 if (output_type_ != GROUP) { |
144 // Don't pull target info like libraries and configs from dependencies into | 114 // Don't pull target info like libraries and configs from dependencies into |
145 // a group target. When A depends on a group G, the G's dependents will | 115 // a group target. When A depends on a group G, the G's dependents will |
146 // be treated as direct dependencies of A, so this is unnecessary and will | 116 // be treated as direct dependencies of A, so this is unnecessary and will |
147 // actually result in duplicated settings (since settings will also be | 117 // actually result in duplicated settings (since settings will also be |
148 // pulled from G to A in case G has configs directly on it). | 118 // pulled from G to A in case G has configs directly on it). |
149 PullDependentTargetInfo(&unique_configs); | 119 PullDependentTargetInfo(); |
150 } | 120 } |
151 PullForwardedDependentConfigs(); | 121 PullForwardedDependentConfigs(); |
152 PullRecursiveHardDeps(); | 122 PullRecursiveHardDeps(); |
153 } | 123 } |
154 | 124 |
155 bool Target::IsLinkable() const { | 125 bool Target::IsLinkable() const { |
156 return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY; | 126 return output_type_ == STATIC_LIBRARY || output_type_ == SHARED_LIBRARY; |
157 } | 127 } |
158 | 128 |
159 void Target::PullDependentTargetInfo(std::set<const Config*>* unique_configs) { | 129 void Target::PullDependentTargetInfo() { |
160 // Gather info from our dependents we need. | 130 // Gather info from our dependents we need. |
161 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) { | 131 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) { |
162 const Target* dep = deps_[dep_i].ptr; | 132 const Target* dep = deps_[dep_i].ptr; |
163 MergeAllDependentConfigsFrom(dep, unique_configs, &configs_, | 133 MergeAllDependentConfigsFrom(dep, &configs_, &all_dependent_configs_); |
164 &all_dependent_configs_); | 134 MergeDirectDependentConfigsFrom(dep, &configs_); |
165 MergeDirectDependentConfigsFrom(dep, unique_configs, &configs_); | |
166 | 135 |
167 // Direct dependent libraries. | 136 // Direct dependent libraries. |
168 if (dep->output_type() == STATIC_LIBRARY || | 137 if (dep->output_type() == STATIC_LIBRARY || |
169 dep->output_type() == SHARED_LIBRARY || | 138 dep->output_type() == SHARED_LIBRARY || |
170 dep->output_type() == SOURCE_SET) | 139 dep->output_type() == SOURCE_SET) |
171 inherited_libraries_.insert(dep); | 140 inherited_libraries_.push_back(dep); |
172 | 141 |
173 // Inherited libraries and flags are inherited across static library | 142 // Inherited libraries and flags are inherited across static library |
174 // boundaries. | 143 // boundaries. |
175 if (dep->output_type() != SHARED_LIBRARY && | 144 if (dep->output_type() != SHARED_LIBRARY && |
176 dep->output_type() != EXECUTABLE) { | 145 dep->output_type() != EXECUTABLE) { |
177 const std::set<const Target*> inherited = dep->inherited_libraries(); | 146 inherited_libraries_.Append(dep->inherited_libraries().begin(), |
178 for (std::set<const Target*>::const_iterator i = inherited.begin(); | 147 dep->inherited_libraries().end()); |
179 i != inherited.end(); ++i) | |
180 inherited_libraries_.insert(*i); | |
181 | 148 |
182 // Inherited library settings. | 149 // Inherited library settings. |
183 all_lib_dirs_.append(dep->all_lib_dirs()); | 150 all_lib_dirs_.append(dep->all_lib_dirs()); |
184 all_libs_.append(dep->all_libs()); | 151 all_libs_.append(dep->all_libs()); |
185 } | 152 } |
186 } | 153 } |
187 } | 154 } |
188 | 155 |
189 void Target::PullForwardedDependentConfigs() { | 156 void Target::PullForwardedDependentConfigs() { |
190 // Groups implicitly forward all if its dependency's configs. | 157 // Groups implicitly forward all if its dependency's configs. |
191 if (output_type() == GROUP) | 158 if (output_type() == GROUP) { |
192 forward_dependent_configs_ = deps_; | 159 for (size_t i = 0; i < deps_.size(); i++) |
| 160 forward_dependent_configs_.push_back(deps_[i]); |
| 161 } |
193 | 162 |
194 // Forward direct dependent configs if requested. | 163 // Forward direct dependent configs if requested. |
195 for (size_t dep = 0; dep < forward_dependent_configs_.size(); dep++) { | 164 for (size_t dep = 0; dep < forward_dependent_configs_.size(); dep++) { |
196 const Target* from_target = forward_dependent_configs_[dep].ptr; | 165 const Target* from_target = forward_dependent_configs_[dep].ptr; |
197 | 166 |
198 // The forward_dependent_configs_ must be in the deps already, so we | 167 // The forward_dependent_configs_ must be in the deps already, so we |
199 // don't need to bother copying to our configs, only forwarding. | 168 // don't need to bother copying to our configs, only forwarding. |
200 DCHECK(std::find_if(deps_.begin(), deps_.end(), | 169 DCHECK(std::find_if(deps_.begin(), deps_.end(), |
201 LabelPtrPtrEquals<Target>(from_target)) != | 170 LabelPtrPtrEquals<Target>(from_target)) != |
202 deps_.end()); | 171 deps_.end()); |
203 direct_dependent_configs_.insert( | 172 direct_dependent_configs_.Append( |
204 direct_dependent_configs_.end(), | |
205 from_target->direct_dependent_configs().begin(), | 173 from_target->direct_dependent_configs().begin(), |
206 from_target->direct_dependent_configs().end()); | 174 from_target->direct_dependent_configs().end()); |
207 } | 175 } |
208 } | 176 } |
209 | 177 |
210 void Target::PullRecursiveHardDeps() { | 178 void Target::PullRecursiveHardDeps() { |
211 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) { | 179 for (size_t dep_i = 0; dep_i < deps_.size(); dep_i++) { |
212 const Target* dep = deps_[dep_i].ptr; | 180 const Target* dep = deps_[dep_i].ptr; |
213 if (dep->hard_dep()) | 181 if (dep->hard_dep()) |
214 recursive_hard_deps_.insert(dep); | 182 recursive_hard_deps_.insert(dep); |
215 | 183 |
216 // Android STL doesn't like insert(begin, end) so do it manually. | 184 // Android STL doesn't like insert(begin, end) so do it manually. |
217 // TODO(brettw) this can be changed to insert(dep->begin(), dep->end()) when | 185 // TODO(brettw) this can be changed to insert(dep->begin(), dep->end()) when |
218 // Android uses a better STL. | 186 // Android uses a better STL. |
219 for (std::set<const Target*>::const_iterator cur = | 187 for (std::set<const Target*>::const_iterator cur = |
220 dep->recursive_hard_deps().begin(); | 188 dep->recursive_hard_deps().begin(); |
221 cur != dep->recursive_hard_deps().end(); ++cur) | 189 cur != dep->recursive_hard_deps().end(); ++cur) |
222 recursive_hard_deps_.insert(*cur); | 190 recursive_hard_deps_.insert(*cur); |
223 } | 191 } |
224 } | 192 } |
OLD | NEW |