OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "tools/gn/err.h" | 5 #include "tools/gn/err.h" |
6 #include "tools/gn/functions.h" | 6 #include "tools/gn/functions.h" |
7 #include "tools/gn/parse_tree.h" | 7 #include "tools/gn/parse_tree.h" |
8 #include "tools/gn/scope.h" | 8 #include "tools/gn/scope.h" |
9 | 9 |
10 namespace functions { | 10 namespace functions { |
11 | 11 |
12 const char kSetDefaults[] = "set_defaults"; | 12 const char kSetDefaults[] = "set_defaults"; |
13 const char kSetDefaults_HelpShort[] = | 13 const char kSetDefaults_HelpShort[] = |
14 "set_defaults: Set default values for a target type."; | 14 "set_defaults: Set default values for a target type."; |
15 const char kSetDefaults_Help[] = | 15 const char kSetDefaults_Help[] = |
16 "set_defaults: Set default values for a target type.\n" | 16 "set_defaults: Set default values for a target type.\n" |
17 "\n" | 17 "\n" |
18 " set_defaults(<target_type_name>) { <values...> }\n" | 18 " set_defaults(<target_type_name>) { <values...> }\n" |
19 "\n" | 19 "\n" |
20 " Sets the default values for a given target type. Whenever\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" | 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" | 22 " set_default's block will be copied into the current scope.\n" |
23 "\n" | 23 "\n" |
24 " When the target type is used, the variable copying is very strict.\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" | 25 " If a variable with that name is already in scope, the build will fail\n" |
26 " with an error.\n" | 26 " with an error.\n" |
27 "\n" | 27 "\n" |
28 " set_defaults can be used for built-in target types (\"executable\",\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" | 29 " \"shared_library\", etc.) and custom ones defined via the \"template\"\n" |
30 " command.\n" | 30 " command. It can be called more than once and the most recent call in\n" |
| 31 " any scope will apply, but there is no way to refer to the previous\n" |
| 32 " defaults and modify them (each call to set_defaults must supply a\n" |
| 33 " complete list of all defaults it wants). If you want to share\n" |
| 34 " defaults, store them in a separate variable.\n" |
31 "\n" | 35 "\n" |
32 "Example:\n" | 36 "Example\n" |
| 37 "\n" |
33 " set_defaults(\"static_library\") {\n" | 38 " set_defaults(\"static_library\") {\n" |
34 " configs = [ \"//tools/mything:settings\" ]\n" | 39 " configs = [ \"//tools/mything:settings\" ]\n" |
35 " }\n" | 40 " }\n" |
36 "\n" | 41 "\n" |
37 " static_library(\"mylib\")\n" | 42 " static_library(\"mylib\")\n" |
38 " # The configs will be auto-populated as above. You can remove it if\n" | 43 " # 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" | 44 " # you don't want the default for a particular default:\n" |
40 " configs -= \"//tools/mything:settings\"\n" | 45 " configs -= \"//tools/mything:settings\"\n" |
41 " }\n"; | 46 " }\n"; |
42 | 47 |
43 Value RunSetDefaults(Scope* scope, | 48 Value RunSetDefaults(Scope* scope, |
44 const FunctionCallNode* function, | 49 const FunctionCallNode* function, |
45 const std::vector<Value>& args, | 50 const std::vector<Value>& args, |
46 BlockNode* block, | 51 BlockNode* block, |
47 Err* err) { | 52 Err* err) { |
48 if (!EnsureSingleStringArg(function, args, err)) | 53 if (!EnsureSingleStringArg(function, args, err)) |
49 return Value(); | 54 return Value(); |
50 const std::string& target_type(args[0].string_value()); | 55 const std::string& target_type(args[0].string_value()); |
51 | 56 |
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) { | 57 if (!block) { |
74 FillNeedsBlockError(function, err); | 58 FillNeedsBlockError(function, err); |
75 return Value(); | 59 return Value(); |
76 } | 60 } |
77 | 61 |
78 // Run the block for the rule invocation. | 62 // Run the block for the rule invocation. |
79 Scope block_scope(scope); | 63 Scope block_scope(scope); |
80 block->Execute(&block_scope, err); | 64 block->Execute(&block_scope, err); |
81 if (err->has_error()) | 65 if (err->has_error()) |
82 return Value(); | 66 return Value(); |
83 | 67 |
84 // Now copy the values set on the scope we made into the free-floating one | 68 // 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. | 69 // (with no containing scope) used to hold the target defaults. |
86 Scope* dest = scope->MakeTargetDefaults(target_type); | 70 Scope* dest = scope->MakeTargetDefaults(target_type); |
87 block_scope.NonRecursiveMergeTo(dest, Scope::MergeOptions(), function, | 71 block_scope.NonRecursiveMergeTo(dest, Scope::MergeOptions(), function, |
88 "<SHOULD NOT FAIL>", err); | 72 "<SHOULD NOT FAIL>", err); |
89 return Value(); | 73 return Value(); |
90 } | 74 } |
91 | 75 |
92 } // namespace functions | 76 } // namespace functions |
OLD | NEW |