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/functions.h" 6 7 #include "tools/gn/err.h" 8 #include "tools/gn/parse_tree.h" 9 #include "tools/gn/scope.h" 10 #include "tools/gn/target_generator.h" 11 #include "tools/gn/value.h" 12 13 namespace functions { 14 15 namespace { 16 17 Value ExecuteGenericTarget(const char* target_type, 18 Scope* scope, 19 const FunctionCallNode* function, 20 const std::vector<Value>& args, 21 BlockNode* block, 22 Err* err) { 23 if (!EnsureNotProcessingImport(function, scope, err) || 24 !EnsureNotProcessingBuildConfig(function, scope, err)) 25 return Value(); 26 Scope block_scope(scope); 27 if (!FillTargetBlockScope(scope, function, target_type, block, 28 args, &block_scope, err)) 29 return Value(); 30 31 block->ExecuteBlockInScope(&block_scope, err); 32 if (err->has_error()) 33 return Value(); 34 35 TargetGenerator::GenerateTarget(&block_scope, function->function(), args, 36 target_type, err); 37 38 block_scope.CheckForUnusedVars(err); 39 return Value(); 40 } 41 42 } // namespace 43 44 // component ------------------------------------------------------------------- 45 46 const char kComponent[] = "component"; 47 const char kComponent_Help[] = 48 "TODO(brettw) write this."; 49 50 Value RunComponent(Scope* scope, 51 const FunctionCallNode* function, 52 const std::vector<Value>& args, 53 BlockNode* block, 54 Err* err) { 55 // A component is either a shared or static library, depending on the value 56 // of |component_mode|. 57 const Value* component_mode_value = scope->GetValue("component_mode"); 58 59 static const char helptext[] = 60 "You're declaring a component here but have not defined " 61 "\"component_mode\" to\neither \"shared_library\" or \"static_library\"."; 62 if (!component_mode_value) { 63 *err = Err(function->function(), "No component mode set.", helptext); 64 return Value(); 65 } 66 if (component_mode_value->type() != Value::STRING || 67 (component_mode_value->string_value() != functions::kSharedLibrary && 68 component_mode_value->string_value() != functions::kStaticLibrary)) { 69 *err = Err(function->function(), "Invalid component mode set.", helptext); 70 return Value(); 71 } 72 const std::string& component_mode = component_mode_value->string_value(); 73 74 if (!EnsureNotProcessingImport(function, scope, err)) 75 return Value(); 76 Scope block_scope(scope); 77 if (!FillTargetBlockScope(scope, function, component_mode.c_str(), block, 78 args, &block_scope, err)) 79 return Value(); 80 81 block->ExecuteBlockInScope(&block_scope, err); 82 if (err->has_error()) 83 return Value(); 84 85 TargetGenerator::GenerateTarget(&block_scope, function->function(), args, 86 component_mode, err); 87 return Value(); 88 } 89 90 // copy ------------------------------------------------------------------------ 91 92 const char kCopy[] = "copy"; 93 const char kCopy_Help[] = 94 "TODO(brettw) write this."; 95 96 Value RunCopy(const FunctionCallNode* function, 97 const std::vector<Value>& args, 98 Scope* scope, 99 Err* err) { 100 if (!EnsureNotProcessingImport(function, scope, err) || 101 !EnsureNotProcessingBuildConfig(function, scope, err)) 102 return Value(); 103 TargetGenerator::GenerateTarget(scope, function->function(), args, 104 functions::kCopy, err); 105 return Value(); 106 } 107 108 // custom ---------------------------------------------------------------------- 109 110 const char kCustom[] = "custom"; 111 const char kCustom_Help[] = 112 "custom: Declare a script-generated target.\n" 113 "\n" 114 " This target type allows you to run a script over a set of source\n" 115 " files and generate a set of output files.\n" 116 "\n" 117 " The script will be executed with the given arguments with the current\n" 118 " directory being that of the current BUILD file.\n" 119 "\n" 120 " There are two modes. The first mode is the \"per-file\" mode where you\n" 121 " specify a list of sources and the script is run once for each one as a\n" 122 " build rule. In this case, each file specified in the |outputs|\n" 123 " variable must be unique when applied to each source file (normally you\n" 124 " would reference |{{source_name_part}}| from within each one) or the\n" 125 " build system will get confused about how to build those files. You\n" 126 " should use the |data| variable to list all additional dependencies of\n" 127 " your script: these will be added as dependencies for each build step.\n" 128 "\n" 129 " The second mode is when you just want to run a script once rather than\n" 130 " as a general rule over a set of files. In this case you don't list any\n" 131 " sources. Dependencies of your script are specified only in the |data|\n" 132 " variable and your |outputs| variable should just list all outputs.\n" 133 "\n" 134 "Variables:\n" 135 "\n" 136 " args, data, deps, outputs, script*, sources\n" 137 " * = required\n" 138 "\n" 139 " There are some special substrings that will be searched for when\n" 140 " processing some variables:\n" 141 "\n" 142 " {{source}}\n" 143 " Expanded in |args|, this is the name of the source file relative\n" 144 " to the current directory when running the script. This is how\n" 145 " you specify the current input file to your script.\n" 146 "\n" 147 " {{source_name_part}}\n" 148 " Expanded in |args| and |outputs|, this is just the filename part\n" 149 " of the current source file with no directory or extension. This\n" 150 " is how you specify a name transformation to the output. Normally\n" 151 " you would write an output as\n" 152 " \"$target_output_dir/{{source_name_part}}.o\".\n" 153 "\n" 154 " All |outputs| files must be inside the output directory of the build.\n" 155 " You would generally use |$target_output_dir| or |$target_gen_dir| to\n" 156 " reference the output or generated intermediate file directories,\n" 157 " respectively.\n" 158 "\n" 159 "Examples:\n" 160 "\n" 161 " custom(\"general_rule\") {\n" 162 " script = \"do_processing.py\"\n" 163 " sources = [ \"foo.idl\" ]\n" 164 " data = [ \"my_configuration.txt\" ]\n" 165 " outputs = [ \"$target_gen_dir/{{source_name_part}}.h\" ]\n" 166 " args = [ \"{{source}}\",\n" 167 " \"-o\",\n" 168 " \"$relative_target_gen_dir/{{source_name_part}}.h\" ]\n" 169 " }\n" 170 "\n" 171 " custom(\"just_run_this_guy_once\") {\n" 172 " script = \"doprocessing.py\"\n" 173 " data = [ \"my_configuration.txt\" ]\n" 174 " outputs = [ \"$target_gen_dir/insightful_output.txt\" ]\n" 175 " args = [ \"--output_dir\", $target_gen_dir ]\n" 176 " }\n"; 177 178 Value RunCustom(Scope* scope, 179 const FunctionCallNode* function, 180 const std::vector<Value>& args, 181 BlockNode* block, 182 Err* err) { 183 return ExecuteGenericTarget(functions::kCustom, scope, function, args, 184 block, err); 185 } 186 187 // executable ------------------------------------------------------------------ 188 189 const char kExecutable[] = "executable"; 190 const char kExecutable_Help[] = 191 "TODO(brettw) write this."; 192 193 Value RunExecutable(Scope* scope, 194 const FunctionCallNode* function, 195 const std::vector<Value>& args, 196 BlockNode* block, 197 Err* err) { 198 return ExecuteGenericTarget(functions::kExecutable, scope, function, args, 199 block, err); 200 } 201 202 // group ----------------------------------------------------------------------- 203 204 const char kGroup[] = "group"; 205 const char kGroup_Help[] = 206 "group: Declare a named group of targets.\n" 207 "\n" 208 " This target type allows you to create meta-targets that just collect a\n" 209 " set of dependencies into one named target.\n" 210 "\n" 211 "Variables:\n" 212 "\n" 213 " deps\n" 214 "\n" 215 "Example:\n" 216 " group(\"all\") {\n" 217 " deps = [\n" 218 " \"//project:runner\",\n" 219 " \"//project:unit_tests\",\n" 220 " ]\n" 221 " }"; 222 223 Value RunGroup(Scope* scope, 224 const FunctionCallNode* function, 225 const std::vector<Value>& args, 226 BlockNode* block, 227 Err* err) { 228 return ExecuteGenericTarget(functions::kGroup, scope, function, args, 229 block, err); 230 } 231 232 // shared_library -------------------------------------------------------------- 233 234 const char kSharedLibrary[] = "shared_library"; 235 const char kSharedLibrary_Help[] = 236 "TODO(brettw) write this."; 237 238 Value RunSharedLibrary(Scope* scope, 239 const FunctionCallNode* function, 240 const std::vector<Value>& args, 241 BlockNode* block, 242 Err* err) { 243 return ExecuteGenericTarget(functions::kSharedLibrary, scope, function, args, 244 block, err); 245 } 246 247 // static_library -------------------------------------------------------------- 248 249 const char kStaticLibrary[] = "static_library"; 250 const char kStaticLibrary_Help[] = 251 "TODO(brettw) write this."; 252 253 Value RunStaticLibrary(Scope* scope, 254 const FunctionCallNode* function, 255 const std::vector<Value>& args, 256 BlockNode* block, 257 Err* err) { 258 return ExecuteGenericTarget(functions::kStaticLibrary, scope, function, args, 259 block, err); 260 } 261 262 // test ------------------------------------------------------------------------ 263 264 const char kTest[] = "test"; 265 const char kTest_Help[] = 266 "TODO(brettw) write this."; 267 268 Value RunTest(Scope* scope, 269 const FunctionCallNode* function, 270 const std::vector<Value>& args, 271 BlockNode* block, 272 Err* err) { 273 return ExecuteGenericTarget(functions::kExecutable, scope, function, args, 274 block, err); 275 } 276 277 } // namespace functions 278