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

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

Issue 56433003: GN threading refactor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « tools/gn/target_generator.h ('k') | tools/gn/target_manager.h » ('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/target_generator.h" 5 #include "tools/gn/target_generator.h"
6 6
7 #include "tools/gn/binary_target_generator.h" 7 #include "tools/gn/binary_target_generator.h"
8 #include "tools/gn/build_settings.h" 8 #include "tools/gn/build_settings.h"
9 #include "tools/gn/config.h" 9 #include "tools/gn/config.h"
10 #include "tools/gn/copy_target_generator.h" 10 #include "tools/gn/copy_target_generator.h"
11 #include "tools/gn/err.h" 11 #include "tools/gn/err.h"
12 #include "tools/gn/filesystem_utils.h" 12 #include "tools/gn/filesystem_utils.h"
13 #include "tools/gn/functions.h" 13 #include "tools/gn/functions.h"
14 #include "tools/gn/group_target_generator.h" 14 #include "tools/gn/group_target_generator.h"
15 #include "tools/gn/item_node.h"
16 #include "tools/gn/parse_tree.h" 15 #include "tools/gn/parse_tree.h"
17 #include "tools/gn/scheduler.h" 16 #include "tools/gn/scheduler.h"
18 #include "tools/gn/scope.h" 17 #include "tools/gn/scope.h"
19 #include "tools/gn/script_target_generator.h" 18 #include "tools/gn/script_target_generator.h"
20 #include "tools/gn/target_manager.h"
21 #include "tools/gn/token.h" 19 #include "tools/gn/token.h"
22 #include "tools/gn/value.h" 20 #include "tools/gn/value.h"
23 #include "tools/gn/value_extractors.h" 21 #include "tools/gn/value_extractors.h"
24 #include "tools/gn/variables.h" 22 #include "tools/gn/variables.h"
25 23
26 TargetGenerator::TargetGenerator(Target* target, 24 TargetGenerator::TargetGenerator(Target* target,
27 Scope* scope, 25 Scope* scope,
28 const Token& function_token, 26 const FunctionCallNode* function_call,
29 Err* err) 27 Err* err)
30 : target_(target), 28 : target_(target),
31 scope_(scope), 29 scope_(scope),
32 function_token_(function_token), 30 function_call_(function_call),
33 err_(err) { 31 err_(err) {
34 } 32 }
35 33
36 TargetGenerator::~TargetGenerator() { 34 TargetGenerator::~TargetGenerator() {
37 } 35 }
38 36
39 void TargetGenerator::Run() { 37 void TargetGenerator::Run() {
40 // All target types use these. 38 // All target types use these.
41 FillDependentConfigs(); 39 FillDependentConfigs();
42 FillData(); 40 FillData();
43 FillDependencies(); 41 FillDependencies();
44 FillGypFile(); 42 FillGypFile();
45 43
46 // To type-specific generation. 44 // Do type-specific generation.
47 DoRun(); 45 DoRun();
48
49 // Mark the target as complete.
50 if (!err_->has_error()) {
51 target_->SetGenerated(&function_token_);
52 GetBuildSettings()->target_manager().TargetGenerationComplete(
53 target_->label(), err_);
54 }
55 } 46 }
56 47
57 // static 48 // static
58 void TargetGenerator::GenerateTarget(Scope* scope, 49 void TargetGenerator::GenerateTarget(Scope* scope,
59 const Token& function_token, 50 const FunctionCallNode* function_call,
60 const std::vector<Value>& args, 51 const std::vector<Value>& args,
61 const std::string& output_type, 52 const std::string& output_type,
62 Err* err) { 53 Err* err) {
63 // Name is the argument to the function. 54 // Name is the argument to the function.
64 if (args.size() != 1u || args[0].type() != Value::STRING) { 55 if (args.size() != 1u || args[0].type() != Value::STRING) {
65 *err = Err(function_token, 56 *err = Err(function_call,
66 "Target generator requires one string argument.", 57 "Target generator requires one string argument.",
67 "Otherwise I'm not sure what to call this target."); 58 "Otherwise I'm not sure what to call this target.");
68 return; 59 return;
69 } 60 }
70 61
71 // The location of the target is the directory name with no slash at the end. 62 // The location of the target is the directory name with no slash at the end.
72 // FIXME(brettw) validate name. 63 // FIXME(brettw) validate name.
73 const Label& toolchain_label = ToolchainLabelForScope(scope); 64 const Label& toolchain_label = ToolchainLabelForScope(scope);
74 Label label(scope->GetSourceDir(), args[0].string_value(), 65 Label label(scope->GetSourceDir(), args[0].string_value(),
75 toolchain_label.dir(), toolchain_label.name()); 66 toolchain_label.dir(), toolchain_label.name());
76 67
77 if (g_scheduler->verbose_logging()) 68 if (g_scheduler->verbose_logging())
78 g_scheduler->Log("Generating target", label.GetUserVisibleName(true)); 69 g_scheduler->Log("Defining target", label.GetUserVisibleName(true));
79 70
80 Target* target = 71 scoped_ptr<Target> target(new Target(scope->settings(), label));
81 scope->settings()->build_settings()->target_manager().GetTarget( 72 target->set_defined_from(function_call);
82 label, function_token.range(), NULL, err);
83 if (err->has_error())
84 return;
85 73
86 // Create and call out to the proper generator. 74 // Create and call out to the proper generator.
87 if (output_type == functions::kCopy) { 75 if (output_type == functions::kCopy) {
88 CopyTargetGenerator generator(target, scope, function_token, err); 76 CopyTargetGenerator generator(target.get(), scope, function_call, err);
89 generator.Run(); 77 generator.Run();
90 } else if (output_type == functions::kCustom) { 78 } else if (output_type == functions::kCustom) {
91 ScriptTargetGenerator generator(target, scope, function_token, err); 79 ScriptTargetGenerator generator(target.get(), scope, function_call, err);
92 generator.Run(); 80 generator.Run();
93 } else if (output_type == functions::kExecutable) { 81 } else if (output_type == functions::kExecutable) {
94 BinaryTargetGenerator generator(target, scope, function_token, 82 BinaryTargetGenerator generator(target.get(), scope, function_call,
95 Target::EXECUTABLE, err); 83 Target::EXECUTABLE, err);
96 generator.Run(); 84 generator.Run();
97 } else if (output_type == functions::kGroup) { 85 } else if (output_type == functions::kGroup) {
98 GroupTargetGenerator generator(target, scope, function_token, err); 86 GroupTargetGenerator generator(target.get(), scope, function_call, err);
99 generator.Run(); 87 generator.Run();
100 } else if (output_type == functions::kSharedLibrary) { 88 } else if (output_type == functions::kSharedLibrary) {
101 BinaryTargetGenerator generator(target, scope, function_token, 89 BinaryTargetGenerator generator(target.get(), scope, function_call,
102 Target::SHARED_LIBRARY, err); 90 Target::SHARED_LIBRARY, err);
103 generator.Run(); 91 generator.Run();
104 } else if (output_type == functions::kSourceSet) { 92 } else if (output_type == functions::kSourceSet) {
105 BinaryTargetGenerator generator(target, scope, function_token, 93 BinaryTargetGenerator generator(target.get(), scope, function_call,
106 Target::SOURCE_SET, err); 94 Target::SOURCE_SET, err);
107 generator.Run(); 95 generator.Run();
108 } else if (output_type == functions::kStaticLibrary) { 96 } else if (output_type == functions::kStaticLibrary) {
109 BinaryTargetGenerator generator(target, scope, function_token, 97 BinaryTargetGenerator generator(target.get(), scope, function_call,
110 Target::STATIC_LIBRARY, err); 98 Target::STATIC_LIBRARY, err);
111 generator.Run(); 99 generator.Run();
112 } else { 100 } else {
113 *err = Err(function_token, "Not a known output type", 101 *err = Err(function_call, "Not a known output type",
114 "I am very confused."); 102 "I am very confused.");
115 } 103 }
104
105 if (!err->has_error())
106 scope->settings()->build_settings()->ItemDefined(target.PassAs<Item>());
116 } 107 }
117 108
118 const BuildSettings* TargetGenerator::GetBuildSettings() const { 109 const BuildSettings* TargetGenerator::GetBuildSettings() const {
119 return scope_->settings()->build_settings(); 110 return scope_->settings()->build_settings();
120 } 111 }
121 112
122 void TargetGenerator::FillSources() { 113 void TargetGenerator::FillSources() {
123 const Value* value = scope_->GetValue(variables::kSources, true); 114 const Value* value = scope_->GetValue(variables::kSources, true);
124 if (!value) 115 if (!value)
125 return; 116 return;
(...skipping 22 matching lines...) Expand all
148 } 139 }
149 140
150 void TargetGenerator::FillDependentConfigs() { 141 void TargetGenerator::FillDependentConfigs() {
151 FillGenericConfigs(variables::kAllDependentConfigs, 142 FillGenericConfigs(variables::kAllDependentConfigs,
152 &target_->all_dependent_configs()); 143 &target_->all_dependent_configs());
153 FillGenericConfigs(variables::kDirectDependentConfigs, 144 FillGenericConfigs(variables::kDirectDependentConfigs,
154 &target_->direct_dependent_configs()); 145 &target_->direct_dependent_configs());
155 } 146 }
156 147
157 void TargetGenerator::FillData() { 148 void TargetGenerator::FillData() {
158 // TODO(brettW) hook this up to the constant when we have cleaned up
159 // how data files are used.
160 const Value* value = scope_->GetValue(variables::kData, true); 149 const Value* value = scope_->GetValue(variables::kData, true);
161 if (!value) 150 if (!value)
162 return; 151 return;
163 152
164 Target::FileList dest_data; 153 Target::FileList dest_data;
165 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value, 154 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
166 scope_->GetSourceDir(), &dest_data, err_)) 155 scope_->GetSourceDir(), &dest_data, err_))
167 return; 156 return;
168 target_->data().swap(dest_data); 157 target_->data().swap(dest_data);
169 } 158 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 CHECK(outputs.size() == value->list_value().size()); 211 CHECK(outputs.size() == value->list_value().size());
223 for (size_t i = 0; i < outputs.size(); i++) { 212 for (size_t i = 0; i < outputs.size(); i++) {
224 if (!EnsureStringIsInOutputDir( 213 if (!EnsureStringIsInOutputDir(
225 GetBuildSettings()->build_dir(), 214 GetBuildSettings()->build_dir(),
226 outputs[i].value(), value->list_value()[i], err_)) 215 outputs[i].value(), value->list_value()[i], err_))
227 return; 216 return;
228 } 217 }
229 target_->script_values().outputs().swap(outputs); 218 target_->script_values().outputs().swap(outputs);
230 } 219 }
231 220
232 void TargetGenerator::SetToolchainDependency() {
233 // TODO(brettw) currently we lock separately for each config, dep, and
234 // toolchain we add which is bad! Do this in one lock.
235 ItemTree* tree = &GetBuildSettings()->item_tree();
236 base::AutoLock lock(tree->lock());
237 ItemNode* tc_node =
238 tree->GetExistingNodeLocked(ToolchainLabelForScope(scope_));
239 target_->item_node()->AddDependency(
240 GetBuildSettings(), function_token_.range(), tc_node, err_);
241 }
242
243 void TargetGenerator::FillGenericConfigs(const char* var_name, 221 void TargetGenerator::FillGenericConfigs(const char* var_name,
244 LabelConfigVector* dest) { 222 LabelConfigVector* dest) {
245 const Value* value = scope_->GetValue(var_name, true); 223 const Value* value = scope_->GetValue(var_name, true);
246 if (!value) 224 if (value) {
247 return; 225 ExtractListOfLabels(*value, scope_->GetSourceDir(),
248 if (!ExtractListOfLabels(*value, scope_->GetSourceDir(), 226 ToolchainLabelForScope(scope_), dest, err_);
249 ToolchainLabelForScope(scope_), dest, err_))
250 return;
251
252 for (size_t i = 0; i < dest->size(); i++) {
253 LabelConfigPair& cur = (*dest)[i];
254 cur.ptr = Config::GetConfig(scope_->settings(),
255 value->list_value()[i].origin()->GetRange(),
256 cur.label, target_, err_);
257 if (err_->has_error())
258 return;
259 } 227 }
260 } 228 }
261 229
262 void TargetGenerator::FillGenericDeps(const char* var_name, 230 void TargetGenerator::FillGenericDeps(const char* var_name,
263 LabelTargetVector* dest) { 231 LabelTargetVector* dest) {
264 const Value* value = scope_->GetValue(var_name, true); 232 const Value* value = scope_->GetValue(var_name, true);
265 if (!value) 233 if (value) {
266 return; 234 ExtractListOfLabels(*value, scope_->GetSourceDir(),
267 if (!ExtractListOfLabels(*value, scope_->GetSourceDir(), 235 ToolchainLabelForScope(scope_), dest, err_);
268 ToolchainLabelForScope(scope_), dest, err_))
269 return;
270
271 for (size_t i = 0; i < dest->size(); i++) {
272 LabelTargetPair& cur = (*dest)[i];
273 cur.ptr = GetBuildSettings()->target_manager().GetTarget(
274 cur.label, value->list_value()[i].origin()->GetRange(), target_, err_);
275 if (err_->has_error())
276 return;
277 } 236 }
278 } 237 }
279 238
280 void TargetGenerator::FillForwardDependentConfigs() { 239 void TargetGenerator::FillForwardDependentConfigs() {
281 const Value* value = scope_->GetValue( 240 const Value* value = scope_->GetValue(
282 variables::kForwardDependentConfigsFrom, true); 241 variables::kForwardDependentConfigsFrom, true);
283 if (!value) 242 if (value) {
284 return; 243 ExtractListOfLabels(*value, scope_->GetSourceDir(),
285 244 ToolchainLabelForScope(scope_),
286 LabelTargetVector& dest = target_->forward_dependent_configs(); 245 &target_->forward_dependent_configs(), err_);
287 if (!ExtractListOfLabels(*value, scope_->GetSourceDir(),
288 ToolchainLabelForScope(scope_), &dest, err_))
289 return;
290
291 // We currently assume that the list is very small and do a brute-force
292 // search in the deps for the labeled target. This could be optimized.
293 const LabelTargetVector& deps = target_->deps();
294 std::vector<const Target*> forward_from_list;
295 for (size_t dest_index = 0; dest_index < dest.size(); dest_index++) {
296 LabelTargetPair& cur_dest = dest[dest_index];
297 for (size_t dep_index = 0; dep_index < deps.size(); dep_index++) {
298 if (deps[dep_index].label == cur_dest.label) {
299 cur_dest.ptr = deps[dep_index].ptr;
300 break;
301 }
302 }
303 if (!cur_dest.ptr) {
304 *err_ = Err(cur_dest.origin,
305 "Can't forward from this target.",
306 "forward_dependent_configs_from must contain a list of labels that\n"
307 "must all appear in the deps of the same target.");
308 return;
309 }
310 } 246 }
311 } 247 }
312
313
314
315
316
OLDNEW
« no previous file with comments | « tools/gn/target_generator.h ('k') | tools/gn/target_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698