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