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 10namespace functions { 11 12const char kSetDefaults[] = "set_defaults"; 13const char kSetDefaults_HelpShort[] = 14 "set_defaults: Set default values for a target type."; 15const 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 43Value 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