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/args.h" | 5 #include "tools/gn/args.h" |
6 | 6 |
7 #include "base/sys_info.h" | 7 #include "base/sys_info.h" |
8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
9 #include "tools/gn/variables.h" | 9 #include "tools/gn/variables.h" |
10 | 10 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 " specify arguments that apply only to those files. It is also useful\n" | 65 " specify arguments that apply only to those files. It is also useful\n" |
66 " to specify build args in an \"import\"-ed file if you want such\n" | 66 " to specify build args in an \"import\"-ed file if you want such\n" |
67 " arguments to apply to multiple buildfiles.\n"; | 67 " arguments to apply to multiple buildfiles.\n"; |
68 | 68 |
69 Args::Args() { | 69 Args::Args() { |
70 } | 70 } |
71 | 71 |
72 Args::Args(const Args& other) | 72 Args::Args(const Args& other) |
73 : overrides_(other.overrides_), | 73 : overrides_(other.overrides_), |
74 all_overrides_(other.all_overrides_), | 74 all_overrides_(other.all_overrides_), |
75 declared_arguments_(other.declared_arguments_) { | 75 declared_arguments_per_toolchain_( |
76 other.declared_arguments_per_toolchain_) { | |
76 } | 77 } |
77 | 78 |
78 Args::~Args() { | 79 Args::~Args() { |
79 } | 80 } |
80 | 81 |
81 void Args::AddArgOverride(const char* name, const Value& value) { | 82 void Args::AddArgOverride(const char* name, const Value& value) { |
82 base::AutoLock lock(lock_); | 83 base::AutoLock lock(lock_); |
83 | 84 |
84 overrides_[base::StringPiece(name)] = value; | 85 overrides_[base::StringPiece(name)] = value; |
85 all_overrides_[base::StringPiece(name)] = value; | 86 all_overrides_[base::StringPiece(name)] = value; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
117 ApplyOverridesLocked(overrides_, dest); | 118 ApplyOverridesLocked(overrides_, dest); |
118 ApplyOverridesLocked(toolchain_overrides, dest); | 119 ApplyOverridesLocked(toolchain_overrides, dest); |
119 SaveOverrideRecordLocked(toolchain_overrides); | 120 SaveOverrideRecordLocked(toolchain_overrides); |
120 } | 121 } |
121 | 122 |
122 bool Args::DeclareArgs(const Scope::KeyValueMap& args, | 123 bool Args::DeclareArgs(const Scope::KeyValueMap& args, |
123 Scope* scope_to_set, | 124 Scope* scope_to_set, |
124 Err* err) const { | 125 Err* err) const { |
125 base::AutoLock lock(lock_); | 126 base::AutoLock lock(lock_); |
126 | 127 |
128 Scope::KeyValueMap& declared_arguments( | |
129 DeclaredArgumentsForToolchain(scope_to_set)); | |
127 for (const auto& arg : args) { | 130 for (const auto& arg : args) { |
128 // Verify that the value hasn't already been declared. We want each value | 131 // Verify that the value hasn't already been declared. We want each value |
129 // to be declared only once. | 132 // to be declared only once. |
130 // | 133 // |
131 // The tricky part is that a buildfile can be interpreted multiple times | 134 // The tricky part is that a buildfile can be interpreted multiple times |
132 // when used from different toolchains, so we can't just check that we've | 135 // when used from different toolchains, so we can't just check that we've |
133 // seen it before. Instead, we check that the location matches. | 136 // seen it before. Instead, we check that the location matches. |
134 Scope::KeyValueMap::iterator previously_declared = | 137 Scope::KeyValueMap::iterator previously_declared = |
135 declared_arguments_.find(arg.first); | 138 declared_arguments.find(arg.first); |
136 if (previously_declared != declared_arguments_.end()) { | 139 if (previously_declared != declared_arguments.end()) { |
137 if (previously_declared->second.origin() != arg.second.origin()) { | 140 if (previously_declared->second.origin() != arg.second.origin()) { |
138 // Declaration location mismatch. | 141 // Declaration location mismatch. |
139 *err = Err(arg.second.origin(), | 142 *err = Err(arg.second.origin(), |
140 "Duplicate build argument declaration.", | 143 "Duplicate build argument declaration.", |
141 "Here you're declaring an argument that was already declared " | 144 "Here you're declaring an argument that was already declared " |
142 "elsewhere.\nYou can only declare each argument once in the entire " | 145 "elsewhere.\nYou can only declare each argument once in the entire " |
143 "build so there is one\ncanonical place for documentation and the " | 146 "build so there is one\ncanonical place for documentation and the " |
144 "default value. Either move this\nargument to the build config " | 147 "default value. Either move this\nargument to the build config " |
145 "file (for visibility everywhere) or to a .gni file\nthat you " | 148 "file (for visibility everywhere) or to a .gni file\nthat you " |
146 "\"import\" from the files where you need it (preferred)."); | 149 "\"import\" from the files where you need it (preferred)."); |
147 err->AppendSubErr(Err(previously_declared->second.origin(), | 150 err->AppendSubErr(Err(previously_declared->second.origin(), |
148 "Previous declaration.", | 151 "Previous declaration.", |
149 "See also \"gn help buildargs\" for more on how " | 152 "See also \"gn help buildargs\" for more on how " |
150 "build arguments work.")); | 153 "build arguments work.")); |
151 return false; | 154 return false; |
152 } | 155 } |
153 } else { | 156 } else { |
154 declared_arguments_.insert(arg); | 157 declared_arguments.insert(arg); |
155 } | 158 } |
156 | 159 |
157 // Only set on the current scope to the new value if it hasn't been already | 160 // Only set on the current scope to the new value if it hasn't been already |
158 // set. Mark the variable used so the build script can override it in | 161 // set. Mark the variable used so the build script can override it in |
159 // certain cases without getting unused value errors. | 162 // certain cases without getting unused value errors. |
160 if (!scope_to_set->GetValue(arg.first)) { | 163 if (!scope_to_set->GetValue(arg.first)) { |
161 scope_to_set->SetValue(arg.first, arg.second, arg.second.origin()); | 164 scope_to_set->SetValue(arg.first, arg.second, arg.second.origin()); |
162 scope_to_set->MarkUsed(arg.first); | 165 scope_to_set->MarkUsed(arg.first); |
163 } | 166 } |
164 } | 167 } |
165 | 168 |
166 return true; | 169 return true; |
167 } | 170 } |
168 | 171 |
169 bool Args::VerifyAllOverridesUsed(Err* err) const { | 172 bool Args::VerifyAllOverridesUsed(Err* err) const { |
170 base::AutoLock lock(lock_); | 173 base::AutoLock lock(lock_); |
171 return VerifyAllOverridesUsed(all_overrides_, declared_arguments_, err); | 174 for (const auto& map_pair : declared_arguments_per_toolchain_) { |
175 if (!VerifyAllOverridesUsed(all_overrides_, map_pair.second, err)) | |
brettw
2015/03/14 05:14:32
I don't think this is quite right. We want to retu
sky
2015/03/16 16:20:45
Done.
| |
176 return false; | |
177 } | |
178 return true; | |
172 } | 179 } |
173 | 180 |
181 void Args::MergeDeclaredArguments(Scope::KeyValueMap* dest) const { | |
182 base::AutoLock lock(lock_); | |
183 for (const auto& map_pair : declared_arguments_per_toolchain_) { | |
184 for (const auto& arg : map_pair.second) | |
185 (*dest)[arg.first] = arg.second; | |
186 } | |
187 } | |
188 | |
189 // static | |
174 bool Args::VerifyAllOverridesUsed( | 190 bool Args::VerifyAllOverridesUsed( |
175 const Scope::KeyValueMap& overrides, | 191 const Scope::KeyValueMap& overrides, |
176 const Scope::KeyValueMap& declared_arguments, | 192 const Scope::KeyValueMap& declared_arguments, |
177 Err* err) { | 193 Err* err) { |
178 for (const auto& override : overrides) { | 194 for (const auto& override : overrides) { |
179 if (declared_arguments.find(override.first) == declared_arguments.end()) { | 195 if (declared_arguments.find(override.first) == declared_arguments.end()) { |
180 // Get a list of all possible overrides for help with error finding. | 196 // Get a list of all possible overrides for help with error finding. |
181 // | 197 // |
182 // It might be nice to do edit distance checks to see if we can find one | 198 // It might be nice to do edit distance checks to see if we can find one |
183 // close to what you typed. | 199 // close to what you typed. |
(...skipping 10 matching lines...) Expand all Loading... | |
194 "The variable \"" + override.first.as_string() + | 210 "The variable \"" + override.first.as_string() + |
195 "\" was set as a build " | 211 "\" was set as a build " |
196 "argument\nbut never appeared in a declare_args() block in any " | 212 "argument\nbut never appeared in a declare_args() block in any " |
197 "buildfile.\n\nPossible arguments: " + all_declared_str); | 213 "buildfile.\n\nPossible arguments: " + all_declared_str); |
198 return false; | 214 return false; |
199 } | 215 } |
200 } | 216 } |
201 return true; | 217 return true; |
202 } | 218 } |
203 | 219 |
204 void Args::MergeDeclaredArguments(Scope::KeyValueMap* dest) const { | |
205 base::AutoLock lock(lock_); | |
206 for (const auto& arg : declared_arguments_) | |
207 (*dest)[arg.first] = arg.second; | |
208 } | |
209 | |
210 void Args::SetSystemVarsLocked(Scope* dest) const { | 220 void Args::SetSystemVarsLocked(Scope* dest) const { |
211 lock_.AssertAcquired(); | 221 lock_.AssertAcquired(); |
212 | 222 |
213 // Host OS. | 223 // Host OS. |
214 const char* os = nullptr; | 224 const char* os = nullptr; |
215 #if defined(OS_WIN) | 225 #if defined(OS_WIN) |
216 os = "win"; | 226 os = "win"; |
217 #elif defined(OS_MACOSX) | 227 #elif defined(OS_MACOSX) |
218 os = "mac"; | 228 os = "mac"; |
219 #elif defined(OS_LINUX) | 229 #elif defined(OS_LINUX) |
(...skipping 30 matching lines...) Expand all Loading... | |
250 Value os_val(nullptr, std::string(os)); | 260 Value os_val(nullptr, std::string(os)); |
251 dest->SetValue(variables::kHostOs, os_val, nullptr); | 261 dest->SetValue(variables::kHostOs, os_val, nullptr); |
252 dest->SetValue(variables::kTargetOs, empty_string, nullptr); | 262 dest->SetValue(variables::kTargetOs, empty_string, nullptr); |
253 dest->SetValue(variables::kCurrentOs, empty_string, nullptr); | 263 dest->SetValue(variables::kCurrentOs, empty_string, nullptr); |
254 | 264 |
255 Value arch_val(nullptr, std::string(arch)); | 265 Value arch_val(nullptr, std::string(arch)); |
256 dest->SetValue(variables::kHostCpu, arch_val, nullptr); | 266 dest->SetValue(variables::kHostCpu, arch_val, nullptr); |
257 dest->SetValue(variables::kTargetCpu, empty_string, nullptr); | 267 dest->SetValue(variables::kTargetCpu, empty_string, nullptr); |
258 dest->SetValue(variables::kCurrentCpu, empty_string, nullptr); | 268 dest->SetValue(variables::kCurrentCpu, empty_string, nullptr); |
259 | 269 |
260 declared_arguments_[variables::kHostOs] = os_val; | 270 Scope::KeyValueMap& declared_arguments(DeclaredArgumentsForToolchain(dest)); |
261 declared_arguments_[variables::kCurrentOs] = empty_string; | 271 declared_arguments[variables::kHostOs] = os_val; |
262 declared_arguments_[variables::kTargetOs] = empty_string; | 272 declared_arguments[variables::kCurrentOs] = empty_string; |
263 declared_arguments_[variables::kHostCpu] = arch_val; | 273 declared_arguments[variables::kTargetOs] = empty_string; |
264 declared_arguments_[variables::kCurrentCpu] = empty_string; | 274 declared_arguments[variables::kHostCpu] = arch_val; |
265 declared_arguments_[variables::kTargetCpu] = empty_string; | 275 declared_arguments[variables::kCurrentCpu] = empty_string; |
276 declared_arguments[variables::kTargetCpu] = empty_string; | |
266 | 277 |
267 // Mark these variables used so the build config file can override them | 278 // Mark these variables used so the build config file can override them |
268 // without geting a warning about overwriting an unused variable. | 279 // without geting a warning about overwriting an unused variable. |
269 dest->MarkUsed(variables::kHostCpu); | 280 dest->MarkUsed(variables::kHostCpu); |
270 dest->MarkUsed(variables::kCurrentCpu); | 281 dest->MarkUsed(variables::kCurrentCpu); |
271 dest->MarkUsed(variables::kTargetCpu); | 282 dest->MarkUsed(variables::kTargetCpu); |
272 dest->MarkUsed(variables::kHostOs); | 283 dest->MarkUsed(variables::kHostOs); |
273 dest->MarkUsed(variables::kCurrentOs); | 284 dest->MarkUsed(variables::kCurrentOs); |
274 dest->MarkUsed(variables::kTargetOs); | 285 dest->MarkUsed(variables::kTargetOs); |
275 } | 286 } |
276 | 287 |
277 void Args::ApplyOverridesLocked(const Scope::KeyValueMap& values, | 288 void Args::ApplyOverridesLocked(const Scope::KeyValueMap& values, |
278 Scope* scope) const { | 289 Scope* scope) const { |
279 lock_.AssertAcquired(); | 290 lock_.AssertAcquired(); |
280 for (const auto& val : values) | 291 for (const auto& val : values) |
281 scope->SetValue(val.first, val.second, val.second.origin()); | 292 scope->SetValue(val.first, val.second, val.second.origin()); |
282 } | 293 } |
283 | 294 |
284 void Args::SaveOverrideRecordLocked(const Scope::KeyValueMap& values) const { | 295 void Args::SaveOverrideRecordLocked(const Scope::KeyValueMap& values) const { |
285 lock_.AssertAcquired(); | 296 lock_.AssertAcquired(); |
286 for (const auto& val : values) | 297 for (const auto& val : values) |
287 all_overrides_[val.first] = val.second; | 298 all_overrides_[val.first] = val.second; |
288 } | 299 } |
300 | |
301 Scope::KeyValueMap& Args::DeclaredArgumentsForToolchain(Scope* scope) const { | |
302 lock_.AssertAcquired(); | |
303 return declared_arguments_per_toolchain_[scope->settings()]; | |
304 } | |
OLD | NEW |