| // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "gn/err.h" |
| #include "gn/functions.h" |
| #include "gn/parse_tree.h" |
| #include "gn/scope.h" |
| |
| namespace functions { |
| |
| const char kSetDefaults[] = "set_defaults"; |
| const char kSetDefaults_HelpShort[] = |
| "set_defaults: Set default values for a target type."; |
| const char kSetDefaults_Help[] = |
| R"(set_defaults: Set default values for a target type. |
| |
| set_defaults(<target_type_name>) { <values...> } |
| |
| Sets the default values for a given target type. Whenever target_type_name is |
| seen in the future, the values specified in set_default's block will be |
| copied into the current scope. |
| |
| When the target type is used, the variable copying is very strict. If a |
| variable with that name is already in scope, the build will fail with an |
| error. |
| |
| set_defaults can be used for built-in target types ("executable", |
| "shared_library", etc.) and custom ones defined via the "template" command. |
| It can be called more than once and the most recent call in any scope will |
| apply, but there is no way to refer to the previous defaults and modify them |
| (each call to set_defaults must supply a complete list of all defaults it |
| wants). If you want to share defaults, store them in a separate variable. |
| |
| Example |
| |
| set_defaults("static_library") { |
| configs = [ "//tools/mything:settings" ] |
| } |
| |
| static_library("mylib") { |
| # The configs will be auto-populated as above. You can remove it if |
| # you don't want the default for a particular default: |
| configs -= [ "//tools/mything:settings" ] |
| } |
| )"; |
| |
| Value RunSetDefaults(Scope* scope, |
| const FunctionCallNode* function, |
| const std::vector<Value>& args, |
| BlockNode* block, |
| Err* err) { |
| if (!EnsureSingleStringArg(function, args, err)) |
| return Value(); |
| const std::string& target_type(args[0].string_value()); |
| |
| if (!block) { |
| FillNeedsBlockError(function, err); |
| return Value(); |
| } |
| |
| // Run the block for the rule invocation. |
| Scope block_scope(scope); |
| block->Execute(&block_scope, err); |
| if (err->has_error()) |
| return Value(); |
| |
| // Now copy the values set on the scope we made into the free-floating one |
| // (with no containing scope) used to hold the target defaults. |
| Scope* dest = scope->MakeTargetDefaults(target_type); |
| block_scope.NonRecursiveMergeTo(dest, Scope::MergeOptions(), function, |
| "<SHOULD NOT FAIL>", err); |
| return Value(); |
| } |
| |
| } // namespace functions |