Created a <webview> find API.
[chromium-blink-merge.git] / tools / gn / target_generator.cc
blob81c4394e0e2006de6f842f4bd7dcf90e008f65c0
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/target_generator.h"
7 #include "tools/gn/binary_target_generator.h"
8 #include "tools/gn/build_settings.h"
9 #include "tools/gn/config.h"
10 #include "tools/gn/copy_target_generator.h"
11 #include "tools/gn/err.h"
12 #include "tools/gn/filesystem_utils.h"
13 #include "tools/gn/functions.h"
14 #include "tools/gn/group_target_generator.h"
15 #include "tools/gn/parse_tree.h"
16 #include "tools/gn/scheduler.h"
17 #include "tools/gn/scope.h"
18 #include "tools/gn/script_target_generator.h"
19 #include "tools/gn/token.h"
20 #include "tools/gn/value.h"
21 #include "tools/gn/value_extractors.h"
22 #include "tools/gn/variables.h"
24 TargetGenerator::TargetGenerator(Target* target,
25 Scope* scope,
26 const FunctionCallNode* function_call,
27 Err* err)
28 : target_(target),
29 scope_(scope),
30 function_call_(function_call),
31 err_(err) {
34 TargetGenerator::~TargetGenerator() {
37 void TargetGenerator::Run() {
38 // All target types use these.
39 FillDependentConfigs();
40 FillData();
41 FillDependencies();
42 FillGypFile();
44 // Do type-specific generation.
45 DoRun();
48 // static
49 void TargetGenerator::GenerateTarget(Scope* scope,
50 const FunctionCallNode* function_call,
51 const std::vector<Value>& args,
52 const std::string& output_type,
53 Err* err) {
54 // Name is the argument to the function.
55 if (args.size() != 1u || args[0].type() != Value::STRING) {
56 *err = Err(function_call,
57 "Target generator requires one string argument.",
58 "Otherwise I'm not sure what to call this target.");
59 return;
62 // The location of the target is the directory name with no slash at the end.
63 // FIXME(brettw) validate name.
64 const Label& toolchain_label = ToolchainLabelForScope(scope);
65 Label label(scope->GetSourceDir(), args[0].string_value(),
66 toolchain_label.dir(), toolchain_label.name());
68 if (g_scheduler->verbose_logging())
69 g_scheduler->Log("Defining target", label.GetUserVisibleName(true));
71 scoped_ptr<Target> target(new Target(scope->settings(), label));
72 target->set_defined_from(function_call);
74 // Create and call out to the proper generator.
75 if (output_type == functions::kCopy) {
76 CopyTargetGenerator generator(target.get(), scope, function_call, err);
77 generator.Run();
78 } else if (output_type == functions::kCustom) {
79 ScriptTargetGenerator generator(target.get(), scope, function_call, err);
80 generator.Run();
81 } else if (output_type == functions::kExecutable) {
82 BinaryTargetGenerator generator(target.get(), scope, function_call,
83 Target::EXECUTABLE, err);
84 generator.Run();
85 } else if (output_type == functions::kGroup) {
86 GroupTargetGenerator generator(target.get(), scope, function_call, err);
87 generator.Run();
88 } else if (output_type == functions::kSharedLibrary) {
89 BinaryTargetGenerator generator(target.get(), scope, function_call,
90 Target::SHARED_LIBRARY, err);
91 generator.Run();
92 } else if (output_type == functions::kSourceSet) {
93 BinaryTargetGenerator generator(target.get(), scope, function_call,
94 Target::SOURCE_SET, err);
95 generator.Run();
96 } else if (output_type == functions::kStaticLibrary) {
97 BinaryTargetGenerator generator(target.get(), scope, function_call,
98 Target::STATIC_LIBRARY, err);
99 generator.Run();
100 } else {
101 *err = Err(function_call, "Not a known output type",
102 "I am very confused.");
105 if (!err->has_error())
106 scope->settings()->build_settings()->ItemDefined(target.PassAs<Item>());
109 const BuildSettings* TargetGenerator::GetBuildSettings() const {
110 return scope_->settings()->build_settings();
113 void TargetGenerator::FillSources() {
114 const Value* value = scope_->GetValue(variables::kSources, true);
115 if (!value)
116 return;
118 Target::FileList dest_sources;
119 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
120 scope_->GetSourceDir(), &dest_sources, err_))
121 return;
122 target_->sources().swap(dest_sources);
125 void TargetGenerator::FillSourcePrereqs() {
126 const Value* value = scope_->GetValue(variables::kSourcePrereqs, true);
127 if (!value)
128 return;
130 Target::FileList dest_reqs;
131 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
132 scope_->GetSourceDir(), &dest_reqs, err_))
133 return;
134 target_->source_prereqs().swap(dest_reqs);
137 void TargetGenerator::FillConfigs() {
138 FillGenericConfigs(variables::kConfigs, &target_->configs());
141 void TargetGenerator::FillDependentConfigs() {
142 FillGenericConfigs(variables::kAllDependentConfigs,
143 &target_->all_dependent_configs());
144 FillGenericConfigs(variables::kDirectDependentConfigs,
145 &target_->direct_dependent_configs());
148 void TargetGenerator::FillData() {
149 const Value* value = scope_->GetValue(variables::kData, true);
150 if (!value)
151 return;
153 Target::FileList dest_data;
154 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
155 scope_->GetSourceDir(), &dest_data, err_))
156 return;
157 target_->data().swap(dest_data);
160 void TargetGenerator::FillDependencies() {
161 FillGenericDeps(variables::kDeps, &target_->deps());
162 FillGenericDeps(variables::kDatadeps, &target_->datadeps());
164 // This is a list of dependent targets to have their configs fowarded, so
165 // it goes here rather than in FillConfigs.
166 FillForwardDependentConfigs();
168 FillHardDep();
171 void TargetGenerator::FillGypFile() {
172 const Value* gyp_file_value = scope_->GetValue(variables::kGypFile, true);
173 if (!gyp_file_value)
174 return;
175 if (!gyp_file_value->VerifyTypeIs(Value::STRING, err_))
176 return;
178 target_->set_gyp_file(scope_->GetSourceDir().ResolveRelativeFile(
179 gyp_file_value->string_value()));
182 void TargetGenerator::FillHardDep() {
183 const Value* hard_dep_value = scope_->GetValue(variables::kHardDep, true);
184 if (!hard_dep_value)
185 return;
186 if (!hard_dep_value->VerifyTypeIs(Value::BOOLEAN, err_))
187 return;
188 target_->set_hard_dep(hard_dep_value->boolean_value());
191 void TargetGenerator::FillExternal() {
192 const Value* value = scope_->GetValue(variables::kExternal, true);
193 if (!value)
194 return;
195 if (!value->VerifyTypeIs(Value::BOOLEAN, err_))
196 return;
197 target_->set_external(value->boolean_value());
200 void TargetGenerator::FillOutputs() {
201 const Value* value = scope_->GetValue(variables::kOutputs, true);
202 if (!value)
203 return;
205 Target::FileList outputs;
206 if (!ExtractListOfRelativeFiles(scope_->settings()->build_settings(), *value,
207 scope_->GetSourceDir(), &outputs, err_))
208 return;
210 // Validate that outputs are in the output dir.
211 CHECK(outputs.size() == value->list_value().size());
212 for (size_t i = 0; i < outputs.size(); i++) {
213 if (!EnsureStringIsInOutputDir(
214 GetBuildSettings()->build_dir(),
215 outputs[i].value(), value->list_value()[i], err_))
216 return;
218 target_->script_values().outputs().swap(outputs);
221 void TargetGenerator::FillGenericConfigs(const char* var_name,
222 LabelConfigVector* dest) {
223 const Value* value = scope_->GetValue(var_name, true);
224 if (value) {
225 ExtractListOfLabels(*value, scope_->GetSourceDir(),
226 ToolchainLabelForScope(scope_), dest, err_);
230 void TargetGenerator::FillGenericDeps(const char* var_name,
231 LabelTargetVector* dest) {
232 const Value* value = scope_->GetValue(var_name, true);
233 if (value) {
234 ExtractListOfLabels(*value, scope_->GetSourceDir(),
235 ToolchainLabelForScope(scope_), dest, err_);
239 void TargetGenerator::FillForwardDependentConfigs() {
240 const Value* value = scope_->GetValue(
241 variables::kForwardDependentConfigsFrom, true);
242 if (value) {
243 ExtractListOfLabels(*value, scope_->GetSourceDir(),
244 ToolchainLabelForScope(scope_),
245 &target_->forward_dependent_configs(), err_);