Remove the now unused TextButton code.
[chromium-blink-merge.git] / tools / gn / ninja_action_target_writer.cc
blob6a632e789e32f7f0f24c69dc9f89c8d75a7f5b6c
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.
5 #include "tools/gn/ninja_action_target_writer.h"
7 #include "base/strings/string_util.h"
8 #include "tools/gn/err.h"
9 #include "tools/gn/file_template.h"
10 #include "tools/gn/string_utils.h"
11 #include "tools/gn/target.h"
13 NinjaActionTargetWriter::NinjaActionTargetWriter(const Target* target,
14 const Toolchain* toolchain,
15 std::ostream& out)
16 : NinjaTargetWriter(target, toolchain, out),
17 path_output_no_escaping_(
18 target->settings()->build_settings()->build_dir(),
19 ESCAPE_NONE) {
22 NinjaActionTargetWriter::~NinjaActionTargetWriter() {
25 void NinjaActionTargetWriter::Run() {
26 FileTemplate args_template(target_->settings(),
27 target_->action_values().args());
28 std::string custom_rule_name = WriteRuleDefinition(args_template);
30 // Collect our deps to pass as "extra hard dependencies" for input deps. This
31 // will force all of the action's dependencies to be completed before the
32 // action is run. Usually, if an action has a dependency, it will be
33 // operating on the result of that previous step, so we need to be sure to
34 // serialize these.
35 std::vector<const Target*> extra_hard_deps;
36 for (size_t i = 0; i < target_->deps().size(); i++)
37 extra_hard_deps.push_back(target_->deps()[i].ptr);
39 // For ACTIONs this is a bit inefficient since it creates an input dep
40 // stamp file even though we're only going to use it once. It would save a
41 // build step to skip this and write the order-only deps directly on the
42 // build rule. This should probably be handled by WriteInputDepsStampAndGetDep
43 // automatically if we supply a count of sources (so it can optimize based on
44 // how many times things would be duplicated).
45 std::string implicit_deps = WriteInputDepsStampAndGetDep(extra_hard_deps);
46 out_ << std::endl;
48 // Collects all output files for writing below.
49 std::vector<OutputFile> output_files;
51 if (target_->output_type() == Target::ACTION_FOREACH) {
52 // Write separate build lines for each input source file.
53 WriteSourceRules(custom_rule_name, implicit_deps, args_template,
54 &output_files);
55 } else {
56 DCHECK(target_->output_type() == Target::ACTION);
58 // Write a rule that invokes the script once with the outputs as outputs,
59 // and the data as inputs.
60 out_ << "build";
61 const Target::FileList& outputs = target_->action_values().outputs();
62 for (size_t i = 0; i < outputs.size(); i++) {
63 OutputFile output_path(
64 RemovePrefix(outputs[i].value(),
65 settings_->build_settings()->build_dir().value()));
66 output_files.push_back(output_path);
67 out_ << " ";
68 path_output_.WriteFile(out_, output_path);
71 out_ << ": " << custom_rule_name << implicit_deps << std::endl;
72 if (target_->action_values().has_depfile()) {
73 out_ << " depfile = ";
74 WriteDepfile(SourceFile());
75 out_ << std::endl;
78 out_ << std::endl;
80 WriteStamp(output_files);
83 std::string NinjaActionTargetWriter::WriteRuleDefinition(
84 const FileTemplate& args_template) {
85 // Make a unique name for this rule.
87 // Use a unique name for the response file when there are multiple build
88 // steps so that they don't stomp on each other. When there are no sources,
89 // there will be only one invocation so we can use a simple name.
90 std::string target_label = target_->label().GetUserVisibleName(true);
91 std::string custom_rule_name(target_label);
92 base::ReplaceChars(custom_rule_name, ":/()", "_", &custom_rule_name);
93 custom_rule_name.append("_rule");
95 if (settings_->IsWin()) {
96 // Send through gyp-win-tool and use a response file.
97 std::string rspfile = custom_rule_name;
98 if (has_sources())
99 rspfile += ".$unique_name";
100 rspfile += ".rsp";
102 out_ << "rule " << custom_rule_name << std::endl;
103 out_ << " command = ";
104 path_output_.WriteFile(out_, settings_->build_settings()->python_path());
105 // TODO(brettw) this hardcodes "environment.x86" which is something that
106 // the Chrome Windows toolchain writes. We should have a way to invoke
107 // python without requiring this gyp_win_tool thing.
108 out_ << " gyp-win-tool action-wrapper environment.x86 " << rspfile
109 << std::endl;
110 out_ << " description = ACTION " << target_label << std::endl;
111 out_ << " restat = 1" << std::endl;
112 out_ << " rspfile = " << rspfile << std::endl;
114 // The build command goes in the rsp file.
115 out_ << " rspfile_content = ";
116 path_output_.WriteFile(out_, settings_->build_settings()->python_path());
117 out_ << " ";
118 path_output_.WriteFile(out_, target_->action_values().script());
119 args_template.WriteWithNinjaExpansions(out_);
120 out_ << std::endl;
121 } else {
122 // Posix can execute Python directly.
123 out_ << "rule " << custom_rule_name << std::endl;
124 out_ << " command = ";
125 path_output_.WriteFile(out_, settings_->build_settings()->python_path());
126 out_ << " ";
127 path_output_.WriteFile(out_, target_->action_values().script());
128 args_template.WriteWithNinjaExpansions(out_);
129 out_ << std::endl;
130 out_ << " description = ACTION " << target_label << std::endl;
131 out_ << " restat = 1" << std::endl;
134 return custom_rule_name;
137 void NinjaActionTargetWriter::WriteArgsSubstitutions(
138 const SourceFile& source,
139 const FileTemplate& args_template) {
140 EscapeOptions template_escape_options;
141 template_escape_options.mode = ESCAPE_NINJA_COMMAND;
143 args_template.WriteNinjaVariablesForSubstitution(
144 out_, target_->settings(), source, template_escape_options);
147 void NinjaActionTargetWriter::WriteSourceRules(
148 const std::string& custom_rule_name,
149 const std::string& implicit_deps,
150 const FileTemplate& args_template,
151 std::vector<OutputFile>* output_files) {
152 FileTemplate output_template(GetOutputTemplate());
154 const Target::FileList& sources = target_->sources();
155 for (size_t i = 0; i < sources.size(); i++) {
156 out_ << "build";
157 WriteOutputFilesForBuildLine(output_template, sources[i], output_files);
159 out_ << ": " << custom_rule_name << " ";
160 path_output_.WriteFile(out_, sources[i]);
161 out_ << implicit_deps << std::endl;
163 // Windows needs a unique ID for the response file.
164 if (target_->settings()->IsWin())
165 out_ << " unique_name = " << i << std::endl;
167 if (args_template.has_substitutions())
168 WriteArgsSubstitutions(sources[i], args_template);
170 if (target_->action_values().has_depfile()) {
171 out_ << " depfile = ";
172 WriteDepfile(sources[i]);
173 out_ << std::endl;
178 void NinjaActionTargetWriter::WriteStamp(
179 const std::vector<OutputFile>& output_files) {
180 out_ << "build ";
181 path_output_.WriteFile(out_, helper_.GetTargetOutputFile(target_));
182 out_ << ": "
183 << helper_.GetRulePrefix(target_->settings())
184 << "stamp";
186 // The action stamp depends on all output files from running the action.
187 for (size_t i = 0; i < output_files.size(); i++) {
188 out_ << " ";
189 path_output_.WriteFile(out_, output_files[i]);
192 // It also depends on all datadeps. These are needed at runtime and should
193 // be compiled when the action is, but don't need to be done before we run
194 // the action.
195 for (size_t i = 0; i < target_->datadeps().size(); i++) {
196 out_ << " ";
197 path_output_.WriteFile(out_,
198 helper_.GetTargetOutputFile(target_->datadeps()[i].ptr));
201 out_ << std::endl;
204 void NinjaActionTargetWriter::WriteOutputFilesForBuildLine(
205 const FileTemplate& output_template,
206 const SourceFile& source,
207 std::vector<OutputFile>* output_files) {
208 std::vector<std::string> output_template_result;
209 output_template.Apply(source, &output_template_result);
210 for (size_t out_i = 0; out_i < output_template_result.size(); out_i++) {
211 OutputFile output_path(output_template_result[out_i]);
212 output_files->push_back(output_path);
213 out_ << " ";
214 path_output_.WriteFile(out_, output_path);
218 void NinjaActionTargetWriter::WriteDepfile(const SourceFile& source) {
219 std::vector<std::string> result;
220 GetDepfileTemplate().Apply(source, &result);
221 path_output_.WriteFile(out_, OutputFile(result[0]));
224 FileTemplate NinjaActionTargetWriter::GetDepfileTemplate() const {
225 std::vector<std::string> template_args;
226 std::string depfile_relative_to_build_dir =
227 RemovePrefix(target_->action_values().depfile().value(),
228 settings_->build_settings()->build_dir().value());
229 template_args.push_back(depfile_relative_to_build_dir);
230 return FileTemplate(settings_, template_args);