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_generator.h" | 5 #include "tools/gn/target_generator.h" |
6 | 6 |
7 #include "tools/gn/action_target_generator.h" | 7 #include "tools/gn/action_target_generator.h" |
8 #include "tools/gn/binary_target_generator.h" | 8 #include "tools/gn/binary_target_generator.h" |
9 #include "tools/gn/build_settings.h" | 9 #include "tools/gn/build_settings.h" |
10 #include "tools/gn/config.h" | 10 #include "tools/gn/config.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 scope_(scope), | 29 scope_(scope), |
30 function_call_(function_call), | 30 function_call_(function_call), |
31 err_(err) { | 31 err_(err) { |
32 } | 32 } |
33 | 33 |
34 TargetGenerator::~TargetGenerator() { | 34 TargetGenerator::~TargetGenerator() { |
35 } | 35 } |
36 | 36 |
37 void TargetGenerator::Run() { | 37 void TargetGenerator::Run() { |
38 // All target types use these. | 38 // All target types use these. |
39 FillDependentConfigs(); | 39 if (!FillDependentConfigs()) |
40 if (err_->has_error()) | |
41 return; | 40 return; |
42 | 41 |
43 FillData(); | 42 if (!FillData()) |
44 if (err_->has_error()) | |
45 return; | 43 return; |
46 | 44 |
47 FillDependencies(); | 45 if (!FillDependencies()) |
48 if (err_->has_error()) | |
49 return; | 46 return; |
50 | 47 |
51 FillTestonly(); | 48 if (!FillTestonly()) |
52 if (err_->has_error()) | |
53 return; | 49 return; |
54 | 50 |
55 if (!Visibility::FillItemVisibility(target_, scope_, err_)) | 51 if (!Visibility::FillItemVisibility(target_, scope_, err_)) |
56 return; | 52 return; |
57 | 53 |
58 // Do type-specific generation. | 54 // Do type-specific generation. |
59 DoRun(); | 55 DoRun(); |
60 } | 56 } |
61 | 57 |
62 // static | 58 // static |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 *err = Err(function_call, "Can't define a target in this context."); | 126 *err = Err(function_call, "Can't define a target in this context."); |
131 return; | 127 return; |
132 } | 128 } |
133 collector->push_back(new scoped_ptr<Item>(target.PassAs<Item>())); | 129 collector->push_back(new scoped_ptr<Item>(target.PassAs<Item>())); |
134 } | 130 } |
135 | 131 |
136 const BuildSettings* TargetGenerator::GetBuildSettings() const { | 132 const BuildSettings* TargetGenerator::GetBuildSettings() const { |
137 return scope_->settings()->build_settings(); | 133 return scope_->settings()->build_settings(); |
138 } | 134 } |
139 | 135 |
140 void TargetGenerator::FillSources() { | 136 bool TargetGenerator::FillSources() { |
141 const Value* value = scope_->GetValue(variables::kSources, true); | 137 const Value* value = scope_->GetValue(variables::kSources, true); |
142 if (!value) | 138 if (!value) |
143 return; | 139 return true; |
144 | 140 |
145 Target::FileList dest_sources; | 141 Target::FileList dest_sources; |
146 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, | 142 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, |
147 scope_->GetSourceDir(), &dest_sources, err_)) | 143 scope_->GetSourceDir(), &dest_sources, err_)) |
148 return; | 144 return false; |
149 target_->sources().swap(dest_sources); | 145 target_->sources().swap(dest_sources); |
| 146 return true; |
150 } | 147 } |
151 | 148 |
152 void TargetGenerator::FillPublic() { | 149 bool TargetGenerator::FillPublic() { |
153 const Value* value = scope_->GetValue(variables::kPublic, true); | 150 const Value* value = scope_->GetValue(variables::kPublic, true); |
154 if (!value) | 151 if (!value) |
155 return; | 152 return true; |
156 | 153 |
157 // If the public headers are defined, don't default to public. | 154 // If the public headers are defined, don't default to public. |
158 target_->set_all_headers_public(false); | 155 target_->set_all_headers_public(false); |
159 | 156 |
160 Target::FileList dest_public; | 157 Target::FileList dest_public; |
161 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, | 158 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, |
162 scope_->GetSourceDir(), &dest_public, err_)) | 159 scope_->GetSourceDir(), &dest_public, err_)) |
163 return; | 160 return false; |
164 target_->public_headers().swap(dest_public); | 161 target_->public_headers().swap(dest_public); |
| 162 return true; |
165 } | 163 } |
166 | 164 |
167 void TargetGenerator::FillInputs() { | 165 bool TargetGenerator::FillInputs() { |
168 const Value* value = scope_->GetValue(variables::kInputs, true); | 166 const Value* value = scope_->GetValue(variables::kInputs, true); |
169 if (!value) { | 167 if (!value) { |
170 // Older versions used "source_prereqs". Allow use of this variable until | 168 // Older versions used "source_prereqs". Allow use of this variable until |
171 // all callers are updated. | 169 // all callers are updated. |
172 // TODO(brettw) remove this eventually. | 170 // TODO(brettw) remove this eventually. |
173 value = scope_->GetValue("source_prereqs", true); | 171 value = scope_->GetValue("source_prereqs", true); |
174 | |
175 if (!value) | 172 if (!value) |
176 return; | 173 return true; |
177 } | 174 } |
178 | 175 |
179 Target::FileList dest_inputs; | 176 Target::FileList dest_inputs; |
180 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, | 177 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, |
181 scope_->GetSourceDir(), &dest_inputs, err_)) | 178 scope_->GetSourceDir(), &dest_inputs, err_)) |
182 return; | 179 return false; |
183 target_->inputs().swap(dest_inputs); | 180 target_->inputs().swap(dest_inputs); |
| 181 return true; |
184 } | 182 } |
185 | 183 |
186 void TargetGenerator::FillConfigs() { | 184 bool TargetGenerator::FillConfigs() { |
187 FillGenericConfigs(variables::kConfigs, &target_->configs()); | 185 return FillGenericConfigs(variables::kConfigs, &target_->configs()); |
188 } | 186 } |
189 | 187 |
190 void TargetGenerator::FillDependentConfigs() { | 188 bool TargetGenerator::FillDependentConfigs() { |
191 FillGenericConfigs(variables::kAllDependentConfigs, | 189 if (!FillGenericConfigs(variables::kAllDependentConfigs, |
192 &target_->all_dependent_configs()); | 190 &target_->all_dependent_configs())) |
193 FillGenericConfigs(variables::kDirectDependentConfigs, | 191 return false; |
194 &target_->direct_dependent_configs()); | 192 if (!FillGenericConfigs(variables::kPublicConfigs, |
| 193 &target_->public_configs())) |
| 194 return false; |
| 195 |
| 196 // "public_configs" was previously named "direct_dependent_configs", fall |
| 197 // back to that if public_configs was undefined. |
| 198 if (!scope_->GetValue(variables::kPublicConfigs, false)) { |
| 199 if (!FillGenericConfigs("direct_dependent_configs", |
| 200 &target_->public_configs())) |
| 201 return false; |
| 202 } |
| 203 return true; |
195 } | 204 } |
196 | 205 |
197 void TargetGenerator::FillData() { | 206 bool TargetGenerator::FillData() { |
198 const Value* value = scope_->GetValue(variables::kData, true); | 207 const Value* value = scope_->GetValue(variables::kData, true); |
199 if (!value) | 208 if (!value) |
200 return; | 209 return true; |
201 | 210 |
202 Target::FileList dest_data; | 211 Target::FileList dest_data; |
203 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, | 212 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, |
204 scope_->GetSourceDir(), &dest_data, err_)) | 213 scope_->GetSourceDir(), &dest_data, err_)) |
205 return; | 214 return false; |
206 target_->data().swap(dest_data); | 215 target_->data().swap(dest_data); |
| 216 return true; |
207 } | 217 } |
208 | 218 |
209 void TargetGenerator::FillDependencies() { | 219 bool TargetGenerator::FillDependencies() { |
210 FillGenericDeps(variables::kDeps, &target_->deps()); | 220 if (!FillGenericDeps(variables::kDeps, &target_->private_deps())) |
211 if (err_->has_error()) | 221 return false; |
212 return; | 222 if (!FillGenericDeps(variables::kPublicDeps, &target_->public_deps())) |
213 FillGenericDeps(variables::kDatadeps, &target_->datadeps()); | 223 return false; |
214 if (err_->has_error()) | 224 if (!FillGenericDeps(variables::kDataDeps, &target_->data_deps())) |
215 return; | 225 return false; |
| 226 |
| 227 // "data_deps" was previously named "datadeps". For backwards-compat, read |
| 228 // the old one if no "data_deps" were specified. |
| 229 if (!scope_->GetValue(variables::kDataDeps, false)) { |
| 230 if (!FillGenericDeps("datadeps", &target_->data_deps())) |
| 231 return false; |
| 232 } |
216 | 233 |
217 // This is a list of dependent targets to have their configs fowarded, so | 234 // This is a list of dependent targets to have their configs fowarded, so |
218 // it goes here rather than in FillConfigs. | 235 // it goes here rather than in FillConfigs. |
219 FillForwardDependentConfigs(); | 236 if (!FillForwardDependentConfigs()) |
220 if (err_->has_error()) | 237 return false; |
221 return; | 238 return true; |
222 } | 239 } |
223 | 240 |
224 void TargetGenerator::FillTestonly() { | 241 bool TargetGenerator::FillTestonly() { |
225 const Value* value = scope_->GetValue(variables::kTestonly, true); | 242 const Value* value = scope_->GetValue(variables::kTestonly, true); |
226 if (value) { | 243 if (value) { |
227 if (!value->VerifyTypeIs(Value::BOOLEAN, err_)) | 244 if (!value->VerifyTypeIs(Value::BOOLEAN, err_)) |
228 return; | 245 return false; |
229 target_->set_testonly(value->boolean_value()); | 246 target_->set_testonly(value->boolean_value()); |
230 } | 247 } |
| 248 return true; |
231 } | 249 } |
232 | 250 |
233 void TargetGenerator::FillOutputs(bool allow_substitutions) { | 251 bool TargetGenerator::FillOutputs(bool allow_substitutions) { |
234 const Value* value = scope_->GetValue(variables::kOutputs, true); | 252 const Value* value = scope_->GetValue(variables::kOutputs, true); |
235 if (!value) | 253 if (!value) |
236 return; | 254 return true; |
237 | 255 |
238 SubstitutionList& outputs = target_->action_values().outputs(); | 256 SubstitutionList& outputs = target_->action_values().outputs(); |
239 if (!outputs.Parse(*value, err_)) | 257 if (!outputs.Parse(*value, err_)) |
240 return; | 258 return false; |
241 | 259 |
242 if (!allow_substitutions) { | 260 if (!allow_substitutions) { |
243 // Verify no substitutions were actually used. | 261 // Verify no substitutions were actually used. |
244 if (!outputs.required_types().empty()) { | 262 if (!outputs.required_types().empty()) { |
245 *err_ = Err(*value, "Source expansions not allowed here.", | 263 *err_ = Err(*value, "Source expansions not allowed here.", |
246 "The outputs of this target used source {{expansions}} but this " | 264 "The outputs of this target used source {{expansions}} but this " |
247 "targe type\ndoesn't support them. Just express the outputs " | 265 "targe type\ndoesn't support them. Just express the outputs " |
248 "literally."); | 266 "literally."); |
249 return; | 267 return false; |
250 } | 268 } |
251 } | 269 } |
252 | 270 |
253 // Check the substitutions used are valid for this purpose. | 271 // Check the substitutions used are valid for this purpose. |
254 if (!EnsureValidSourcesSubstitutions(outputs.required_types(), | 272 if (!EnsureValidSourcesSubstitutions(outputs.required_types(), |
255 value->origin(), err_)) | 273 value->origin(), err_)) |
256 return; | 274 return false; |
257 | 275 |
258 // Validate that outputs are in the output dir. | 276 // Validate that outputs are in the output dir. |
259 CHECK(outputs.list().size() == value->list_value().size()); | 277 CHECK(outputs.list().size() == value->list_value().size()); |
260 for (size_t i = 0; i < outputs.list().size(); i++) { | 278 for (size_t i = 0; i < outputs.list().size(); i++) { |
261 if (!EnsureSubstitutionIsInOutputDir(outputs.list()[i], | 279 if (!EnsureSubstitutionIsInOutputDir(outputs.list()[i], |
262 value->list_value()[i])) | 280 value->list_value()[i])) |
263 return; | 281 return false; |
264 } | 282 } |
| 283 return true; |
265 } | 284 } |
266 | 285 |
267 bool TargetGenerator::EnsureSubstitutionIsInOutputDir( | 286 bool TargetGenerator::EnsureSubstitutionIsInOutputDir( |
268 const SubstitutionPattern& pattern, | 287 const SubstitutionPattern& pattern, |
269 const Value& original_value) { | 288 const Value& original_value) { |
270 if (pattern.ranges().empty()) { | 289 if (pattern.ranges().empty()) { |
271 // Pattern is empty, error out (this prevents weirdness below). | 290 // Pattern is empty, error out (this prevents weirdness below). |
272 *err_ = Err(original_value, "This has an empty value in it."); | 291 *err_ = Err(original_value, "This has an empty value in it."); |
273 return false; | 292 return false; |
274 } | 293 } |
(...skipping 13 matching lines...) Expand all Loading... |
288 "The given file should be in the output directory. Normally you\n" | 307 "The given file should be in the output directory. Normally you\n" |
289 "would specify\n\"$target_out_dir/foo\" or " | 308 "would specify\n\"$target_out_dir/foo\" or " |
290 "\"{{source_gen_dir}}/foo\"."); | 309 "\"{{source_gen_dir}}/foo\"."); |
291 return false; | 310 return false; |
292 } | 311 } |
293 } | 312 } |
294 | 313 |
295 return true; | 314 return true; |
296 } | 315 } |
297 | 316 |
298 void TargetGenerator::FillGenericConfigs(const char* var_name, | 317 bool TargetGenerator::FillGenericConfigs(const char* var_name, |
299 UniqueVector<LabelConfigPair>* dest) { | 318 UniqueVector<LabelConfigPair>* dest) { |
300 const Value* value = scope_->GetValue(var_name, true); | 319 const Value* value = scope_->GetValue(var_name, true); |
301 if (value) { | 320 if (value) { |
302 ExtractListOfUniqueLabels(*value, scope_->GetSourceDir(), | 321 ExtractListOfUniqueLabels(*value, scope_->GetSourceDir(), |
303 ToolchainLabelForScope(scope_), dest, err_); | 322 ToolchainLabelForScope(scope_), dest, err_); |
304 } | 323 } |
| 324 return !err_->has_error(); |
305 } | 325 } |
306 | 326 |
307 void TargetGenerator::FillGenericDeps(const char* var_name, | 327 bool TargetGenerator::FillGenericDeps(const char* var_name, |
308 LabelTargetVector* dest) { | 328 LabelTargetVector* dest) { |
309 const Value* value = scope_->GetValue(var_name, true); | 329 const Value* value = scope_->GetValue(var_name, true); |
310 if (value) { | 330 if (value) { |
311 ExtractListOfLabels(*value, scope_->GetSourceDir(), | 331 ExtractListOfLabels(*value, scope_->GetSourceDir(), |
312 ToolchainLabelForScope(scope_), dest, err_); | 332 ToolchainLabelForScope(scope_), dest, err_); |
313 } | 333 } |
| 334 return !err_->has_error(); |
314 } | 335 } |
315 | 336 |
316 void TargetGenerator::FillForwardDependentConfigs() { | 337 bool TargetGenerator::FillForwardDependentConfigs() { |
317 const Value* value = scope_->GetValue( | 338 const Value* value = scope_->GetValue( |
318 variables::kForwardDependentConfigsFrom, true); | 339 variables::kForwardDependentConfigsFrom, true); |
319 if (value) { | 340 if (value) { |
320 ExtractListOfUniqueLabels(*value, scope_->GetSourceDir(), | 341 ExtractListOfUniqueLabels(*value, scope_->GetSourceDir(), |
321 ToolchainLabelForScope(scope_), | 342 ToolchainLabelForScope(scope_), |
322 &target_->forward_dependent_configs(), err_); | 343 &target_->forward_dependent_configs(), err_); |
323 } | 344 } |
| 345 return !err_->has_error(); |
324 } | 346 } |
OLD | NEW |