Chromium Code Reviews| 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 |