| 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/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 Loading... |
| 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 Loading... |
| 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 | |
| OLD | NEW |