| 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 |