Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(63)

Side by Side Diff: tools/gn/args.cc

Issue 984353002: Makes declared_arguments per toolchain (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: feedback Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/args.h ('k') | tools/gn/args_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 " default values. These default values will apply if none of the steps\n" 59 " default values. These default values will apply if none of the steps\n"
60 " listed in the \"How build arguments are set\" section above apply to\n" 60 " listed in the \"How build arguments are set\" section above apply to\n"
61 " the given argument, but the defaults will not override any of these.\n" 61 " the given argument, but the defaults will not override any of these.\n"
62 "\n" 62 "\n"
63 " Often, the root build config file will declare global arguments that\n" 63 " Often, the root build config file will declare global arguments that\n"
64 " will be passed to all buildfiles. Individual build files can also\n" 64 " will be passed to all buildfiles. Individual build files can also\n"
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 namespace {
70
71 // Removes all entries in |overrides| that are in |declared_overrides|.
72 void RemoveDeclaredOverrides(const Scope::KeyValueMap& declared_arguments,
73 Scope::KeyValueMap* overrides) {
74 for (Scope::KeyValueMap::iterator override = overrides->begin();
75 override != overrides->end();) {
76 if (declared_arguments.find(override->first) == declared_arguments.end())
77 ++override;
78 else
79 overrides->erase(override++);
80 }
81 }
82
83 } // namespace
84
69 Args::Args() { 85 Args::Args() {
70 } 86 }
71 87
72 Args::Args(const Args& other) 88 Args::Args(const Args& other)
73 : overrides_(other.overrides_), 89 : overrides_(other.overrides_),
74 all_overrides_(other.all_overrides_), 90 all_overrides_(other.all_overrides_),
75 declared_arguments_(other.declared_arguments_) { 91 declared_arguments_per_toolchain_(
92 other.declared_arguments_per_toolchain_) {
76 } 93 }
77 94
78 Args::~Args() { 95 Args::~Args() {
79 } 96 }
80 97
81 void Args::AddArgOverride(const char* name, const Value& value) { 98 void Args::AddArgOverride(const char* name, const Value& value) {
82 base::AutoLock lock(lock_); 99 base::AutoLock lock(lock_);
83 100
84 overrides_[base::StringPiece(name)] = value; 101 overrides_[base::StringPiece(name)] = value;
85 all_overrides_[base::StringPiece(name)] = value; 102 all_overrides_[base::StringPiece(name)] = value;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 ApplyOverridesLocked(overrides_, dest); 134 ApplyOverridesLocked(overrides_, dest);
118 ApplyOverridesLocked(toolchain_overrides, dest); 135 ApplyOverridesLocked(toolchain_overrides, dest);
119 SaveOverrideRecordLocked(toolchain_overrides); 136 SaveOverrideRecordLocked(toolchain_overrides);
120 } 137 }
121 138
122 bool Args::DeclareArgs(const Scope::KeyValueMap& args, 139 bool Args::DeclareArgs(const Scope::KeyValueMap& args,
123 Scope* scope_to_set, 140 Scope* scope_to_set,
124 Err* err) const { 141 Err* err) const {
125 base::AutoLock lock(lock_); 142 base::AutoLock lock(lock_);
126 143
144 Scope::KeyValueMap& declared_arguments(
145 DeclaredArgumentsForToolchainLocked(scope_to_set));
127 for (const auto& arg : args) { 146 for (const auto& arg : args) {
128 // Verify that the value hasn't already been declared. We want each value 147 // Verify that the value hasn't already been declared. We want each value
129 // to be declared only once. 148 // to be declared only once.
130 // 149 //
131 // The tricky part is that a buildfile can be interpreted multiple times 150 // 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 151 // 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. 152 // seen it before. Instead, we check that the location matches.
134 Scope::KeyValueMap::iterator previously_declared = 153 Scope::KeyValueMap::iterator previously_declared =
135 declared_arguments_.find(arg.first); 154 declared_arguments.find(arg.first);
136 if (previously_declared != declared_arguments_.end()) { 155 if (previously_declared != declared_arguments.end()) {
137 if (previously_declared->second.origin() != arg.second.origin()) { 156 if (previously_declared->second.origin() != arg.second.origin()) {
138 // Declaration location mismatch. 157 // Declaration location mismatch.
139 *err = Err(arg.second.origin(), 158 *err = Err(arg.second.origin(),
140 "Duplicate build argument declaration.", 159 "Duplicate build argument declaration.",
141 "Here you're declaring an argument that was already declared " 160 "Here you're declaring an argument that was already declared "
142 "elsewhere.\nYou can only declare each argument once in the entire " 161 "elsewhere.\nYou can only declare each argument once in the entire "
143 "build so there is one\ncanonical place for documentation and the " 162 "build so there is one\ncanonical place for documentation and the "
144 "default value. Either move this\nargument to the build config " 163 "default value. Either move this\nargument to the build config "
145 "file (for visibility everywhere) or to a .gni file\nthat you " 164 "file (for visibility everywhere) or to a .gni file\nthat you "
146 "\"import\" from the files where you need it (preferred)."); 165 "\"import\" from the files where you need it (preferred).");
147 err->AppendSubErr(Err(previously_declared->second.origin(), 166 err->AppendSubErr(Err(previously_declared->second.origin(),
148 "Previous declaration.", 167 "Previous declaration.",
149 "See also \"gn help buildargs\" for more on how " 168 "See also \"gn help buildargs\" for more on how "
150 "build arguments work.")); 169 "build arguments work."));
151 return false; 170 return false;
152 } 171 }
153 } else { 172 } else {
154 declared_arguments_.insert(arg); 173 declared_arguments.insert(arg);
155 } 174 }
156 175
157 // Only set on the current scope to the new value if it hasn't been already 176 // 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 177 // set. Mark the variable used so the build script can override it in
159 // certain cases without getting unused value errors. 178 // certain cases without getting unused value errors.
160 if (!scope_to_set->GetValue(arg.first)) { 179 if (!scope_to_set->GetValue(arg.first)) {
161 scope_to_set->SetValue(arg.first, arg.second, arg.second.origin()); 180 scope_to_set->SetValue(arg.first, arg.second, arg.second.origin());
162 scope_to_set->MarkUsed(arg.first); 181 scope_to_set->MarkUsed(arg.first);
163 } 182 }
164 } 183 }
165 184
166 return true; 185 return true;
167 } 186 }
168 187
169 bool Args::VerifyAllOverridesUsed(Err* err) const { 188 bool Args::VerifyAllOverridesUsed(Err* err) const {
170 base::AutoLock lock(lock_); 189 base::AutoLock lock(lock_);
171 return VerifyAllOverridesUsed(all_overrides_, declared_arguments_, err); 190 Scope::KeyValueMap all_overrides(all_overrides_);
172 } 191 for (const auto& map_pair : declared_arguments_per_toolchain_)
192 RemoveDeclaredOverrides(map_pair.second, &all_overrides);
173 193
174 bool Args::VerifyAllOverridesUsed( 194 if (all_overrides.empty())
175 const Scope::KeyValueMap& overrides, 195 return true;
176 const Scope::KeyValueMap& declared_arguments,
177 Err* err) {
178 for (const auto& override : overrides) {
179 if (declared_arguments.find(override.first) == declared_arguments.end()) {
180 // Get a list of all possible overrides for help with error finding.
181 //
182 // It might be nice to do edit distance checks to see if we can find one
183 // close to what you typed.
184 std::string all_declared_str;
185 for (Scope::KeyValueMap::const_iterator cur_str =
186 declared_arguments.begin();
187 cur_str != declared_arguments.end(); ++cur_str) {
188 if (cur_str != declared_arguments.begin())
189 all_declared_str += ", ";
190 all_declared_str += cur_str->first.as_string();
191 }
192 196
193 *err = Err(override.second.origin(), "Build argument has no effect.", 197 // Get a list of all possible overrides for help with error finding.
194 "The variable \"" + override.first.as_string() + 198 //
195 "\" was set as a build " 199 // It might be nice to do edit distance checks to see if we can find one close
196 "argument\nbut never appeared in a declare_args() block in any " 200 // to what you typed.
197 "buildfile.\n\nPossible arguments: " + all_declared_str); 201 std::string all_declared_str;
198 return false; 202 for (const auto& map_pair : declared_arguments_per_toolchain_) {
203 for (const auto& cur_str : map_pair.second) {
204 if (!all_declared_str.empty())
205 all_declared_str += ", ";
206 all_declared_str += cur_str.first.as_string();
199 } 207 }
200 } 208 }
201 return true; 209
210 *err = Err(
211 all_overrides.begin()->second.origin(), "Build argument has no effect.",
212 "The variable \"" + all_overrides.begin()->first.as_string() +
213 "\" was set as a build argument\nbut never appeared in a " +
sky 2015/03/16 16:20:45 git cl format did this. No idea why it indented he
214 "declare_args() block in any buildfile.\n\nPossible arguments: " +
215 all_declared_str);
216 return false;
202 } 217 }
203 218
204 void Args::MergeDeclaredArguments(Scope::KeyValueMap* dest) const { 219 void Args::MergeDeclaredArguments(Scope::KeyValueMap* dest) const {
205 base::AutoLock lock(lock_); 220 base::AutoLock lock(lock_);
206 for (const auto& arg : declared_arguments_) 221 for (const auto& map_pair : declared_arguments_per_toolchain_) {
207 (*dest)[arg.first] = arg.second; 222 for (const auto& arg : map_pair.second)
223 (*dest)[arg.first] = arg.second;
224 }
208 } 225 }
209 226
210 void Args::SetSystemVarsLocked(Scope* dest) const { 227 void Args::SetSystemVarsLocked(Scope* dest) const {
211 lock_.AssertAcquired(); 228 lock_.AssertAcquired();
212 229
213 // Host OS. 230 // Host OS.
214 const char* os = nullptr; 231 const char* os = nullptr;
215 #if defined(OS_WIN) 232 #if defined(OS_WIN)
216 os = "win"; 233 os = "win";
217 #elif defined(OS_MACOSX) 234 #elif defined(OS_MACOSX)
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 Value os_val(nullptr, std::string(os)); 267 Value os_val(nullptr, std::string(os));
251 dest->SetValue(variables::kHostOs, os_val, nullptr); 268 dest->SetValue(variables::kHostOs, os_val, nullptr);
252 dest->SetValue(variables::kTargetOs, empty_string, nullptr); 269 dest->SetValue(variables::kTargetOs, empty_string, nullptr);
253 dest->SetValue(variables::kCurrentOs, empty_string, nullptr); 270 dest->SetValue(variables::kCurrentOs, empty_string, nullptr);
254 271
255 Value arch_val(nullptr, std::string(arch)); 272 Value arch_val(nullptr, std::string(arch));
256 dest->SetValue(variables::kHostCpu, arch_val, nullptr); 273 dest->SetValue(variables::kHostCpu, arch_val, nullptr);
257 dest->SetValue(variables::kTargetCpu, empty_string, nullptr); 274 dest->SetValue(variables::kTargetCpu, empty_string, nullptr);
258 dest->SetValue(variables::kCurrentCpu, empty_string, nullptr); 275 dest->SetValue(variables::kCurrentCpu, empty_string, nullptr);
259 276
260 declared_arguments_[variables::kHostOs] = os_val; 277 Scope::KeyValueMap& declared_arguments(
261 declared_arguments_[variables::kCurrentOs] = empty_string; 278 DeclaredArgumentsForToolchainLocked(dest));
262 declared_arguments_[variables::kTargetOs] = empty_string; 279 declared_arguments[variables::kHostOs] = os_val;
263 declared_arguments_[variables::kHostCpu] = arch_val; 280 declared_arguments[variables::kCurrentOs] = empty_string;
264 declared_arguments_[variables::kCurrentCpu] = empty_string; 281 declared_arguments[variables::kTargetOs] = empty_string;
265 declared_arguments_[variables::kTargetCpu] = empty_string; 282 declared_arguments[variables::kHostCpu] = arch_val;
283 declared_arguments[variables::kCurrentCpu] = empty_string;
284 declared_arguments[variables::kTargetCpu] = empty_string;
266 285
267 // Mark these variables used so the build config file can override them 286 // Mark these variables used so the build config file can override them
268 // without geting a warning about overwriting an unused variable. 287 // without geting a warning about overwriting an unused variable.
269 dest->MarkUsed(variables::kHostCpu); 288 dest->MarkUsed(variables::kHostCpu);
270 dest->MarkUsed(variables::kCurrentCpu); 289 dest->MarkUsed(variables::kCurrentCpu);
271 dest->MarkUsed(variables::kTargetCpu); 290 dest->MarkUsed(variables::kTargetCpu);
272 dest->MarkUsed(variables::kHostOs); 291 dest->MarkUsed(variables::kHostOs);
273 dest->MarkUsed(variables::kCurrentOs); 292 dest->MarkUsed(variables::kCurrentOs);
274 dest->MarkUsed(variables::kTargetOs); 293 dest->MarkUsed(variables::kTargetOs);
275 } 294 }
276 295
277 void Args::ApplyOverridesLocked(const Scope::KeyValueMap& values, 296 void Args::ApplyOverridesLocked(const Scope::KeyValueMap& values,
278 Scope* scope) const { 297 Scope* scope) const {
279 lock_.AssertAcquired(); 298 lock_.AssertAcquired();
280 for (const auto& val : values) 299 for (const auto& val : values)
281 scope->SetValue(val.first, val.second, val.second.origin()); 300 scope->SetValue(val.first, val.second, val.second.origin());
282 } 301 }
283 302
284 void Args::SaveOverrideRecordLocked(const Scope::KeyValueMap& values) const { 303 void Args::SaveOverrideRecordLocked(const Scope::KeyValueMap& values) const {
285 lock_.AssertAcquired(); 304 lock_.AssertAcquired();
286 for (const auto& val : values) 305 for (const auto& val : values)
287 all_overrides_[val.first] = val.second; 306 all_overrides_[val.first] = val.second;
288 } 307 }
308
309 Scope::KeyValueMap& Args::DeclaredArgumentsForToolchainLocked(
310 Scope* scope) const {
311 lock_.AssertAcquired();
312 return declared_arguments_per_toolchain_[scope->settings()];
313 }
OLDNEW
« no previous file with comments | « tools/gn/args.h ('k') | tools/gn/args_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698