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/err.h"
      6 #include "tools/gn/functions.h"
      7 #include "tools/gn/parse_tree.h"
      8 #include "tools/gn/scope.h"
      9 
     10 namespace functions {
     11 
     12 const char kSetDefaults[] = "set_defaults";
     13 const char kSetDefaults_Help[] =
     14     "set_defaults: Set default values for a target type.\n"
     15     "\n"
     16     "  set_defaults(<target_type_name>) { <values...> }\n"
     17     "\n"
     18     "  Sets the default values for a given target type. Whenever\n"
     19     "  target_type_name is seen in the future, the values specified in\n"
     20     "  set_default's block will be copied into the current scope.\n"
     21     "\n"
     22     "  When the target type is used, the variable copying is very strict.\n"
     23     "  If a variable with that name is already in scope, the build will fail\n"
     24     "  with an error.\n"
     25     "\n"
     26     "  set_defaults can be used for built-in target types (\"executable\",\n"
     27     "  \"shared_library\", etc.) and custom ones defined via the \"template\"\n"
     28     "  command.\n"
     29     "\n"
     30     "Example:\n"
     31     "  set_defaults(\"static_library\") {\n"
     32     "    configs = [ \"//tools/mything:settings\" ]\n"
     33     "  }\n"
     34     "\n"
     35     "  static_library(\"mylib\")\n"
     36     "    # The configs will be auto-populated as above. You can remove it if\n"
     37     "    # you don't want the default for a particular default:\n"
     38     "    configs -= \"//tools/mything:setgings\"\n"
     39     "  }\n";
     40 
     41 Value RunSetDefaults(Scope* scope,
     42                      const FunctionCallNode* function,
     43                      const std::vector<Value>& args,
     44                      BlockNode* block,
     45                      Err* err) {
     46   if (!EnsureSingleStringArg(function, args, err))
     47     return Value();
     48   const std::string& target_type(args[0].string_value());
     49 
     50   // Ensure there aren't defaults already set.
     51   //
     52   // It might be nice to allow multiple calls set mutate the defaults. The
     53   // main case for this is where some local portions of the code want
     54   // additional defaults they specify in an imported file.
     55   //
     56   // Currently, we don't allow imports to clobber anything, so this wouldn't
     57   // work. Additionally, allowing this would be undesirable since we don't
     58   // want multiple imports to each try to set defaults, since it might look
     59   // like the defaults are modified by each one in sequence, while in fact
     60   // imports would always clobber previous values and it would be confusing.
     61   //
     62   // If we wanted this, the solution would be to allow imports to overwrite
     63   // target defaults set up by the default build config only. That way there
     64   // are no ordering issues, but this would be more work.
     65   if (scope->GetTargetDefaults(target_type)) {
     66     *err = Err(function->function(),
     67                "This target type defaults were already set.");
     68     return Value();
     69   }
     70 
     71   if (!block) {
     72     FillNeedsBlockError(function, err);
     73     return Value();
     74   }
     75 
     76   // Run the block for the rule invocation.
     77   Scope block_scope(scope);
     78   block->ExecuteBlockInScope(&block_scope, err);
     79   if (err->has_error())
     80     return Value();
     81 
     82   // Now copy the values set on the scope we made into the free-floating one
     83   // (with no containing scope) used to hold the target defaults.
     84   Scope* dest = scope->MakeTargetDefaults(target_type);
     85   block_scope.NonRecursiveMergeTo(dest, function, "<SHOULD NOT FAIL>", err);
     86   return Value();
     87 }
     88 
     89 }  // namespace functions
     90