// 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 "tools/gn/err.h" #include "tools/gn/functions.h" #include "tools/gn/parse_tree.h" #include "tools/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[] = "set_defaults: Set default values for a target type.\n" "\n" " set_defaults() { }\n" "\n" " Sets the default values for a given target type. Whenever\n" " target_type_name is seen in the future, the values specified in\n" " set_default's block will be copied into the current scope.\n" "\n" " When the target type is used, the variable copying is very strict.\n" " If a variable with that name is already in scope, the build will fail\n" " with an error.\n" "\n" " set_defaults can be used for built-in target types (\"executable\",\n" " \"shared_library\", etc.) and custom ones defined via the \"template\"\n" " command.\n" "\n" "Example:\n" " set_defaults(\"static_library\") {\n" " configs = [ \"//tools/mything:settings\" ]\n" " }\n" "\n" " static_library(\"mylib\")\n" " # The configs will be auto-populated as above. You can remove it if\n" " # you don't want the default for a particular default:\n" " configs -= \"//tools/mything:settings\"\n" " }\n"; Value RunSetDefaults(Scope* scope, const FunctionCallNode* function, const std::vector& args, BlockNode* block, Err* err) { if (!EnsureSingleStringArg(function, args, err)) return Value(); const std::string& target_type(args[0].string_value()); // Ensure there aren't defaults already set. // // It might be nice to allow multiple calls set mutate the defaults. The // main case for this is where some local portions of the code want // additional defaults they specify in an imported file. // // Currently, we don't allow imports to clobber anything, so this wouldn't // work. Additionally, allowing this would be undesirable since we don't // want multiple imports to each try to set defaults, since it might look // like the defaults are modified by each one in sequence, while in fact // imports would always clobber previous values and it would be confusing. // // If we wanted this, the solution would be to allow imports to overwrite // target defaults set up by the default build config only. That way there // are no ordering issues, but this would be more work. if (scope->GetTargetDefaults(target_type)) { *err = Err(function->function(), "This target type defaults were already set."); return 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, "", err); return Value(); } } // namespace functions