Home | History | Annotate | Download | only in gn
      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