<webview>: Define API endpoints for webview.contextMenus API.
[chromium-blink-merge.git] / tools / gn / args.cc
blob2c4891ca82bb742b3cad77d52afdf2515a43204c
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 #include "tools/gn/args.h"
7 #include "build/build_config.h"
8 #include "tools/gn/variables.h"
10 #if defined(OS_WIN)
11 #include "base/win/windows_version.h"
12 #endif
14 const char kBuildArgs_Help[] =
15 "Build Arguments Overview\n"
16 "\n"
17 " Build arguments are variables passed in from outside of the build\n"
18 " that build files can query to determine how the build works.\n"
19 "\n"
20 "How build arguments are set\n"
21 "\n"
22 " First, system default arguments are set based on the current system.\n"
23 " The built-in arguments are:\n"
24 " - cpu_arch (by default this is the same as \"default_cpu_arch\")\n"
25 " - default_cpu_arch\n"
26 " - default_os\n"
27 " - os (by default this is the same as \"default_os\")\n"
28 "\n"
29 " Second, arguments specified on the command-line via \"--args\" are\n"
30 " applied. These can override the system default ones, and add new ones.\n"
31 " These are whitespace-separated. For example:\n"
32 "\n"
33 " gn --args=\"enable_doom_melon=false\" os=\\\"beos\\\"\n"
34 "\n"
35 " Third, toolchain overrides are applied. These are specified in the\n"
36 " toolchain_args section of a toolchain definition. The use-case for\n"
37 " this is that a toolchain may be building code for a different\n"
38 " platform, and that it may want to always specify Posix, for example.\n"
39 " See \"gn help toolchain_args\" for more.\n"
40 "\n"
41 " It is an error to specify an override for a build argument that never\n"
42 " appears in a \"declare_args\" call.\n"
43 "\n"
44 "How build arguments are used\n"
45 "\n"
46 " If you want to use an argument, you use declare_args() and specify\n"
47 " default values. These default values will apply if none of the steps\n"
48 " listed in the \"How build arguments are set\" section above apply to\n"
49 " the given argument, but the defaults will not override any of these.\n"
50 "\n"
51 " Often, the root build config file will declare global arguments that\n"
52 " will be passed to all buildfiles. Individual build files can also\n"
53 " specify arguments that apply only to those files. It is also useful\n"
54 " to specify build args in an \"import\"-ed file if you want such\n"
55 " arguments to apply to multiple buildfiles.\n";
57 Args::Args() {
60 Args::Args(const Args& other)
61 : overrides_(other.overrides_),
62 all_overrides_(other.all_overrides_),
63 declared_arguments_(other.declared_arguments_) {
66 Args::~Args() {
69 void Args::AddArgOverride(const char* name, const Value& value) {
70 base::AutoLock lock(lock_);
72 overrides_[base::StringPiece(name)] = value;
73 all_overrides_[base::StringPiece(name)] = value;
76 void Args::AddArgOverrides(const Scope::KeyValueMap& overrides) {
77 base::AutoLock lock(lock_);
79 for (Scope::KeyValueMap::const_iterator i = overrides.begin();
80 i != overrides.end(); ++i) {
81 overrides_[i->first] = i->second;
82 all_overrides_[i->first] = i->second;
86 const Value* Args::GetArgOverride(const char* name) const {
87 base::AutoLock lock(lock_);
89 Scope::KeyValueMap::const_iterator found =
90 all_overrides_.find(base::StringPiece(name));
91 if (found == all_overrides_.end())
92 return NULL;
93 return &found->second;
96 Scope::KeyValueMap Args::GetAllOverrides() const {
97 base::AutoLock lock(lock_);
98 return all_overrides_;
101 void Args::SetupRootScope(Scope* dest,
102 const Scope::KeyValueMap& toolchain_overrides) const {
103 base::AutoLock lock(lock_);
105 SetSystemVarsLocked(dest);
106 ApplyOverridesLocked(overrides_, dest);
107 ApplyOverridesLocked(toolchain_overrides, dest);
108 SaveOverrideRecordLocked(toolchain_overrides);
111 bool Args::DeclareArgs(const Scope::KeyValueMap& args,
112 Scope* scope_to_set,
113 Err* err) const {
114 base::AutoLock lock(lock_);
116 for (Scope::KeyValueMap::const_iterator i = args.begin();
117 i != args.end(); ++i) {
118 // Verify that the value hasn't already been declared. We want each value
119 // to be declared only once.
121 // The tricky part is that a buildfile can be interpreted multiple times
122 // when used from different toolchains, so we can't just check that we've
123 // seen it before. Instead, we check that the location matches.
124 Scope::KeyValueMap::iterator previously_declared =
125 declared_arguments_.find(i->first);
126 if (previously_declared != declared_arguments_.end()) {
127 if (previously_declared->second.origin() != i->second.origin()) {
128 // Declaration location mismatch.
129 *err = Err(i->second.origin(), "Duplicate build argument declaration.",
130 "Here you're declaring an argument that was already declared "
131 "elsewhere.\nYou can only declare each argument once in the entire "
132 "build so there is one\ncanonical place for documentation and the "
133 "default value. Either move this\nargument to the build config "
134 "file (for visibility everywhere) or to a .gni file\nthat you "
135 "\"import\" from the files where you need it (preferred).");
136 err->AppendSubErr(Err(previously_declared->second.origin(),
137 "Previous declaration.",
138 "See also \"gn help buildargs\" for more on how "
139 "build arguments work."));
140 return false;
142 } else {
143 declared_arguments_.insert(*i);
146 // Only set on the current scope to the new value if it hasn't been already
147 // set. Mark the variable used so the build script can override it in
148 // certain cases without getting unused value errors.
149 if (!scope_to_set->GetValue(i->first)) {
150 scope_to_set->SetValue(i->first, i->second, i->second.origin());
151 scope_to_set->MarkUsed(i->first);
155 return true;
158 bool Args::VerifyAllOverridesUsed(Err* err) const {
159 base::AutoLock lock(lock_);
160 return VerifyAllOverridesUsed(all_overrides_, declared_arguments_, err);
163 bool Args::VerifyAllOverridesUsed(
164 const Scope::KeyValueMap& overrides,
165 const Scope::KeyValueMap& declared_arguments,
166 Err* err) {
167 for (Scope::KeyValueMap::const_iterator i = overrides.begin();
168 i != overrides.end(); ++i) {
169 if (declared_arguments.find(i->first) == declared_arguments.end()) {
170 // Get a list of all possible overrides for help with error finding.
172 // It might be nice to do edit distance checks to see if we can find one
173 // close to what you typed.
174 std::string all_declared_str;
175 for (Scope::KeyValueMap::const_iterator cur_str =
176 declared_arguments.begin();
177 cur_str != declared_arguments.end(); ++cur_str) {
178 if (cur_str != declared_arguments.begin())
179 all_declared_str += ", ";
180 all_declared_str += cur_str->first.as_string();
183 *err = Err(i->second.origin(), "Build argument has no effect.",
184 "The variable \"" + i->first.as_string() + "\" was set as a build "
185 "argument\nbut never appeared in a declare_args() block in any "
186 "buildfile.\n\nPossible arguments: " + all_declared_str);
187 return false;
190 return true;
193 void Args::MergeDeclaredArguments(Scope::KeyValueMap* dest) const {
194 base::AutoLock lock(lock_);
196 for (Scope::KeyValueMap::const_iterator i = declared_arguments_.begin();
197 i != declared_arguments_.end(); ++i)
198 (*dest)[i->first] = i->second;
201 void Args::SetSystemVarsLocked(Scope* dest) const {
202 lock_.AssertAcquired();
204 // Host OS.
205 const char* os = NULL;
206 #if defined(OS_WIN)
207 os = "win";
208 #elif defined(OS_MACOSX)
209 os = "mac";
210 #elif defined(OS_LINUX)
211 os = "linux";
212 #else
213 #error Unknown OS type.
214 #endif
215 Value os_val(NULL, std::string(os));
216 dest->SetValue(variables::kBuildOs, os_val, NULL);
217 dest->SetValue(variables::kOs, os_val, NULL);
219 // Host architecture.
220 static const char kX86[] = "x86";
221 static const char kX64[] = "x64";
222 const char* arch = NULL;
223 #if defined(OS_WIN)
224 // ...on Windows, set the CPU architecture based on the underlying OS, not
225 // whatever the current bit-tedness of the GN binary is.
226 const base::win::OSInfo* os_info = base::win::OSInfo::GetInstance();
227 switch (os_info->architecture()) {
228 case base::win::OSInfo::X86_ARCHITECTURE:
229 arch = kX86;
230 break;
231 case base::win::OSInfo::X64_ARCHITECTURE:
232 arch = kX64;
233 break;
234 default:
235 CHECK(false) << "Windows architecture not handled.";
236 break;
238 #else
239 // ...on all other platforms, just use the bit-tedness of the current
240 // process.
241 #if defined(ARCH_CPU_X86_64)
242 arch = kX64;
243 #elif defined(ARCH_CPU_X86)
244 arch = kX86;
245 #elif defined(ARCH_CPU_ARMEL)
246 static const char kArm[] = "arm";
247 arch = kArm;
248 #else
249 #error Unknown architecture.
250 #endif
251 #endif
252 // Avoid unused var warning.
253 (void)kX86;
254 (void)kX64;
256 Value arch_val(NULL, std::string(arch));
257 dest->SetValue(variables::kBuildCpuArch, arch_val, NULL);
258 dest->SetValue(variables::kCpuArch, arch_val, NULL);
260 // Save the OS and architecture as build arguments that are implicitly
261 // declared. This is so they can be overridden in a toolchain build args
262 // override, and so that they will appear in the "gn args" output.
264 // Do not declare the build* variants since these shouldn't be changed.
266 // Mark these variables used so the build config file can override them
267 // without geting a warning about overwriting an unused variable.
268 declared_arguments_[variables::kOs] = os_val;
269 declared_arguments_[variables::kCpuArch] = arch_val;
270 dest->MarkUsed(variables::kCpuArch);
271 dest->MarkUsed(variables::kOs);
274 void Args::ApplyOverridesLocked(const Scope::KeyValueMap& values,
275 Scope* scope) const {
276 lock_.AssertAcquired();
277 for (Scope::KeyValueMap::const_iterator i = values.begin();
278 i != values.end(); ++i)
279 scope->SetValue(i->first, i->second, i->second.origin());
282 void Args::SaveOverrideRecordLocked(const Scope::KeyValueMap& values) const {
283 lock_.AssertAcquired();
284 for (Scope::KeyValueMap::const_iterator i = values.begin();
285 i != values.end(); ++i)
286 all_overrides_[i->first] = i->second;