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. 4 5 #include "tools/gn/binary_target_generator.h" 6 7 #include "tools/gn/config_values_generator.h" 8 #include "tools/gn/deps_iterator.h" 9 #include "tools/gn/err.h" 10 #include "tools/gn/functions.h" 11 #include "tools/gn/scope.h" 12 #include "tools/gn/value_extractors.h" 13 #include "tools/gn/variables.h" 14 15 BinaryTargetGenerator::BinaryTargetGenerator( 16 Target* target, 17 Scope* scope, 18 const FunctionCallNode* function_call, 19 Target::OutputType type, 20 Err* err) 21 : TargetGenerator(target, scope, function_call, err), 22 output_type_(type) { 23 } 24 25 BinaryTargetGenerator::~BinaryTargetGenerator() { 26 } 27 28 void BinaryTargetGenerator::DoRun() { 29 target_->set_output_type(output_type_); 30 31 if (!FillOutputName()) 32 return; 33 34 if (!FillOutputExtension()) 35 return; 36 37 if (!FillSources()) 38 return; 39 40 if (!FillPublic()) 41 return; 42 43 if (!FillCheckIncludes()) 44 return; 45 46 if (!FillInputs()) 47 return; 48 49 if (!FillConfigs()) 50 return; 51 52 if (!FillAllowCircularIncludesFrom()) 53 return; 54 55 if (!FillCompleteStaticLib()) 56 return; 57 58 // Config values (compiler flags, etc.) set directly on this target. 59 ConfigValuesGenerator gen(&target_->config_values(), scope_, 60 scope_->GetSourceDir(), err_); 61 gen.Run(); 62 if (err_->has_error()) 63 return; 64 } 65 66 bool BinaryTargetGenerator::FillCheckIncludes() { 67 const Value* value = scope_->GetValue(variables::kCheckIncludes, true); 68 if (!value) 69 return true; 70 if (!value->VerifyTypeIs(Value::BOOLEAN, err_)) 71 return false; 72 target_->set_check_includes(value->boolean_value()); 73 return true; 74 } 75 76 bool BinaryTargetGenerator::FillCompleteStaticLib() { 77 if (target_->output_type() == Target::STATIC_LIBRARY) { 78 const Value* value = scope_->GetValue(variables::kCompleteStaticLib, true); 79 if (!value) 80 return true; 81 if (!value->VerifyTypeIs(Value::BOOLEAN, err_)) 82 return false; 83 target_->set_complete_static_lib(value->boolean_value()); 84 } 85 return true; 86 } 87 88 bool BinaryTargetGenerator::FillOutputName() { 89 const Value* value = scope_->GetValue(variables::kOutputName, true); 90 if (!value) 91 return true; 92 if (!value->VerifyTypeIs(Value::STRING, err_)) 93 return false; 94 target_->set_output_name(value->string_value()); 95 return true; 96 } 97 98 bool BinaryTargetGenerator::FillOutputExtension() { 99 const Value* value = scope_->GetValue(variables::kOutputExtension, true); 100 if (!value) 101 return true; 102 if (!value->VerifyTypeIs(Value::STRING, err_)) 103 return false; 104 target_->set_output_extension(value->string_value()); 105 return true; 106 } 107 108 bool BinaryTargetGenerator::FillAllowCircularIncludesFrom() { 109 const Value* value = scope_->GetValue( 110 variables::kAllowCircularIncludesFrom, true); 111 if (!value) 112 return true; 113 114 UniqueVector<Label> circular; 115 ExtractListOfUniqueLabels(*value, scope_->GetSourceDir(), 116 ToolchainLabelForScope(scope_), &circular, err_); 117 if (err_->has_error()) 118 return false; 119 120 // Validate that all circular includes entries are in the deps. 121 for (size_t circular_i = 0; circular_i < circular.size(); circular_i++) { 122 bool found_dep = false; 123 for (DepsIterator iter(target_, DepsIterator::LINKED_ONLY); 124 !iter.done(); iter.Advance()) { 125 if (iter.label() == circular[circular_i]) { 126 found_dep = true; 127 break; 128 } 129 } 130 if (!found_dep) { 131 *err_ = Err(*value, "Label not in deps.", 132 "The label \"" + circular[circular_i].GetUserVisibleName(false) + 133 "\"\nwas not in the deps of this target. " 134 "allow_circular_includes_from only allows\ntargets present in the " 135 "deps."); 136 return false; 137 } 138 } 139 140 // Add to the set. 141 for (size_t i = 0; i < circular.size(); i++) 142 target_->allow_circular_includes_from().insert(circular[i]); 143 return true; 144 } 145