Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(73)

Side by Side Diff: tools/gn/ninja_binary_target_writer.cc

Issue 505353002: Reduce input dependencies in GN. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/gn/ninja_action_target_writer.cc ('k') | tools/gn/ninja_binary_target_writer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "tools/gn/ninja_binary_target_writer.h" 5 #include "tools/gn/ninja_binary_target_writer.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/strings/string_util.h" 9 #include "base/strings/string_util.h"
10 #include "tools/gn/config_values_extractors.h" 10 #include "tools/gn/config_values_extractors.h"
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 #undef WRITE_FLAGS 120 #undef WRITE_FLAGS
121 121
122 WriteSharedVars(subst); 122 WriteSharedVars(subst);
123 } 123 }
124 124
125 void NinjaBinaryTargetWriter::WriteSources( 125 void NinjaBinaryTargetWriter::WriteSources(
126 std::vector<OutputFile>* object_files) { 126 std::vector<OutputFile>* object_files) {
127 const Target::FileList& sources = target_->sources(); 127 const Target::FileList& sources = target_->sources();
128 object_files->reserve(sources.size()); 128 object_files->reserve(sources.size());
129 129
130 std::string implicit_deps = 130 OutputFile input_dep =
131 WriteInputDepsStampAndGetDep(std::vector<const Target*>()); 131 WriteInputDepsStampAndGetDep(std::vector<const Target*>());
132 132
133 std::string rule_prefix = GetNinjaRulePrefixForToolchain(settings_); 133 std::string rule_prefix = GetNinjaRulePrefixForToolchain(settings_);
134 134
135 std::vector<OutputFile> tool_outputs; // Prevent reallocation in loop. 135 std::vector<OutputFile> tool_outputs; // Prevent reallocation in loop.
136 for (size_t i = 0; i < sources.size(); i++) { 136 for (size_t i = 0; i < sources.size(); i++) {
137 Toolchain::ToolType tool_type = Toolchain::TYPE_NONE; 137 Toolchain::ToolType tool_type = Toolchain::TYPE_NONE;
138 if (!GetOutputFilesForSource(target_, sources[i], 138 if (!GetOutputFilesForSource(target_, sources[i],
139 &tool_type, &tool_outputs)) 139 &tool_type, &tool_outputs))
140 continue; // No output for this source. 140 continue; // No output for this source.
141 141
142 if (tool_type != Toolchain::TYPE_NONE) { 142 if (tool_type != Toolchain::TYPE_NONE) {
143 out_ << "build"; 143 out_ << "build";
144 path_output_.WriteFiles(out_, tool_outputs); 144 path_output_.WriteFiles(out_, tool_outputs);
145 out_ << ": " << rule_prefix << Toolchain::ToolTypeToName(tool_type); 145 out_ << ": " << rule_prefix << Toolchain::ToolTypeToName(tool_type);
146 out_ << " "; 146 out_ << " ";
147 path_output_.WriteFile(out_, sources[i]); 147 path_output_.WriteFile(out_, sources[i]);
148 out_ << implicit_deps << std::endl; 148 if (!input_dep.value().empty()) {
149 // Write out the input dependencies as an order-only dependency. This
150 // will cause Ninja to make sure the inputs are up-to-date before
151 // compiling this source, but changes in the inputs deps won't cause
152 // the file to be recompiled.
153 //
154 // This is important to prevent changes in unrelated actions that
155 // are upstream of this target from causing everything to be recompiled.
156 //
157 // Why can we get away with this rather than using implicit deps ("|",
158 // which will force rebuilds when the inputs change)? For source code,
159 // the computed dependencies of all headers will be computed by the
160 // compiler, which will cause source rebuilds if any "real" upstream
161 // dependencies change.
162 //
163 // If a .cc file is generated by an input dependency, Ninja will see
164 // the input to the build rule doesn't exist, and that it is an output
165 // from a previous step, and build the previous step first. This is a
166 // "real" dependency and doesn't need | or || to express.
167 //
168 // The only case where this rule matters is for the first build where
169 // no .d files exist, and Ninja doesn't know what that source file
170 // depends on. In this case it's sufficient to ensure that the upstream
171 // dependencies are built first. This is exactly what Ninja's order-
172 // only dependencies expresses.
173 out_ << " || ";
174 path_output_.WriteFile(out_, input_dep);
175 }
176 out_ << std::endl;
149 } 177 }
150 178
151 // It's theoretically possible for a compiler to produce more than one 179 // It's theoretically possible for a compiler to produce more than one
152 // output, but we'll only link to the first output. 180 // output, but we'll only link to the first output.
153 object_files->push_back(tool_outputs[0]); 181 object_files->push_back(tool_outputs[0]);
154 } 182 }
155 out_ << std::endl; 183 out_ << std::endl;
156 } 184 }
157 185
158 void NinjaBinaryTargetWriter::WriteLinkerStuff( 186 void NinjaBinaryTargetWriter::WriteLinkerStuff(
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 } 236 }
209 } 237 }
210 238
211 // Append implicit dependencies collected above. 239 // Append implicit dependencies collected above.
212 if (!implicit_deps.empty()) { 240 if (!implicit_deps.empty()) {
213 out_ << " |"; 241 out_ << " |";
214 path_output_.WriteFiles(out_, implicit_deps); 242 path_output_.WriteFiles(out_, implicit_deps);
215 } 243 }
216 244
217 // Append data dependencies as order-only dependencies. 245 // Append data dependencies as order-only dependencies.
246 //
247 // This will include data dependencies and input dependencies (like when
248 // this target depends on an action). Having the data dependencies in this
249 // list ensures that the data is available at runtime when the user builds
250 // this target.
251 //
252 // The action dependencies are not strictly necessary in this case. They
253 // should also have been collected via the input deps stamp that each source
254 // file has for an order-only dependency, and since this target depends on
255 // the sources, there is already an implicit order-only dependency. However,
256 // it's extra work to separate these out and there's no disadvantage to
257 // listing them again.
218 WriteOrderOnlyDependencies(non_linkable_deps); 258 WriteOrderOnlyDependencies(non_linkable_deps);
219 259
220 // End of the link "build" line. 260 // End of the link "build" line.
221 out_ << std::endl; 261 out_ << std::endl;
222 262
223 // These go in the inner scope of the link line. 263 // These go in the inner scope of the link line.
224 WriteLinkerFlags(); 264 WriteLinkerFlags();
225 WriteLibs(); 265 WriteLibs();
226 WriteOutputExtension(); 266 WriteOutputExtension();
227 WriteSolibs(solibs); 267 WriteSolibs(solibs);
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
429 return false; // No tool for this file (it's a header file or something). 469 return false; // No tool for this file (it's a header file or something).
430 const Tool* tool = target->toolchain()->GetTool(*computed_tool_type); 470 const Tool* tool = target->toolchain()->GetTool(*computed_tool_type);
431 if (!tool) 471 if (!tool)
432 return false; // Tool does not apply for this toolchain.file. 472 return false; // Tool does not apply for this toolchain.file.
433 473
434 // Figure out what output(s) this compiler produces. 474 // Figure out what output(s) this compiler produces.
435 SubstitutionWriter::ApplyListToCompilerAsOutputFile( 475 SubstitutionWriter::ApplyListToCompilerAsOutputFile(
436 target, source, tool->outputs(), outputs); 476 target, source, tool->outputs(), outputs);
437 return !outputs->empty(); 477 return !outputs->empty();
438 } 478 }
OLDNEW
« no previous file with comments | « tools/gn/ninja_action_target_writer.cc ('k') | tools/gn/ninja_binary_target_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698