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_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 41Value 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