diff options
author | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-20 17:59:15 +0000 |
---|---|---|
committer | brettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-03-20 17:59:15 +0000 |
commit | 2fbe101fd45323476bc2f25a7abd29af9da22b5c (patch) | |
tree | 6183b33d4d762c5d6c33a47b7f99550d9df230cb /tools/gn | |
parent | 8a17386774ce97470f7f001b0527f70c8125e0b5 (diff) | |
download | chromium_src-2fbe101fd45323476bc2f25a7abd29af9da22b5c.zip chromium_src-2fbe101fd45323476bc2f25a7abd29af9da22b5c.tar.gz chromium_src-2fbe101fd45323476bc2f25a7abd29af9da22b5c.tar.bz2 |
GN: Split custom into action and action_foreach
Previously the custom target type implemented two modes: iterate over a list of sources, and run a script once with a set of inputs. This proved a bit confusing since to differentiate these cases you had to either fill in sources or not.
This patch splits that apart into two targets: an action for running a script once, and an action_foreach for running a script over a set of inputs. This makes the differentiation explicit and allows more clear error reporting when you mess it up. I also added additional checks.
BUG=
R=scottmg@chromium.org
Review URL: https://codereview.chromium.org/200923007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@258342 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/gn')
30 files changed, 648 insertions, 415 deletions
diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn index 1c2f162..badfb0b 100644 --- a/tools/gn/BUILD.gn +++ b/tools/gn/BUILD.gn @@ -15,6 +15,10 @@ if (!is_gyp) { static_library("gn_lib") { sources = [ + "action_target_generator.cc", + "action_target_generator.h", + "action_values.cc", + "action_values.h", "args.cc", "args.h", "binary_target_generator.cc", @@ -69,8 +73,8 @@ static_library("gn_lib") { "gyp_binary_target_writer.h", "gyp_helper.cc", "gyp_helper.h", - "gyp_script_target_writer.cc", - "gyp_script_target_writer.h", + "gyp_action_target_writer.cc", + "gyp_action_target_writer.h", "gyp_target_writer.cc", "gyp_target_writer.h", "import_manager.cc", @@ -90,6 +94,8 @@ static_library("gn_lib") { "loader.h", "location.cc", "location.h", + "ninja_action_target_writer.cc", + "ninja_action_target_writer.h", "ninja_binary_target_writer.cc", "ninja_binary_target_writer.h", "ninja_build_writer.cc", @@ -100,8 +106,6 @@ static_library("gn_lib") { "ninja_group_target_writer.h", "ninja_helper.cc", "ninja_helper.h", - "ninja_script_target_writer.cc", - "ninja_script_target_writer.h", "ninja_target_writer.cc", "ninja_target_writer.h", "ninja_toolchain_writer.cc", @@ -125,10 +129,6 @@ static_library("gn_lib") { "scope.h", "scope_per_file_provider.cc", "scope_per_file_provider.h", - "script_target_generator.cc", - "script_target_generator.h", - "script_values.cc", - "script_values.h", "settings.cc", "settings.h", "setup.cc", @@ -185,18 +185,18 @@ test("gn_unittests") { sources = [ "builder_unittest.cc", "escape_unittest.cc", - "file_template_unittest.cc", "filesystem_utils_unittest.cc", + "file_template_unittest.cc", "function_rebase_path_unittest.cc", + "gyp_action_target_writer_unittest.cc", "gyp_binary_target_writer_unittest.cc", - "gyp_script_target_writer_unittest.cc", "input_conversion_unittest.cc", "label_unittest.cc", "loader_unittest.cc", + "ninja_action_target_writer_unittest.cc", "ninja_binary_target_writer_unittest.cc", "ninja_copy_target_writer_unittest.cc", "ninja_helper_unittest.cc", - "ninja_script_target_writer_unittest.cc", "operators_unittest.cc", "parser_unittest.cc", "path_output_unittest.cc", diff --git a/tools/gn/action_target_generator.cc b/tools/gn/action_target_generator.cc new file mode 100644 index 0000000..5f8f959 --- /dev/null +++ b/tools/gn/action_target_generator.cc @@ -0,0 +1,154 @@ +// 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/action_target_generator.h" + +#include "tools/gn/build_settings.h" +#include "tools/gn/err.h" +#include "tools/gn/filesystem_utils.h" +#include "tools/gn/parse_tree.h" +#include "tools/gn/scope.h" +#include "tools/gn/value.h" +#include "tools/gn/value_extractors.h" +#include "tools/gn/variables.h" + +namespace { + +// Returns true if the list of files looks like it might have a {{ }} pattern +// in it. Used for error checking. +bool FileListHasPattern(const Target::FileList& files) { + for (size_t i = 0; i < files.size(); i++) { + if (files[i].value().find("{{") != std::string::npos && + files[i].value().find("}}") != std::string::npos) + return true; + } + return false; +} + +} // namespace + +ActionTargetGenerator::ActionTargetGenerator( + Target* target, + Scope* scope, + const FunctionCallNode* function_call, + Target::OutputType type, + Err* err) + : TargetGenerator(target, scope, function_call, err), + output_type_(type) { +} + +ActionTargetGenerator::~ActionTargetGenerator() { +} + +void ActionTargetGenerator::DoRun() { + target_->set_output_type(output_type_); + + FillExternal(); + if (err_->has_error()) + return; + + FillSources(); + if (err_->has_error()) + return; + if (output_type_ == Target::ACTION_FOREACH && target_->sources().empty()) { + // Foreach rules must always have some sources to have an effect. + *err_ = Err(function_call_, "action_foreach target has no sources.", + "If you don't specify any sources, there is nothing to run your\n" + "script over."); + return; + } + + FillSourcePrereqs(); + if (err_->has_error()) + return; + + FillScript(); + if (err_->has_error()) + return; + + FillScriptArgs(); + if (err_->has_error()) + return; + + FillOutputs(); + if (err_->has_error()) + return; + + FillDepfile(); + if (err_->has_error()) + return; + + CheckOutputs(); + if (err_->has_error()) + return; + + // Action outputs don't depend on the current toolchain so we can skip adding + // that dependency. +} + +void ActionTargetGenerator::FillScript() { + // If this gets called, the target type requires a script, so error out + // if it doesn't have one. + const Value* value = scope_->GetValue(variables::kScript, true); + if (!value) { + *err_ = Err(function_call_, "This target type requires a \"script\"."); + return; + } + if (!value->VerifyTypeIs(Value::STRING, err_)) + return; + + target_->action_values().set_script( + scope_->GetSourceDir().ResolveRelativeFile(value->string_value())); +} + +void ActionTargetGenerator::FillScriptArgs() { + const Value* value = scope_->GetValue(variables::kArgs, true); + if (!value) + return; + + std::vector<std::string> args; + if (!ExtractListOfStringValues(*value, &args, err_)) + return; + target_->action_values().swap_in_args(&args); +} + +void ActionTargetGenerator::FillDepfile() { + const Value* value = scope_->GetValue(variables::kDepfile, true); + if (!value) + return; + target_->action_values().set_depfile( + scope_->settings()->build_settings()->build_dir().ResolveRelativeFile( + value->string_value())); +} + +void ActionTargetGenerator::CheckOutputs() { + const Target::FileList& outputs = target_->action_values().outputs(); + if (outputs.empty()) { + *err_ = Err(function_call_, "Action has no outputs.", + "If you have no outputs, the build system can not tell when your\n" + "script needs to be run."); + return; + } + + if (output_type_ == Target::ACTION) { + // Make sure the outputs for an action have no patterns in them. + if (FileListHasPattern(outputs)) { + *err_ = Err(function_call_, "Action has patterns in the output.", + "An action target should have the outputs completely specified. If\n" + "you want to provide a mapping from source to output, use an\n" + "\"action_foreach\" target."); + return; + } + } else if (output_type_ == Target::ACTION_FOREACH) { + // A foreach target should always have a pattern in the outputs. + if (!FileListHasPattern(outputs)) { + *err_ = Err(function_call_, + "action_foreach should have a pattern in the output.", + "An action_foreach target should have a source expansion pattern in\n" + "it to map source file to unique output file name. Otherwise, the\n" + "build system can't determine when your script needs to be run."); + return; + } + } +} diff --git a/tools/gn/action_target_generator.h b/tools/gn/action_target_generator.h new file mode 100644 index 0000000..aa81c3d --- /dev/null +++ b/tools/gn/action_target_generator.h @@ -0,0 +1,37 @@ +// 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. + +#ifndef TOOLS_GN_ACTION_TARGET_GENERATOR_H_ +#define TOOLS_GN_ACTION_TARGET_GENERATOR_H_ + +#include "base/compiler_specific.h" +#include "tools/gn/target_generator.h" + +// Populates a Target with the values from an action[_foreach] rule. +class ActionTargetGenerator : public TargetGenerator { + public: + ActionTargetGenerator(Target* target, + Scope* scope, + const FunctionCallNode* function_call, + Target::OutputType type, + Err* err); + virtual ~ActionTargetGenerator(); + + protected: + virtual void DoRun() OVERRIDE; + + private: + void FillScript(); + void FillScriptArgs(); + void FillDepfile(); + + // Checks for errors in the outputs variable. + void CheckOutputs(); + + Target::OutputType output_type_; + + DISALLOW_COPY_AND_ASSIGN(ActionTargetGenerator); +}; + +#endif // TOOLS_GN_ACTION_TARGET_GENERATOR_H_ diff --git a/tools/gn/script_values.cc b/tools/gn/action_values.cc index c5d7989..80bea62 100644 --- a/tools/gn/script_values.cc +++ b/tools/gn/action_values.cc @@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "tools/gn/script_values.h" +#include "tools/gn/action_values.h" -ScriptValues::ScriptValues() { +ActionValues::ActionValues() { } -ScriptValues::~ScriptValues() { +ActionValues::~ActionValues() { } diff --git a/tools/gn/script_values.h b/tools/gn/action_values.h index 50219ef..8b883c7 100644 --- a/tools/gn/script_values.h +++ b/tools/gn/action_values.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef TOOLS_GN_SCRIPT_VALUES_H_ -#define TOOLS_GN_SCRIPT_VALUES_H_ +#ifndef TOOLS_GN_ACTION_VALUES_H_ +#define TOOLS_GN_ACTION_VALUES_H_ #include <string> #include <vector> @@ -11,12 +11,12 @@ #include "base/basictypes.h" #include "tools/gn/source_file.h" -// Holds the values (outputs, args, script name, etc.) for a script-based -// target. -class ScriptValues { +// Holds the values (outputs, args, script name, etc.) for either an action or +// an action_foreach target. +class ActionValues { public: - ScriptValues(); - ~ScriptValues(); + ActionValues(); + ~ActionValues(); // Filename of the script to execute. const SourceFile& script() const { return script_; } @@ -43,7 +43,7 @@ class ScriptValues { std::vector<SourceFile> outputs_; SourceFile depfile_; - DISALLOW_COPY_AND_ASSIGN(ScriptValues); + DISALLOW_COPY_AND_ASSIGN(ActionValues); }; -#endif // TOOLS_GN_SCRIPT_VALUES_H_ +#endif // TOOLS_GN_ACTION_VALUES_H_ diff --git a/tools/gn/copy_target_generator.cc b/tools/gn/copy_target_generator.cc index b1b9076..c88b0c4 100644 --- a/tools/gn/copy_target_generator.cc +++ b/tools/gn/copy_target_generator.cc @@ -38,7 +38,7 @@ void CopyTargetGenerator::DoRun() { "You have to specify at least one file to copy in the \"sources\"."); return; } - if (target_->script_values().outputs().size() != 1) { + if (target_->action_values().outputs().size() != 1) { *err_ = Err(function_call_, "Copy command must have exactly one output.", "You must specify exactly one value in the \"outputs\" array for the " "destination of the copy\n(see \"gn help copy\"). If there are " diff --git a/tools/gn/file_template.cc b/tools/gn/file_template.cc index 92a44a9..ec34993 100644 --- a/tools/gn/file_template.cc +++ b/tools/gn/file_template.cc @@ -19,7 +19,7 @@ const char FileTemplate::kSourceFilePart[] = "{{source_file_part}}"; const char kSourceExpansion_Help[] = "How Source Expansion Works\n" "\n" - " Source expansion is used for the custom script and copy target types\n" + " Source expansion is used for the action_foreach and copy target types\n" " to map source file names to output file names or arguments.\n" "\n" " To perform source expansion in the outputs, GN maps every entry in the\n" @@ -34,8 +34,8 @@ const char kSourceExpansion_Help[] = " as a static list of literal file names that do not depend on the\n" " sources.\n" "\n" - " See \"gn help copy\" and \"gn help custom\" for more on how this is\n" - " applied.\n" + " See \"gn help copy\" and \"gn help action_foreach\" for more on how\n" + " this is applied.\n" "\n" "Placeholders\n" "\n" @@ -59,7 +59,7 @@ const char kSourceExpansion_Help[] = "Examples\n" "\n" " Non-varying outputs:\n" - " script(\"hardcoded_outputs\") {\n" + " action(\"hardcoded_outputs\") {\n" " sources = [ \"input1.idl\", \"input2.idl\" ]\n" " outputs = [ \"$target_out_dir/output1.dat\",\n" " \"$target_out_dir/output2.dat\" ]\n" @@ -67,7 +67,7 @@ const char kSourceExpansion_Help[] = " The outputs in this case will be the two literal files given.\n" "\n" " Varying outputs:\n" - " script(\"varying_outputs\") {\n" + " action_foreach(\"varying_outputs\") {\n" " sources = [ \"input1.idl\", \"input2.idl\" ]\n" " outputs = [ \"$target_out_dir/{{source_name_part}}.h\",\n" " \"$target_out_dir/{{source_name_part}}.cc\" ]\n" @@ -96,7 +96,7 @@ FileTemplate::~FileTemplate() { // static FileTemplate FileTemplate::GetForTargetOutputs(const Target* target) { - const Target::FileList& outputs = target->script_values().outputs(); + const Target::FileList& outputs = target->action_values().outputs(); std::vector<std::string> output_template_args; for (size_t i = 0; i < outputs.size(); i++) output_template_args.push_back(outputs[i].value()); diff --git a/tools/gn/function_rebase_path.cc b/tools/gn/function_rebase_path.cc index aefedd5..a167cda 100644 --- a/tools/gn/function_rebase_path.cc +++ b/tools/gn/function_rebase_path.cc @@ -211,7 +211,7 @@ const char kRebasePath_Help[] = " foo = rebase_path(\"source/myfile.txt\", \".\", \".\", \"to_system\")\n" "\n" " # Typical usage for converting to the build directory for a script.\n" - " custom(\"myscript\") {\n" + " action(\"myscript\") {\n" " # Don't convert sources, GN will automatically convert these to be\n" " # relative to the build directory when it contructs the command\n" " # line for your script.\n" @@ -224,7 +224,7 @@ const char kRebasePath_Help[] = " rebase_path(\"//mything/data/input.dat\", root_build_dir),\n" " \"--rel\",\n" " rebase_path(\"relative_path.txt\", root_build_dir)\n" - " ]\n" + " ] + sources\n" " }\n"; Value RunRebasePath(Scope* scope, diff --git a/tools/gn/function_template.cc b/tools/gn/function_template.cc index 0947305..f726529 100644 --- a/tools/gn/function_template.cc +++ b/tools/gn/function_template.cc @@ -58,7 +58,7 @@ const char kTemplate_Help[] = " \"$target_gen_dir/{{source_name_part}}.h\" ]\n" "\n" " # Intermediate target to compile IDL to C source.\n" - " custom(\"${target_name}_code_gen\") {\n" + " action_foreach(\"${target_name}_code_gen\") {\n" " # The |sources| will be inherited from the surrounding scope so\n" " # we don't need to redefine it.\n" " script = \"foo.py\"\n" diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc index 2443ad9..8d146b2 100644 --- a/tools/gn/functions.cc +++ b/tools/gn/functions.cc @@ -574,11 +574,12 @@ struct FunctionInfoInitializer { #define INSERT_FUNCTION(command) \ map[k##command] = FunctionInfo(&Run##command, k##command##_Help); + INSERT_FUNCTION(Action) + INSERT_FUNCTION(ActionForEach) INSERT_FUNCTION(Assert) INSERT_FUNCTION(Component) INSERT_FUNCTION(Config) INSERT_FUNCTION(Copy) - INSERT_FUNCTION(Custom) INSERT_FUNCTION(DeclareArgs) INSERT_FUNCTION(Defined) INSERT_FUNCTION(ExecScript) diff --git a/tools/gn/functions.h b/tools/gn/functions.h index 60eb202..2a5d0a2 100644 --- a/tools/gn/functions.h +++ b/tools/gn/functions.h @@ -54,6 +54,22 @@ typedef Value (*NoBlockFunction)(Scope* scope, const std::vector<Value>& args, Err* err); +extern const char kAction[]; +extern const char kAction_Help[]; +Value RunAction(Scope* scope, + const FunctionCallNode* function, + const std::vector<Value>& args, + BlockNode* block, + Err* err); + +extern const char kActionForEach[]; +extern const char kActionForEach_Help[]; +Value RunActionForEach(Scope* scope, + const FunctionCallNode* function, + const std::vector<Value>& args, + BlockNode* block, + Err* err); + extern const char kAssert[]; extern const char kAssert_Help[]; Value RunAssert(Scope* scope, @@ -83,14 +99,6 @@ Value RunCopy(const FunctionCallNode* function, Scope* block_scope, Err* err); -extern const char kCustom[]; -extern const char kCustom_Help[]; -Value RunCustom(Scope* scope, - const FunctionCallNode* function, - const std::vector<Value>& args, - BlockNode* block, - Err* err); - extern const char kDeclareArgs[]; extern const char kDeclareArgs_Help[]; Value RunDeclareArgs(Scope* scope, diff --git a/tools/gn/functions_target.cc b/tools/gn/functions_target.cc index 8c61f3b..9b47cf74 100644 --- a/tools/gn/functions_target.cc +++ b/tools/gn/functions_target.cc @@ -52,6 +52,148 @@ Value ExecuteGenericTarget(const char* target_type, } // namespace +// action ---------------------------------------------------------------------- + +// Common help paragraph on script runtime execution directories. +#define SCRIPT_EXECUTION_CONTEXT \ + " The script will be executed with the given arguments with the current\n"\ + " directory being that of the root build directory. If you pass files\n"\ + " to your script, see \"gn help to_build_path\" for how to convert\n" \ + " file names to be relative to the build directory (file names in the\n" \ + " sources, outputs, and source_prereqs will be all treated as relative\n" \ + " to the current build file and converted as needed automatically).\n" + +// Common help paragraph on script output directories. +#define SCRIPT_EXECUTION_OUTPUTS \ + " All output files must be inside the output directory of the build.\n" \ + " You would generally use |$target_out_dir| or |$target_gen_dir| to\n" \ + " reference the output or generated intermediate file directories,\n" \ + " respectively.\n" + +const char kAction[] = "action"; +const char kAction_Help[] = + "action: Declare a target that runs a script a single time.\n" + "\n" + " This target type allows you to run a script a single time to produce\n" + " or more output files. If you want to run a script once for each of a\n" + " set of input files, see \"gn help action_foreach\".\n" + "\n" + " In an action the \"sources\" and \"source_prereqs\" are treated the\n" + " same: they're both input dependencies on script execution with no\n" + " special handling. If you want to pass the sources to your script, you\n" + " must do so explicitly by including them in the \"args\".\n" + "\n" + " It is recommended you put inputs to your script in the \"sources\"\n" + " variable, and stuff like other Python files required to run your\n" + " script in the \"source_prereqs\" variable.\n" + "\n" + " You should specify files created by your script by specifying them in\n" + " the \"outputs\".\n" + "\n" + SCRIPT_EXECUTION_CONTEXT + "\n" + "File name handling\n" + "\n" + SCRIPT_EXECUTION_OUTPUTS + "\n" + "Variables\n" + "\n" + " args, data, datadeps, depfile, deps, outputs*, script*,\n" + " source_prereqs, sources\n" + " * = required\n" + "\n" + "Example\n" + "\n" + " action(\"run_this_guy_once\") {\n" + " script = \"doprocessing.py\"\n" + " sources = [ \"my_configuration.txt\" ]\n" + " outputs = [ \"$target_gen_dir/insightful_output.txt\" ]\n" + "\n" + " # Our script imports this Python file so we want to rebuild if it\n" + " # changes.\n" + " source_prereqs = [ \"helper_library.py\" ]\n" + "\n" + " # Note that we have to manually pass the sources to our script if\n" + " # the script needs them as inputs.\n" + " args = [ \"--out\", to_build_path(target_gen_dir) ] + sources\n" + " }\n"; + +Value RunAction(Scope* scope, + const FunctionCallNode* function, + const std::vector<Value>& args, + BlockNode* block, + Err* err) { + return ExecuteGenericTarget(functions::kAction, scope, function, args, + block, err); +} + +// action_foreach -------------------------------------------------------------- + +const char kActionForEach[] = "action_foreach"; +const char kActionForEach_Help[] = + "action_foreach: Run a script over a set of input files.\n" + "\n" + " This target type allows you to run a script once-per-file over a set\n" + " of sources. If you want to run a script once that takes many files as\n" + " input, see \"gn help action\".\n" + "\n" + " The script will be run once per file in the \"sources\" variable. The\n" + " \"outputs\" variable should specify one or more files with a source\n" + " expansion pattern in it (see \"gn help source_expansion\"). The output\n" + " file(s) for each script invocation should be unique. Normally you\n" + " use \"{{source_name_part}}\" in each output file.\n" + "\n" + " If your script takes additional data as input, such as a shared\n" + " configuration file or a Python module it uses, those files should be\n" + " listed in the \"source_prereqs\" variable. These files are treated as\n" + " dependencies of each script invocation.\n" + "\n" + SCRIPT_EXECUTION_CONTEXT + "\n" + "File name handling\n" + "\n" + SCRIPT_EXECUTION_OUTPUTS + "\n" + "Variables\n" + "\n" + " args, data, datadeps, depfile, deps, outputs*, script*,\n" + " source_prereqs, sources*\n" + " * = required\n" + "\n" + "Example\n" + "\n" + " # Runs the script over each IDL file. The IDL script will generate\n" + " # both a .cc and a .h file for each input.\n" + " action_foreach(\"my_idl\") {\n" + " script = \"idl_processor.py\"\n" + " sources = [ \"foo.idl\", \"bar.idl\" ]\n" + "\n" + " # Our script reads this file each time, so we need to list is as a\n" + " # dependency so we can rebuild if it changes.\n" + " source_prereqs = [ \"my_configuration.txt\" ]\n" + "\n" + " # Transformation from source file name to output file names.\n" + " outputs = [ \"$target_gen_dir/{{source_name_part}}.h\",\n" + " \"$target_gen_dir/{{source_name_part}}.cc\" ]\n" + "\n" + " # Note that since \"args\" is opaque to GN, if you specify paths\n" + " # here, you will need to convert it to be relative to the build\n" + " # directory using \"to_build_path()\".\n" + " args = [ \"{{source}}\",\n" + " \"-o\",\n" + " to_build_path(relative_target_gen_dir) + \"/\" +\n" + " {{source_name_part}}.h\" ]\n" + " }\n" + "\n"; +Value RunActionForEach(Scope* scope, + const FunctionCallNode* function, + const std::vector<Value>& args, + BlockNode* block, + Err* err) { + return ExecuteGenericTarget(functions::kActionForEach, scope, function, args, + block, err); +} + // component ------------------------------------------------------------------- const char kComponent[] = "component"; @@ -167,91 +309,6 @@ Value RunCopy(const FunctionCallNode* function, return Value(); } -// custom ---------------------------------------------------------------------- - -const char kCustom[] = "custom"; -const char kCustom_Help[] = - "custom: Declare a script-generated target.\n" - "\n" - " This target type allows you to run a script over a set of source\n" - " files and generate a set of output files.\n" - "\n" - " The script will be executed with the given arguments with the current\n" - " directory being that of the root build directory. If you pass files\n" - " to your script, see \"gn help to_build_path\" for how to convert\n" - " file names to be relative to the build directory (file names in the\n" - " sources, outputs, and source_prereqs will be all treated as relative\n" - " to the current build file and converted as needed automatically).\n" - "\n" - " There are two modes. The first mode is the \"per-file\" mode where you\n" - " specify a list of sources and the script is run once for each one as a\n" - " build rule. In this case, each file specified in the |outputs|\n" - " variable must be unique when applied to each source file (normally you\n" - " would reference |{{source_name_part}}| from within each one) or the\n" - " build system will get confused about how to build those files. You\n" - " should use the |source_prereqs| variable to list all additional\n" - " dependencies of your script: these will be added as dependencies for\n" - " each build step.\n" - "\n" - " The second mode is when you just want to run a script once rather than\n" - " as a general rule over a set of files. In this case you don't list any\n" - " sources. Dependencies of your script are specified only in the\n" - " |source_prereqs| variable and your |outputs| variable should just list\n" - " all outputs.\n" - "\n" - "File name handling\n" - "\n" - " All output files must be inside the output directory of the build.\n" - " You would generally use |$target_out_dir| or |$target_gen_dir| to\n" - " reference the output or generated intermediate file directories,\n" - " respectively.\n" - "\n" - " You can specify a mapping from source files to output files using\n" - " source expansion (see \"gn help source_expansion\"). The placeholders\n" - " will look like \"{{source}}\", for example, and can appear in\n" - " either the outputs or the args lists.\n" - "\n" - "Variables\n" - "\n" - " args, deps, outputs, script*, source_prereqs, sources\n" - " * = required\n" - "\n" - "Examples\n" - "\n" - " # Runs the script over each IDL file. The IDL script will generate\n" - " # both a .cc and a .h file for each input.\n" - " custom(\"general_rule\") {\n" - " script = \"idl_processor.py\"\n" - " sources = [ \"foo.idl\", \"bar.idl\" ]\n" - " source_prereqs = [ \"my_configuration.txt\" ]\n" - " outputs = [ \"$target_gen_dir/{{source_name_part}}.h\",\n" - " \"$target_gen_dir/{{source_name_part}}.cc\" ]\n" - "\n" - " # Note that since \"args\" is opaque to GN, if you specify paths\n" - " # here, you will need to convert it to be relative to the build\n" - " # directory using \"to_build_path()\".\n" - " args = [ \"{{source}}\",\n" - " \"-o\",\n" - " to_build_path(relative_target_gen_dir) + \"/\" +\n" - " {{source_name_part}}.h\" ]\n" - " }\n" - "\n" - " custom(\"just_run_this_guy_once\") {\n" - " script = \"doprocessing.py\"\n" - " source_prereqs = [ \"my_configuration.txt\" ]\n" - " outputs = [ \"$target_gen_dir/insightful_output.txt\" ]\n" - " args = [ \"--output_dir\", to_build_path(target_gen_dir) ]\n" - " }\n"; - -Value RunCustom(Scope* scope, - const FunctionCallNode* function, - const std::vector<Value>& args, - BlockNode* block, - Err* err) { - return ExecuteGenericTarget(functions::kCustom, scope, function, args, - block, err); -} - // executable ------------------------------------------------------------------ const char kExecutable[] = "executable"; diff --git a/tools/gn/gn.gyp b/tools/gn/gn.gyp index 0670ad4..fe305c1 100644 --- a/tools/gn/gn.gyp +++ b/tools/gn/gn.gyp @@ -10,6 +10,10 @@ '../../base/base.gyp:base', ], 'sources': [ + 'action_target_generator.cc', + 'action_target_generator.h', + 'action_values.cc', + 'action_values.h', 'args.cc', 'args.h', 'binary_target_generator.cc', @@ -60,12 +64,12 @@ 'function_write_file.cc', 'group_target_generator.cc', 'group_target_generator.h', + 'gyp_action_target_writer.cc', + 'gyp_action_target_writer.h', 'gyp_binary_target_writer.cc', 'gyp_binary_target_writer.h', 'gyp_helper.cc', 'gyp_helper.h', - 'gyp_script_target_writer.cc', - 'gyp_script_target_writer.h', 'gyp_target_writer.cc', 'gyp_target_writer.h', 'import_manager.cc', @@ -85,6 +89,8 @@ 'loader.h', 'location.cc', 'location.h', + 'ninja_action_target_writer.cc', + 'ninja_action_target_writer.h', 'ninja_binary_target_writer.cc', 'ninja_binary_target_writer.h', 'ninja_build_writer.cc', @@ -95,8 +101,6 @@ 'ninja_group_target_writer.h', 'ninja_helper.cc', 'ninja_helper.h', - 'ninja_script_target_writer.cc', - 'ninja_script_target_writer.h', 'ninja_target_writer.cc', 'ninja_target_writer.h', 'ninja_toolchain_writer.cc', @@ -120,10 +124,6 @@ 'scope.h', 'scope_per_file_provider.cc', 'scope_per_file_provider.h', - 'script_target_generator.cc', - 'script_target_generator.h', - 'script_values.cc', - 'script_values.h', 'settings.cc', 'settings.h', 'setup.cc', @@ -174,18 +174,18 @@ 'sources': [ 'builder_unittest.cc', 'escape_unittest.cc', - 'file_template_unittest.cc', 'filesystem_utils_unittest.cc', + 'file_template_unittest.cc', 'function_rebase_path_unittest.cc', + 'gyp_action_target_writer_unittest.cc', 'gyp_binary_target_writer_unittest.cc', - 'gyp_script_target_writer_unittest.cc', 'input_conversion_unittest.cc', 'label_unittest.cc', 'loader_unittest.cc', + 'ninja_action_target_writer_unittest.cc', 'ninja_binary_target_writer_unittest.cc', - 'ninja_helper_unittest.cc', 'ninja_copy_target_writer_unittest.cc', - 'ninja_script_target_writer_unittest.cc', + 'ninja_helper_unittest.cc', 'operators_unittest.cc', 'parser_unittest.cc', 'path_output_unittest.cc', diff --git a/tools/gn/gyp_script_target_writer.cc b/tools/gn/gyp_action_target_writer.cc index 472a23b..7df2b9d 100644 --- a/tools/gn/gyp_script_target_writer.cc +++ b/tools/gn/gyp_action_target_writer.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "tools/gn/gyp_script_target_writer.h" +#include "tools/gn/gyp_action_target_writer.h" #include "tools/gn/builder_record.h" #include "tools/gn/err.h" @@ -11,11 +11,11 @@ #include "tools/gn/settings.h" #include "tools/gn/target.h" -// Write script targets as GYP actions that just invoke Ninja. This allows us -// to not have to worry about duplicating the precise GN script execution +// Write action targets as GYP actions that just invoke Ninja. This allows us +// to not have to worry about duplicating the precise GN action execution // semantices in GYP for each platform (GYP varies a bit). -GypScriptTargetWriter::GypScriptTargetWriter(const TargetGroup& group, +GypActionTargetWriter::GypActionTargetWriter(const TargetGroup& group, const Toolchain* toolchain, const SourceDir& gyp_dir, std::ostream& out) @@ -23,14 +23,14 @@ GypScriptTargetWriter::GypScriptTargetWriter(const TargetGroup& group, gyp_dir, out) { } -GypScriptTargetWriter::~GypScriptTargetWriter() { +GypActionTargetWriter::~GypActionTargetWriter() { } -void GypScriptTargetWriter::Run() { +void GypActionTargetWriter::Run() { int indent = 4; std::string name = helper_.GetNameForTarget(target_); - // Put the ninja build for this script target in this directory. + // Put the ninja build for this action target in this directory. SourceDir ninja_dir(GetTargetOutputDir(target_).value() + name + "_ninja/"); Indent(indent) << "{\n"; @@ -57,7 +57,7 @@ void GypScriptTargetWriter::Run() { Indent(indent) << "},\n"; } -void GypScriptTargetWriter::WriteActionInputs(int indent) { +void GypActionTargetWriter::WriteActionInputs(int indent) { Indent(indent) << "'inputs': [\n"; // Write everything that should be considered an input for dependency @@ -79,13 +79,13 @@ void GypScriptTargetWriter::WriteActionInputs(int indent) { Indent(indent) << "],\n"; } -void GypScriptTargetWriter::WriteActionOutputs(int indent) { +void GypActionTargetWriter::WriteActionOutputs(int indent) { Indent(indent) << "'outputs': [\n"; const Target::FileList& sources = target_->sources(); if (sources.empty()) { // Just write outputs directly if there are no sources. - const Target::FileList& output = target_->script_values().outputs(); + const Target::FileList& output = target_->action_values().outputs(); for (size_t output_i = 0; output_i < output.size(); output_i++) { Indent(indent + kExtraIndent) << "'"; path_output_.WriteFile(out_, output[output_i]); diff --git a/tools/gn/gyp_script_target_writer.h b/tools/gn/gyp_action_target_writer.h index 9f277f1..1ef3a7c 100644 --- a/tools/gn/gyp_script_target_writer.h +++ b/tools/gn/gyp_action_target_writer.h @@ -2,21 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef TOOLS_GN_GYP_SCRIPT_TARGET_WRITER_H_ -#define TOOLS_GN_GYP_SCRIPT_TARGET_WRITER_H_ +#ifndef TOOLS_GN_GYP_ACTION_TARGET_WRITER_H_ +#define TOOLS_GN_GYP_ACTION_TARGET_WRITER_H_ #include "base/compiler_specific.h" #include "tools/gn/gyp_target_writer.h" #include "tools/gn/target.h" #include "tools/gn/toolchain.h" -class GypScriptTargetWriter : public GypTargetWriter { +class GypActionTargetWriter : public GypTargetWriter { public: - GypScriptTargetWriter(const TargetGroup& group, + GypActionTargetWriter(const TargetGroup& group, const Toolchain* toolchain, const SourceDir& gyp_dir, std::ostream& out); - virtual ~GypScriptTargetWriter(); + virtual ~GypActionTargetWriter(); virtual void Run() OVERRIDE; @@ -24,7 +24,7 @@ class GypScriptTargetWriter : public GypTargetWriter { void WriteActionInputs(int indent); void WriteActionOutputs(int indent); - DISALLOW_COPY_AND_ASSIGN(GypScriptTargetWriter); + DISALLOW_COPY_AND_ASSIGN(GypActionTargetWriter); }; -#endif // TOOLS_GN_GYP_SCRIPT_TARGET_WRITER_H_ +#endif // TOOLS_GN_GYP_ACTION_TARGET_WRITER_H_ diff --git a/tools/gn/gyp_script_target_writer_unittest.cc b/tools/gn/gyp_action_target_writer_unittest.cc index ed07a5f..14c2930 100644 --- a/tools/gn/gyp_script_target_writer_unittest.cc +++ b/tools/gn/gyp_action_target_writer_unittest.cc @@ -4,20 +4,20 @@ #include "testing/gtest/include/gtest/gtest.h" #include "tools/gn/builder_record.h" -#include "tools/gn/gyp_script_target_writer.h" +#include "tools/gn/gyp_action_target_writer.h" #include "tools/gn/test_with_scope.h" -TEST(GypScriptTargetWriter, Run) { +TEST(GypActionTargetWriter, Run) { TestWithScope setup; setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); scoped_ptr<Target> target( new Target(setup.settings(), Label(SourceDir("//foo/"), "bar"))); - target->set_output_type(Target::CUSTOM); + target->set_output_type(Target::ACTION); target->sources().push_back(SourceFile("//foo/input1.txt")); target->sources().push_back(SourceFile("//foo/input2.txt")); - target->script_values().outputs().push_back( + target->action_values().outputs().push_back( SourceFile("//out/Debug/{{source_file_part}}.out")); BuilderRecord record(BuilderRecord::ITEM_TARGET, target->label()); @@ -28,7 +28,7 @@ TEST(GypScriptTargetWriter, Run) { setup.settings()->set_target_os(Settings::WIN); std::ostringstream out; - GypScriptTargetWriter writer(group, setup.toolchain(), + GypActionTargetWriter writer(group, setup.toolchain(), SourceDir("//out/gn_gyp/"), out); writer.Run(); diff --git a/tools/gn/gyp_target_writer.cc b/tools/gn/gyp_target_writer.cc index 0f362d4..789b6b0 100644 --- a/tools/gn/gyp_target_writer.cc +++ b/tools/gn/gyp_target_writer.cc @@ -11,8 +11,8 @@ #include "tools/gn/build_settings.h" #include "tools/gn/builder_record.h" #include "tools/gn/filesystem_utils.h" +#include "tools/gn/gyp_action_target_writer.h" #include "tools/gn/gyp_binary_target_writer.h" -#include "tools/gn/gyp_script_target_writer.h" #include "tools/gn/scheduler.h" #include "tools/gn/settings.h" #include "tools/gn/target.h" @@ -77,8 +77,9 @@ void GypTargetWriter::WriteFile(const SourceFile& gyp_file, switch (cur->output_type()) { case Target::COPY_FILES: break; // TODO(brettw) - case Target::CUSTOM: { - GypScriptTargetWriter writer(targets[i], debug_toolchain, + case Target::ACTION: + case Target::ACTION_FOREACH: { + GypActionTargetWriter writer(targets[i], debug_toolchain, gyp_file.GetDir(), file); writer.Run(); break; diff --git a/tools/gn/ninja_script_target_writer.cc b/tools/gn/ninja_action_target_writer.cc index f2004e3..fef58ac 100644 --- a/tools/gn/ninja_script_target_writer.cc +++ b/tools/gn/ninja_action_target_writer.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "tools/gn/ninja_script_target_writer.h" +#include "tools/gn/ninja_action_target_writer.h" #include "base/strings/string_util.h" #include "tools/gn/err.h" @@ -10,7 +10,7 @@ #include "tools/gn/string_utils.h" #include "tools/gn/target.h" -NinjaScriptTargetWriter::NinjaScriptTargetWriter(const Target* target, +NinjaActionTargetWriter::NinjaActionTargetWriter(const Target* target, const Toolchain* toolchain, std::ostream& out) : NinjaTargetWriter(target, toolchain, out), @@ -19,30 +19,32 @@ NinjaScriptTargetWriter::NinjaScriptTargetWriter(const Target* target, ESCAPE_NONE, false) { } -NinjaScriptTargetWriter::~NinjaScriptTargetWriter() { +NinjaActionTargetWriter::~NinjaActionTargetWriter() { } -void NinjaScriptTargetWriter::Run() { - FileTemplate args_template(target_->script_values().args()); +void NinjaActionTargetWriter::Run() { + FileTemplate args_template(target_->action_values().args()); std::string custom_rule_name = WriteRuleDefinition(args_template); std::string implicit_deps = GetSourcesImplicitDeps(); // Collects all output files for writing below. std::vector<OutputFile> output_files; - if (has_sources()) { + if (target_->output_type() == Target::ACTION_FOREACH) { // Write separate build lines for each input source file. WriteSourceRules(custom_rule_name, implicit_deps, args_template, &output_files); } else { - // No sources, write a rule that invokes the script once with the - // outputs as outputs, and the data as inputs. + DCHECK(target_->output_type() == Target::ACTION); + + // Write a rule that invokes the script once with the outputs as outputs, + // and the data as inputs. out_ << "build"; - if (target_->script_values().has_depfile()) { + if (target_->action_values().has_depfile()) { out_ << " "; WriteDepfile(SourceFile()); } - const Target::FileList& outputs = target_->script_values().outputs(); + const Target::FileList& outputs = target_->action_values().outputs(); for (size_t i = 0; i < outputs.size(); i++) { OutputFile output_path( RemovePrefix(outputs[i].value(), @@ -51,8 +53,21 @@ void NinjaScriptTargetWriter::Run() { out_ << " "; path_output_.WriteFile(out_, output_path); } - out_ << ": " << custom_rule_name << implicit_deps << std::endl; - if (target_->script_values().has_depfile()) { + + out_ << ": " << custom_rule_name << implicit_deps; + + // In the case of running the script once, we allow you to write the input + // dependencies in both sources and source_prereqs. source_prereqs are + // already in the implicit deps written above, but the sources aren't + // (since treating the sources this was is unique to an action). + const Target::FileList& sources = target_->sources(); + for (size_t i = 0; i < sources.size(); i++) { + out_ << " "; + path_output_.WriteFile(out_, sources[i]); + } + out_ << std::endl; + + if (target_->action_values().has_depfile()) { out_ << " depfile = "; WriteDepfile(SourceFile()); out_ << std::endl; @@ -63,7 +78,7 @@ void NinjaScriptTargetWriter::Run() { WriteStamp(output_files); } -std::string NinjaScriptTargetWriter::WriteRuleDefinition( +std::string NinjaActionTargetWriter::WriteRuleDefinition( const FileTemplate& args_template) { // Make a unique name for this rule. // @@ -90,7 +105,7 @@ std::string NinjaScriptTargetWriter::WriteRuleDefinition( // python without requiring this gyp_win_tool thing. out_ << " gyp-win-tool action-wrapper environment.x86 " << rspfile << std::endl; - out_ << " description = CUSTOM " << target_label << std::endl; + out_ << " description = ACTION " << target_label << std::endl; out_ << " restat = 1" << std::endl; out_ << " rspfile = " << rspfile << std::endl; @@ -98,7 +113,7 @@ std::string NinjaScriptTargetWriter::WriteRuleDefinition( out_ << " rspfile_content = "; path_output_.WriteFile(out_, settings_->build_settings()->python_path()); out_ << " "; - path_output_.WriteFile(out_, target_->script_values().script()); + path_output_.WriteFile(out_, target_->action_values().script()); args_template.WriteWithNinjaExpansions(out_); out_ << std::endl; } else { @@ -107,10 +122,10 @@ std::string NinjaScriptTargetWriter::WriteRuleDefinition( out_ << " command = "; path_output_.WriteFile(out_, settings_->build_settings()->python_path()); out_ << " "; - path_output_.WriteFile(out_, target_->script_values().script()); + path_output_.WriteFile(out_, target_->action_values().script()); args_template.WriteWithNinjaExpansions(out_); out_ << std::endl; - out_ << " description = CUSTOM " << target_label << std::endl; + out_ << " description = ACTION " << target_label << std::endl; out_ << " restat = 1" << std::endl; } @@ -118,7 +133,7 @@ std::string NinjaScriptTargetWriter::WriteRuleDefinition( return custom_rule_name; } -void NinjaScriptTargetWriter::WriteArgsSubstitutions( +void NinjaActionTargetWriter::WriteArgsSubstitutions( const SourceFile& source, const FileTemplate& args_template) { std::ostringstream source_file_stream; @@ -132,7 +147,7 @@ void NinjaScriptTargetWriter::WriteArgsSubstitutions( out_, source_file_stream.str(), template_escape_options); } -void NinjaScriptTargetWriter::WriteSourceRules( +void NinjaActionTargetWriter::WriteSourceRules( const std::string& custom_rule_name, const std::string& implicit_deps, const FileTemplate& args_template, @@ -155,7 +170,7 @@ void NinjaScriptTargetWriter::WriteSourceRules( if (args_template.has_substitutions()) WriteArgsSubstitutions(sources[i], args_template); - if (target_->script_values().has_depfile()) { + if (target_->action_values().has_depfile()) { out_ << " depfile = "; WriteDepfile(sources[i]); out_ << std::endl; @@ -163,7 +178,7 @@ void NinjaScriptTargetWriter::WriteSourceRules( } } -void NinjaScriptTargetWriter::WriteStamp( +void NinjaActionTargetWriter::WriteStamp( const std::vector<OutputFile>& output_files) { out_ << "build "; path_output_.WriteFile(out_, helper_.GetTargetOutputFile(target_)); @@ -177,13 +192,13 @@ void NinjaScriptTargetWriter::WriteStamp( out_ << std::endl; } -void NinjaScriptTargetWriter::WriteOutputFilesForBuildLine( +void NinjaActionTargetWriter::WriteOutputFilesForBuildLine( const FileTemplate& output_template, const SourceFile& source, std::vector<OutputFile>* output_files) { // If there is a depfile specified we need to list it as the first output as // that is what ninja will expect the depfile to refer to itself as. - if (target_->script_values().has_depfile()) { + if (target_->action_values().has_depfile()) { out_ << " "; WriteDepfile(source); } @@ -197,16 +212,16 @@ void NinjaScriptTargetWriter::WriteOutputFilesForBuildLine( } } -void NinjaScriptTargetWriter::WriteDepfile(const SourceFile& source) { +void NinjaActionTargetWriter::WriteDepfile(const SourceFile& source) { std::vector<std::string> result; GetDepfileTemplate().ApplyString(source.value(), &result); path_output_.WriteFile(out_, OutputFile(result[0])); } -FileTemplate NinjaScriptTargetWriter::GetDepfileTemplate() const { +FileTemplate NinjaActionTargetWriter::GetDepfileTemplate() const { std::vector<std::string> template_args; std::string depfile_relative_to_build_dir = - RemovePrefix(target_->script_values().depfile().value(), + RemovePrefix(target_->action_values().depfile().value(), settings_->build_settings()->build_dir().value()); template_args.push_back(depfile_relative_to_build_dir); return FileTemplate(template_args); diff --git a/tools/gn/ninja_script_target_writer.h b/tools/gn/ninja_action_target_writer.h index e32a4a6..e5ece40 100644 --- a/tools/gn/ninja_script_target_writer.h +++ b/tools/gn/ninja_action_target_writer.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef TOOLS_GN_NINJA_SCRIPT_TARGET_WRITER_H_ -#define TOOLS_GN_NINJA_SCRIPT_TARGET_WRITER_H_ +#ifndef TOOLS_GN_NINJA_ACTION_TARGET_WRITER_H_ +#define TOOLS_GN_NINJA_ACTION_TARGET_WRITER_H_ #include <vector> @@ -14,22 +14,22 @@ class FileTemplate; class OutputFile; -// Writes a .ninja file for a custom script target type. -class NinjaScriptTargetWriter : public NinjaTargetWriter { +// Writes a .ninja file for a action target type. +class NinjaActionTargetWriter : public NinjaTargetWriter { public: - NinjaScriptTargetWriter(const Target* target, + NinjaActionTargetWriter(const Target* target, const Toolchain* toolchain, std::ostream& out); - virtual ~NinjaScriptTargetWriter(); + virtual ~NinjaActionTargetWriter(); virtual void Run() OVERRIDE; private: - FRIEND_TEST_ALL_PREFIXES(NinjaScriptTargetWriter, + FRIEND_TEST_ALL_PREFIXES(NinjaActionTargetWriter, WriteOutputFilesForBuildLine); - FRIEND_TEST_ALL_PREFIXES(NinjaScriptTargetWriter, + FRIEND_TEST_ALL_PREFIXES(NinjaActionTargetWriter, WriteOutputFilesForBuildLineWithDepfile); - FRIEND_TEST_ALL_PREFIXES(NinjaScriptTargetWriter, + FRIEND_TEST_ALL_PREFIXES(NinjaActionTargetWriter, WriteArgsSubstitutions); bool has_sources() const { return !target_->sources().empty(); } @@ -77,7 +77,7 @@ class NinjaScriptTargetWriter : public NinjaTargetWriter { // computing intermediate strings. PathOutput path_output_no_escaping_; - DISALLOW_COPY_AND_ASSIGN(NinjaScriptTargetWriter); + DISALLOW_COPY_AND_ASSIGN(NinjaActionTargetWriter); }; -#endif // TOOLS_GN_NINJA_SCRIPT_TARGET_WRITER_H_ +#endif // TOOLS_GN_NINJA_ACTION_TARGET_WRITER_H_ diff --git a/tools/gn/ninja_script_target_writer_unittest.cc b/tools/gn/ninja_action_target_writer_unittest.cc index 6319dff..c1aa6f4 100644 --- a/tools/gn/ninja_script_target_writer_unittest.cc +++ b/tools/gn/ninja_action_target_writer_unittest.cc @@ -7,21 +7,21 @@ #include "testing/gtest/include/gtest/gtest.h" #include "tools/gn/file_template.h" -#include "tools/gn/ninja_script_target_writer.h" +#include "tools/gn/ninja_action_target_writer.h" #include "tools/gn/test_with_scope.h" -TEST(NinjaScriptTargetWriter, WriteOutputFilesForBuildLine) { +TEST(NinjaActionTargetWriter, WriteOutputFilesForBuildLine) { TestWithScope setup; setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); - target.script_values().outputs().push_back( + target.action_values().outputs().push_back( SourceFile("//out/Debug/gen/a b{{source_name_part}}.h")); - target.script_values().outputs().push_back( + target.action_values().outputs().push_back( SourceFile("//out/Debug/gen/{{source_name_part}}.cc")); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); FileTemplate output_template = writer.GetOutputTemplate(); @@ -36,20 +36,20 @@ TEST(NinjaScriptTargetWriter, WriteOutputFilesForBuildLine) { EXPECT_EQ(" gen/a$ bbar.h gen/bar.cc", out_str); } -TEST(NinjaScriptTargetWriter, WriteOutputFilesForBuildLineWithDepfile) { +TEST(NinjaActionTargetWriter, WriteOutputFilesForBuildLineWithDepfile) { TestWithScope setup; setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); - target.script_values().set_depfile( + target.action_values().set_depfile( SourceFile("//out/Debug/gen/{{source_name_part}}.d")); - target.script_values().outputs().push_back( + target.action_values().outputs().push_back( SourceFile("//out/Debug/gen/{{source_name_part}}.h")); - target.script_values().outputs().push_back( + target.action_values().outputs().push_back( SourceFile("//out/Debug/gen/{{source_name_part}}.cc")); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); FileTemplate output_template = writer.GetOutputTemplate(); @@ -64,13 +64,13 @@ TEST(NinjaScriptTargetWriter, WriteOutputFilesForBuildLineWithDepfile) { EXPECT_EQ(" gen/bar.d gen/bar.h gen/bar.cc", out_str); } -TEST(NinjaScriptTargetWriter, WriteArgsSubstitutions) { +TEST(NinjaActionTargetWriter, WriteArgsSubstitutions) { TestWithScope setup; setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); std::vector<std::string> args; args.push_back("-i"); @@ -88,24 +88,100 @@ TEST(NinjaScriptTargetWriter, WriteArgsSubstitutions) { out_str); } -// Tests the "run script over multiple source files" mode. -TEST(NinjaScriptTargetWriter, InvokeOverSources) { +// Makes sure that we write sources as input dependencies for actions with +// both sources and source_prereqs (ACTION_FOREACH treats the sources +// differently). +TEST(NinjaActionTargetWriter, ActionWithSources) { TestWithScope setup; setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); - target.set_output_type(Target::CUSTOM); + target.set_output_type(Target::ACTION); + + target.action_values().set_script(SourceFile("//foo/script.py")); + + target.sources().push_back(SourceFile("//foo/source.txt")); + target.source_prereqs().push_back(SourceFile("//foo/included.txt")); + + target.action_values().outputs().push_back( + SourceFile("//out/Debug/foo.out")); + + // Posix. + { + setup.settings()->set_target_os(Settings::LINUX); + setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( + "/usr/bin/python"))); + + std::ostringstream out; + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); + writer.Run(); + + const char expected_linux[] = + "rule __foo_bar___rule\n" + " command = /usr/bin/python ../../foo/script.py\n" + " description = ACTION //foo:bar()\n" + " restat = 1" + "\n" + "\n" + "build foo.out: __foo_bar___rule | ../../foo/included.txt ../../foo/source.txt\n" + "\n" + "build obj/foo/bar.stamp: stamp foo.out\n"; + std::string out_str = out.str(); +#if defined(OS_WIN) + std::replace(out_str.begin(), out_str.end(), '\\', '/'); +#endif + EXPECT_EQ(expected_linux, out_str); + } + + // Windows. + { + // Note: we use forward slashes here so that the output will be the same on + // Linux and Windows. + setup.build_settings()->set_python_path(base::FilePath(FILE_PATH_LITERAL( + "C:/python/python.exe"))); + setup.settings()->set_target_os(Settings::WIN); + + std::ostringstream out; + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); + writer.Run(); + + // TODO(brettw) I think we'll need to worry about backslashes here + // depending if we're on actual Windows or Linux pretending to be Windows. + const char expected_win[] = + "rule __foo_bar___rule\n" + " command = C:/python/python.exe gyp-win-tool action-wrapper environment.x86 __foo_bar___rule.$unique_name.rsp\n" + " description = ACTION //foo:bar()\n" + " restat = 1\n" + " rspfile = __foo_bar___rule.$unique_name.rsp\n" + " rspfile_content = C:/python/python.exe ../../foo/script.py\n" + "\n" + "build foo.out: __foo_bar___rule | ../../foo/included.txt ../../foo/source.txt\n" + "\n" + "build obj/foo/bar.stamp: stamp foo.out\n"; + std::string out_str = out.str(); +#if defined(OS_WIN) + std::replace(out_str.begin(), out_str.end(), '\\', '/'); +#endif + EXPECT_EQ(expected_win, out_str); + } +} + +TEST(NinjaActionTargetWriter, ForEach) { + TestWithScope setup; + setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); + Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); + target.set_output_type(Target::ACTION_FOREACH); target.sources().push_back(SourceFile("//foo/input1.txt")); target.sources().push_back(SourceFile("//foo/input2.txt")); - target.script_values().set_script(SourceFile("//foo/script.py")); + target.action_values().set_script(SourceFile("//foo/script.py")); - target.script_values().args().push_back("-i"); - target.script_values().args().push_back("{{source}}"); - target.script_values().args().push_back( + target.action_values().args().push_back("-i"); + target.action_values().args().push_back("{{source}}"); + target.action_values().args().push_back( "--out=foo bar{{source_name_part}}.o"); - target.script_values().outputs().push_back( + target.action_values().outputs().push_back( SourceFile("//out/Debug/{{source_name_part}}.out")); target.source_prereqs().push_back(SourceFile("//foo/included.txt")); @@ -117,14 +193,14 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { "/usr/bin/python"))); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); const char expected_linux[] = "rule __foo_bar___rule\n" " command = /usr/bin/python ../../foo/script.py -i ${source} " "\"--out=foo$ bar${source_name_part}.o\"\n" - " description = CUSTOM //foo:bar()\n" + " description = ACTION //foo:bar()\n" " restat = 1\n" "\n" "build input1.out: __foo_bar___rule ../../foo/input1.txt | " @@ -154,7 +230,7 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { setup.settings()->set_target_os(Settings::WIN); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); // TODO(brettw) I think we'll need to worry about backslashes here @@ -163,7 +239,7 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { "rule __foo_bar___rule\n" " command = C:/python/python.exe gyp-win-tool action-wrapper " "environment.x86 __foo_bar___rule.$unique_name.rsp\n" - " description = CUSTOM //foo:bar()\n" + " description = ACTION //foo:bar()\n" " restat = 1\n" " rspfile = __foo_bar___rule.$unique_name.rsp\n" " rspfile_content = C:/python/python.exe ../../foo/script.py -i " @@ -189,26 +265,25 @@ TEST(NinjaScriptTargetWriter, InvokeOverSources) { } } -// Tests the "run script over multiple source files" mode, with a depfile. -TEST(NinjaScriptTargetWriter, InvokeOverSourcesWithDepfile) { +TEST(NinjaActionTargetWriter, ForEachWithDepfile) { TestWithScope setup; setup.build_settings()->SetBuildDir(SourceDir("//out/Debug/")); Target target(setup.settings(), Label(SourceDir("//foo/"), "bar")); - target.set_output_type(Target::CUSTOM); + target.set_output_type(Target::ACTION_FOREACH); target.sources().push_back(SourceFile("//foo/input1.txt")); target.sources().push_back(SourceFile("//foo/input2.txt")); - target.script_values().set_script(SourceFile("//foo/script.py")); - target.script_values().set_depfile( + target.action_values().set_script(SourceFile("//foo/script.py")); + target.action_values().set_depfile( SourceFile("//out/Debug/gen/{{source_name_part}}.d")); - target.script_values().args().push_back("-i"); - target.script_values().args().push_back("{{source}}"); - target.script_values().args().push_back( + target.action_values().args().push_back("-i"); + target.action_values().args().push_back("{{source}}"); + target.action_values().args().push_back( "--out=foo bar{{source_name_part}}.o"); - target.script_values().outputs().push_back( + target.action_values().outputs().push_back( SourceFile("//out/Debug/{{source_name_part}}.out")); target.source_prereqs().push_back(SourceFile("//foo/included.txt")); @@ -220,14 +295,14 @@ TEST(NinjaScriptTargetWriter, InvokeOverSourcesWithDepfile) { "/usr/bin/python"))); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); const char expected_linux[] = "rule __foo_bar___rule\n" " command = /usr/bin/python ../../foo/script.py -i ${source} " "\"--out=foo$ bar${source_name_part}.o\"\n" - " description = CUSTOM //foo:bar()\n" + " description = ACTION //foo:bar()\n" " restat = 1\n" "\n" "build gen/input1.d input1.out: __foo_bar___rule ../../foo/input1.txt" @@ -259,7 +334,7 @@ TEST(NinjaScriptTargetWriter, InvokeOverSourcesWithDepfile) { setup.settings()->set_target_os(Settings::WIN); std::ostringstream out; - NinjaScriptTargetWriter writer(&target, setup.toolchain(), out); + NinjaActionTargetWriter writer(&target, setup.toolchain(), out); writer.Run(); // TODO(brettw) I think we'll need to worry about backslashes here @@ -268,7 +343,7 @@ TEST(NinjaScriptTargetWriter, InvokeOverSourcesWithDepfile) { "rule __foo_bar___rule\n" " command = C:/python/python.exe gyp-win-tool action-wrapper " "environment.x86 __foo_bar___rule.$unique_name.rsp\n" - " description = CUSTOM //foo:bar()\n" + " description = ACTION //foo:bar()\n" " restat = 1\n" " rspfile = __foo_bar___rule.$unique_name.rsp\n" " rspfile_content = C:/python/python.exe ../../foo/script.py -i " diff --git a/tools/gn/ninja_copy_target_writer.cc b/tools/gn/ninja_copy_target_writer.cc index 89b3e3f..9ab88e4 100644 --- a/tools/gn/ninja_copy_target_writer.cc +++ b/tools/gn/ninja_copy_target_writer.cc @@ -18,7 +18,7 @@ NinjaCopyTargetWriter::~NinjaCopyTargetWriter() { } void NinjaCopyTargetWriter::Run() { - CHECK(target_->script_values().outputs().size() == 1); + CHECK(target_->action_values().outputs().size() == 1); FileTemplate output_template(GetOutputTemplate()); std::vector<OutputFile> output_files; diff --git a/tools/gn/ninja_copy_target_writer_unittest.cc b/tools/gn/ninja_copy_target_writer_unittest.cc index 5642d9d..b86508b 100644 --- a/tools/gn/ninja_copy_target_writer_unittest.cc +++ b/tools/gn/ninja_copy_target_writer_unittest.cc @@ -19,7 +19,7 @@ TEST(NinjaCopyTargetWriter, Run) { target.sources().push_back(SourceFile("//foo/input1.txt")); target.sources().push_back(SourceFile("//foo/input2.txt")); - target.script_values().outputs().push_back( + target.action_values().outputs().push_back( SourceFile("//out/Debug/{{source_name_part}}.out")); // Posix. diff --git a/tools/gn/ninja_helper.cc b/tools/gn/ninja_helper.cc index eddab213..849ec4d 100644 --- a/tools/gn/ninja_helper.cc +++ b/tools/gn/ninja_helper.cc @@ -135,7 +135,8 @@ OutputFile NinjaHelper::GetTargetOutputFile(const Target* target) const { if (target->output_type() == Target::GROUP || target->output_type() == Target::SOURCE_SET || target->output_type() == Target::COPY_FILES || - target->output_type() == Target::CUSTOM) { + target->output_type() == Target::ACTION || + target->output_type() == Target::ACTION_FOREACH) { extension = "stamp"; } else { extension = GetExtensionForOutputType(target->output_type(), diff --git a/tools/gn/ninja_target_writer.cc b/tools/gn/ninja_target_writer.cc index adb1108..905f91f 100644 --- a/tools/gn/ninja_target_writer.cc +++ b/tools/gn/ninja_target_writer.cc @@ -10,10 +10,10 @@ #include "base/file_util.h" #include "tools/gn/err.h" #include "tools/gn/file_template.h" +#include "tools/gn/ninja_action_target_writer.h" #include "tools/gn/ninja_binary_target_writer.h" #include "tools/gn/ninja_copy_target_writer.h" #include "tools/gn/ninja_group_target_writer.h" -#include "tools/gn/ninja_script_target_writer.h" #include "tools/gn/scheduler.h" #include "tools/gn/string_utils.h" #include "tools/gn/target.h" @@ -61,8 +61,9 @@ void NinjaTargetWriter::RunAndWriteFile(const Target* target, if (target->output_type() == Target::COPY_FILES) { NinjaCopyTargetWriter writer(target, toolchain, file); writer.Run(); - } else if (target->output_type() == Target::CUSTOM) { - NinjaScriptTargetWriter writer(target, toolchain, file); + } else if (target->output_type() == Target::ACTION || + target->output_type() == Target::ACTION_FOREACH) { + NinjaActionTargetWriter writer(target, toolchain, file); writer.Run(); } else if (target->output_type() == Target::GROUP) { NinjaGroupTargetWriter writer(target, toolchain, file); @@ -110,7 +111,7 @@ std::string NinjaTargetWriter::GetSourcesImplicitDeps() const { } FileTemplate NinjaTargetWriter::GetOutputTemplate() const { - const Target::FileList& outputs = target_->script_values().outputs(); + const Target::FileList& outputs = target_->action_values().outputs(); std::vector<std::string> output_template_args; for (size_t i = 0; i < outputs.size(); i++) { // All outputs should be in the output dir. diff --git a/tools/gn/script_target_generator.cc b/tools/gn/script_target_generator.cc deleted file mode 100644 index 8f414f4..0000000 --- a/tools/gn/script_target_generator.cc +++ /dev/null @@ -1,95 +0,0 @@ -// 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/script_target_generator.h" - -#include "tools/gn/build_settings.h" -#include "tools/gn/err.h" -#include "tools/gn/filesystem_utils.h" -#include "tools/gn/parse_tree.h" -#include "tools/gn/scope.h" -#include "tools/gn/value.h" -#include "tools/gn/value_extractors.h" -#include "tools/gn/variables.h" - -ScriptTargetGenerator::ScriptTargetGenerator( - Target* target, - Scope* scope, - const FunctionCallNode* function_call, - Err* err) - : TargetGenerator(target, scope, function_call, err) { -} - -ScriptTargetGenerator::~ScriptTargetGenerator() { -} - -void ScriptTargetGenerator::DoRun() { - target_->set_output_type(Target::CUSTOM); - - FillExternal(); - if (err_->has_error()) - return; - - FillSources(); - if (err_->has_error()) - return; - - FillSourcePrereqs(); - if (err_->has_error()) - return; - - FillScript(); - if (err_->has_error()) - return; - - FillScriptArgs(); - if (err_->has_error()) - return; - - FillOutputs(); - if (err_->has_error()) - return; - - FillDepfile(); - if (err_->has_error()) - return; - - // Script outputs don't depend on the current toolchain so we can skip adding - // that dependency. -} - -void ScriptTargetGenerator::FillScript() { - // If this gets called, the target type requires a script, so error out - // if it doesn't have one. - const Value* value = scope_->GetValue(variables::kScript, true); - if (!value) { - *err_ = Err(function_call_, "This target type requires a \"script\"."); - return; - } - if (!value->VerifyTypeIs(Value::STRING, err_)) - return; - - target_->script_values().set_script( - scope_->GetSourceDir().ResolveRelativeFile(value->string_value())); -} - -void ScriptTargetGenerator::FillScriptArgs() { - const Value* value = scope_->GetValue(variables::kArgs, true); - if (!value) - return; - - std::vector<std::string> args; - if (!ExtractListOfStringValues(*value, &args, err_)) - return; - target_->script_values().swap_in_args(&args); -} - -void ScriptTargetGenerator::FillDepfile() { - const Value* value = scope_->GetValue(variables::kDepfile, true); - if (!value) - return; - target_->script_values().set_depfile( - scope_->settings()->build_settings()->build_dir().ResolveRelativeFile( - value->string_value())); -} diff --git a/tools/gn/script_target_generator.h b/tools/gn/script_target_generator.h deleted file mode 100644 index 4d79e51..0000000 --- a/tools/gn/script_target_generator.h +++ /dev/null @@ -1,31 +0,0 @@ -// 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. - -#ifndef TOOLS_GN_SCRIPT_TARGET_GENERATOR_H_ -#define TOOLS_GN_SCRIPT_TARGET_GENERATOR_H_ - -#include "base/compiler_specific.h" -#include "tools/gn/target_generator.h" - -// Populates a Target with the values from a custom script rule. -class ScriptTargetGenerator : public TargetGenerator { - public: - ScriptTargetGenerator(Target* target, - Scope* scope, - const FunctionCallNode* function_call, - Err* err); - virtual ~ScriptTargetGenerator(); - - protected: - virtual void DoRun() OVERRIDE; - - private: - void FillScript(); - void FillScriptArgs(); - void FillDepfile(); - - DISALLOW_COPY_AND_ASSIGN(ScriptTargetGenerator); -}; - -#endif // TOOLS_GN_SCRIPT_TARGET_GENERATOR_H_ diff --git a/tools/gn/target.cc b/tools/gn/target.cc index 635c50e..56b140f 100644 --- a/tools/gn/target.cc +++ b/tools/gn/target.cc @@ -76,8 +76,10 @@ const char* Target::GetStringForOutputType(OutputType type) { return "Static library"; case COPY_FILES: return "Copy"; - case CUSTOM: - return "Custom"; + case ACTION: + return "Action"; + case ACTION_FOREACH: + return "ActionForEach"; default: return ""; } diff --git a/tools/gn/target.h b/tools/gn/target.h index 4501494..2cf0409 100644 --- a/tools/gn/target.h +++ b/tools/gn/target.h @@ -14,11 +14,11 @@ #include "base/logging.h" #include "base/strings/string_piece.h" #include "base/synchronization/lock.h" +#include "tools/gn/action_values.h" #include "tools/gn/config_values.h" #include "tools/gn/item.h" #include "tools/gn/label_ptr.h" #include "tools/gn/ordered_set.h" -#include "tools/gn/script_values.h" #include "tools/gn/source_file.h" class InputFile; @@ -35,7 +35,8 @@ class Target : public Item { STATIC_LIBRARY, SOURCE_SET, COPY_FILES, - CUSTOM, + ACTION, + ACTION_FOREACH, }; typedef std::vector<SourceFile> FileList; typedef std::vector<std::string> StringVector; @@ -131,8 +132,8 @@ class Target : public Item { ConfigValues& config_values() { return config_values_; } const ConfigValues& config_values() const { return config_values_; } - ScriptValues& script_values() { return script_values_; } - const ScriptValues& script_values() const { return script_values_; } + ActionValues& action_values() { return action_values_; } + const ActionValues& action_values() const { return action_values_; } const OrderedSet<SourceDir>& all_lib_dirs() const { return all_lib_dirs_; } const OrderedSet<std::string>& all_libs() const { return all_libs_; } @@ -187,7 +188,7 @@ class Target : public Item { OrderedSet<std::string> all_libs_; ConfigValues config_values_; // Used for all binary targets. - ScriptValues script_values_; // Used for script (CUSTOM) targets. + ActionValues action_values_; // Used for action[_foreach] targets. SourceFile gyp_file_; diff --git a/tools/gn/target_generator.cc b/tools/gn/target_generator.cc index 81c4394..2fb178a 100644 --- a/tools/gn/target_generator.cc +++ b/tools/gn/target_generator.cc @@ -4,6 +4,7 @@ #include "tools/gn/target_generator.h" +#include "tools/gn/action_target_generator.h" #include "tools/gn/binary_target_generator.h" #include "tools/gn/build_settings.h" #include "tools/gn/config.h" @@ -15,7 +16,6 @@ #include "tools/gn/parse_tree.h" #include "tools/gn/scheduler.h" #include "tools/gn/scope.h" -#include "tools/gn/script_target_generator.h" #include "tools/gn/token.h" #include "tools/gn/value.h" #include "tools/gn/value_extractors.h" @@ -75,8 +75,13 @@ void TargetGenerator::GenerateTarget(Scope* scope, if (output_type == functions::kCopy) { CopyTargetGenerator generator(target.get(), scope, function_call, err); generator.Run(); - } else if (output_type == functions::kCustom) { - ScriptTargetGenerator generator(target.get(), scope, function_call, err); + } else if (output_type == functions::kAction) { + ActionTargetGenerator generator(target.get(), scope, function_call, + Target::ACTION, err); + generator.Run(); + } else if (output_type == functions::kActionForEach) { + ActionTargetGenerator generator(target.get(), scope, function_call, + Target::ACTION_FOREACH, err); generator.Run(); } else if (output_type == functions::kExecutable) { BinaryTargetGenerator generator(target.get(), scope, function_call, @@ -215,7 +220,7 @@ void TargetGenerator::FillOutputs() { outputs[i].value(), value->list_value()[i], err_)) return; } - target_->script_values().outputs().swap(outputs); + target_->action_values().outputs().swap(outputs); } void TargetGenerator::FillGenericConfigs(const char* var_name, diff --git a/tools/gn/variables.cc b/tools/gn/variables.cc index b05e818..8fac840 100644 --- a/tools/gn/variables.cc +++ b/tools/gn/variables.cc @@ -181,7 +181,7 @@ const char kRootOutDir_Help[] = "\n" "Example:\n" "\n" - " custom(\"myscript\") {\n" + " action(\"myscript\") {\n" " # Pass the output dir to the script.\n" " args = [ \"-o\", rebase_path(root_out_dir, root_build_dir) ]\n" " }\n"; @@ -206,7 +206,7 @@ const char kTargetGenDir_Help[] = "\n" "Example:\n" "\n" - " custom(\"myscript\") {\n" + " action(\"myscript\") {\n" " # Pass the generated output dir to the script.\n" " args = [ \"-o\", rebase_path(target_gen_dir, root_build_dir) ]" "\n" @@ -232,7 +232,7 @@ const char kTargetOutDir_Help[] = "\n" "Example:\n" "\n" - " custom(\"myscript\") {\n" + " action(\"myscript\") {\n" " # Pass the output dir to the script.\n" " args = [ \"-o\", rebase_path(target_out_dir, root_build_dir) ]" "\n" @@ -263,15 +263,15 @@ const char kAllDependentConfigs_Help[] = const char kArgs[] = "args"; const char kArgs_HelpShort[] = - "args: [string list] Arguments passed to a custom script."; + "args: [string list] Arguments passed to an action."; const char kArgs_Help[] = - "args: Arguments passed to a custom script.\n" + "args: Arguments passed to an action.\n" "\n" - " For custom script targets, args is the list of arguments to pass\n" - " to the script. Typically you would use source expansion (see\n" + " For action and action_foreach targets, args is the list of arguments\n" + " to pass to the script. Typically you would use source expansion (see\n" " \"gn help source_expansion\") to insert the source file names.\n" "\n" - " See also \"gn help custom\".\n"; + " See also \"gn help action\" and \"gn help action_foreach\".\n"; const char kCflags[] = "cflags"; const char kCflags_HelpShort[] = @@ -398,25 +398,25 @@ const char kDefines_Help[] = const char kDepfile[] = "depfile"; const char kDepfile_HelpShort[] = - "depfile: [string] File name for input dependencies for custom targets."; + "depfile: [string] File name for input dependencies for actions."; const char kDepfile_Help[] = - "depfile: [string] File name for input dependencies for custom targets.\n" + "depfile: [string] File name for input dependencies for actions.\n" "\n" - " If nonempty, this string specifies that the current \"custom\" target\n" - " will generate the given \".d\" file containing the dependencies of the\n" - " input. Empty or unset means that the script doesn't generate the\n" - " files.\n" + " If nonempty, this string specifies that the current action or\n" + " action_foreach target will generate the given \".d\" file containing\n" + " the dependencies of the input. Empty or unset means that the script\n" + " doesn't generate the files.\n" "\n" " The .d file should go in the target output directory. If you have more\n" " than one source file that the script is being run over, you can use\n" - " the output file expansions described in \"gn help custom\" to name the\n" - " .d file according to the input." + " the output file expansions described in \"gn help action_foreach\" to\n" + " name the .d file according to the input." "\n" " The format is that of a Makefile, and all of the paths should be\n" " relative to the root build directory.\n" "\n" "Example:\n" - " custom(\"myscript_target\") {\n" + " action_foreach(\"myscript_target\") {\n" " script = \"myscript.py\"\n" " sources = [ ... ]\n" "\n" @@ -438,9 +438,9 @@ const char kDeps_Help[] = "\n" " Specifies dependencies of a target. Shared and dynamic libraries will\n" " be linked into the current target. Other target types that can't be\n" - " linked (like custom scripts and groups) listed in \"deps\" will be\n" - " treated as \"datadeps\". Likewise, if the current target isn't\n" - " linkable, then all deps will be treated as \"datadeps\".\n" + " linked (like actions and groups) listed in \"deps\" will be treated\n" + " as \"datadeps\". Likewise, if the current target isn't linkable, then\n" + " all deps will be treated as \"datadeps\".\n" "\n" " See also \"datadeps\".\n"; @@ -578,7 +578,7 @@ const char kHardDep_Help[] = " ...\n" " }\n" "\n" - " custom(\"myresource\") {\n" + " action(\"myresource\") {\n" " hard_dep = true\n" " script = \"my_generator.py\"\n" " outputs = \"$target_gen_dir/myresource.h\"\n" @@ -708,27 +708,28 @@ const char kOutputName_Help[] = const char kOutputs[] = "outputs"; const char kOutputs_HelpShort[] = - "outputs: [file list] Output files for custom script and copy targets."; + "outputs: [file list] Output files for actions and copy targets."; const char kOutputs_Help[] = - "outputs: Output files for custom script and copy targets.\n" + "outputs: Output files for actions and copy targets.\n" "\n" - " Outputs is valid for \"copy\" and \"custom\" target types and\n" - " indicates the resulting files. The values may contain source\n" - " expansions to generate the output names from the sources (see\n" + " Outputs is valid for \"copy\", \"action\", and \"action_foreach\"\n" + " target types and indicates the resulting files. The values may contain\n" + " source expansions to generate the output names from the sources (see\n" " \"gn help source_expansion\").\n" "\n" " For copy targets, the outputs is the destination for the copied\n" - " file(s). For custom script targets, the outputs should be the list of\n" - " files generated by the script.\n"; + " file(s). For actions, the outputs should be the list of files\n" + " generated by the script.\n"; const char kScript[] = "script"; const char kScript_HelpShort[] = - "script: [file name] Script file for custom script targets."; + "script: [file name] Script file for actions."; const char kScript_Help[] = - "script: Script file for custom script targets.\n" + "script: Script file for actions.\n" "\n" " An absolute or buildfile-relative file name of a Python script to run\n" - " for a custom script target (see \"gn help custom\").\n"; + " for a action and action_foreach targets (see \"gn help action\" and\n" + " \"gn help action_foreach\").\n"; const char kSourcePrereqs[] = "source_prereqs"; const char kSourcePrereqs_HelpShort[] = @@ -757,7 +758,7 @@ const char kSourcePrereqs_Help[] = " the normal include file dependency management will handle them more\n" " efficiently anyway.\n" "\n" - " For custom script targets that don't generate \".d\" files, the\n" + " For action targets that don't generate \".d\" files, the\n" " \"source_prereqs\" section is how you can list known compile-time\n" " dependencies your script may have.\n" "\n" @@ -772,7 +773,7 @@ const char kSourcePrereqs_Help[] = " source_prereqs = [ \"$root_gen_dir/something/generated_data.h\" ]\n" " }\n" "\n" - " custom(\"myscript\") {\n" + " action(\"myscript\") {\n" " script = \"domything.py\"\n" " source_prereqs = [ \"input.data\" ]\n" " }\n"; |