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

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

Issue 2485523002: gn: Make generation of main build.ninja file deterministic. (Closed)
Patch Set: linux Created 4 years, 1 month 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_build_writer.h ('k') | tools/gn/ninja_build_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_build_writer.h" 5 #include "tools/gn/ninja_build_writer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <fstream> 9 #include <fstream>
10 #include <map> 10 #include <map>
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 "\nCollisions:\n" + matches_string); 127 "\nCollisions:\n" + matches_string);
128 for (size_t i = 1; i < matches.size(); i++) 128 for (size_t i = 1; i < matches.size(); i++)
129 result.AppendSubErr(Err(matches[i]->defined_from(), "Collision.")); 129 result.AppendSubErr(Err(matches[i]->defined_from(), "Collision."));
130 return result; 130 return result;
131 } 131 }
132 132
133 } // namespace 133 } // namespace
134 134
135 NinjaBuildWriter::NinjaBuildWriter( 135 NinjaBuildWriter::NinjaBuildWriter(
136 const BuildSettings* build_settings, 136 const BuildSettings* build_settings,
137 const std::map<const Settings*, const Toolchain*>& used_toolchains, 137 const std::unordered_map<const Settings*, const Toolchain*>&
138 used_toolchains,
138 const Toolchain* default_toolchain, 139 const Toolchain* default_toolchain,
139 const std::vector<const Target*>& default_toolchain_targets, 140 const std::vector<const Target*>& default_toolchain_targets,
140 std::ostream& out, 141 std::ostream& out,
141 std::ostream& dep_out) 142 std::ostream& dep_out)
142 : build_settings_(build_settings), 143 : build_settings_(build_settings),
143 used_toolchains_(used_toolchains), 144 used_toolchains_(used_toolchains),
144 default_toolchain_(default_toolchain), 145 default_toolchain_(default_toolchain),
145 default_toolchain_targets_(default_toolchain_targets), 146 default_toolchain_targets_(default_toolchain_targets),
146 out_(out), 147 out_(out),
147 dep_out_(dep_out), 148 dep_out_(dep_out),
(...skipping 12 matching lines...) Expand all
160 } 161 }
161 162
162 // static 163 // static
163 bool NinjaBuildWriter::RunAndWriteFile( 164 bool NinjaBuildWriter::RunAndWriteFile(
164 const BuildSettings* build_settings, 165 const BuildSettings* build_settings,
165 const Builder& builder, 166 const Builder& builder,
166 Err* err) { 167 Err* err) {
167 ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, "build.ninja"); 168 ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, "build.ninja");
168 169
169 std::vector<const Target*> all_targets = builder.GetAllResolvedTargets(); 170 std::vector<const Target*> all_targets = builder.GetAllResolvedTargets();
170 std::map<const Settings*, const Toolchain*> used_toolchains; 171 std::unordered_map<const Settings*, const Toolchain*> used_toolchains;
171 172
172 // Find the default toolchain info. 173 // Find the default toolchain info.
173 Label default_toolchain_label = builder.loader()->GetDefaultToolchain(); 174 Label default_toolchain_label = builder.loader()->GetDefaultToolchain();
174 const Settings* default_toolchain_settings = 175 const Settings* default_toolchain_settings =
175 builder.loader()->GetToolchainSettings(default_toolchain_label); 176 builder.loader()->GetToolchainSettings(default_toolchain_label);
176 const Toolchain* default_toolchain = 177 const Toolchain* default_toolchain =
177 builder.GetToolchain(default_toolchain_label); 178 builder.GetToolchain(default_toolchain_label);
178 179
179 // Most targets will be in the default toolchain. Add it at the beginning and 180 // Most targets will be in the default toolchain. Add it at the beginning and
180 // skip adding it to the list every time in the loop. 181 // skip adding it to the list every time in the loop.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 fileset.insert(other_files.begin(), other_files.end()); 254 fileset.insert(other_files.begin(), other_files.end());
254 255
255 for (const auto& other_file : fileset) 256 for (const auto& other_file : fileset)
256 dep_out_ << " " << FilePathToUTF8(other_file); 257 dep_out_ << " " << FilePathToUTF8(other_file);
257 258
258 out_ << std::endl; 259 out_ << std::endl;
259 } 260 }
260 261
261 void NinjaBuildWriter::WriteAllPools() { 262 void NinjaBuildWriter::WriteAllPools() {
262 // Compute the pools referenced by all tools of all used toolchains. 263 // Compute the pools referenced by all tools of all used toolchains.
263 std::set<const Pool*> used_pools; 264 std::unordered_set<const Pool*> used_pools;
264 for (const auto& pair : used_toolchains_) { 265 for (const auto& pair : used_toolchains_) {
265 for (int j = Toolchain::TYPE_NONE + 1; j < Toolchain::TYPE_NUMTYPES; j++) { 266 for (int j = Toolchain::TYPE_NONE + 1; j < Toolchain::TYPE_NUMTYPES; j++) {
266 Toolchain::ToolType tool_type = static_cast<Toolchain::ToolType>(j); 267 Toolchain::ToolType tool_type = static_cast<Toolchain::ToolType>(j);
267 const Tool* tool = pair.second->GetTool(tool_type); 268 const Tool* tool = pair.second->GetTool(tool_type);
268 if (tool && tool->pool().ptr) 269 if (tool && tool->pool().ptr)
269 used_pools.insert(tool->pool().ptr); 270 used_pools.insert(tool->pool().ptr);
270 } 271 }
271 } 272 }
272 273
273 for (const Pool* pool : used_pools) { 274 // Write pools sorted by their name, to make output deterministic.
274 std::string pool_name = pool->GetNinjaName(default_toolchain_->label()); 275 std::vector<const Pool*> sorted_pools(used_pools.begin(), used_pools.end());
275 out_ << "pool " << pool_name << std::endl 276 auto pool_name = [this](const Pool* pool) {
277 return pool->GetNinjaName(default_toolchain_->label());
278 };
279 std::sort(sorted_pools.begin(), sorted_pools.end(),
280 [&pool_name](const Pool* a, const Pool* b) {
281 return pool_name(a) < pool_name(b);
282 });
283 for (const Pool* pool : sorted_pools) {
284 out_ << "pool " << pool_name(pool) << std::endl
276 << " depth = " << pool->depth() << std::endl 285 << " depth = " << pool->depth() << std::endl
277 << std::endl; 286 << std::endl;
278 } 287 }
279 } 288 }
280 289
281 void NinjaBuildWriter::WriteSubninjas() { 290 void NinjaBuildWriter::WriteSubninjas() {
282 for (const auto& pair : used_toolchains_) { 291 // Write toolchains sorted by their name, to make output deterministic.
292 std::vector<std::pair<const Settings*, const Toolchain*>> sorted_settings(
293 used_toolchains_.begin(), used_toolchains_.end());
294 std::sort(sorted_settings.begin(), sorted_settings.end(),
295 [this](const std::pair<const Settings*, const Toolchain*>& a,
296 const std::pair<const Settings*, const Toolchain*>& b) {
297 // Always put the default toolchain first.
298 if (b.second == default_toolchain_)
299 return false;
300 if (a.second == default_toolchain_)
301 return true;
302 return GetNinjaFileForToolchain(a.first) <
303 GetNinjaFileForToolchain(b.first);
304 });
305 for (const auto& pair : sorted_settings) {
283 out_ << "subninja "; 306 out_ << "subninja ";
284 path_output_.WriteFile(out_, GetNinjaFileForToolchain(pair.first)); 307 path_output_.WriteFile(out_, GetNinjaFileForToolchain(pair.first));
285 out_ << std::endl; 308 out_ << std::endl;
286 } 309 }
287 out_ << std::endl; 310 out_ << std::endl;
288 } 311 }
289 312
290 bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) { 313 bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) {
291 // Track rules as we generate them so we don't accidentally write a phony 314 // Track rules as we generate them so we don't accidentally write a phony
292 // rule that collides with something else. 315 // rule that collides with something else.
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 EscapeOptions ninja_escape; 474 EscapeOptions ninja_escape;
452 ninja_escape.mode = ESCAPE_NINJA; 475 ninja_escape.mode = ESCAPE_NINJA;
453 476
454 // Escape for special chars Ninja will handle. 477 // Escape for special chars Ninja will handle.
455 std::string escaped = EscapeString(phony_name, ninja_escape, nullptr); 478 std::string escaped = EscapeString(phony_name, ninja_escape, nullptr);
456 479
457 out_ << "build " << escaped << ": phony "; 480 out_ << "build " << escaped << ": phony ";
458 path_output_.WriteFile(out_, target->dependency_output_file()); 481 path_output_.WriteFile(out_, target->dependency_output_file());
459 out_ << std::endl; 482 out_ << std::endl;
460 } 483 }
OLDNEW
« no previous file with comments | « tools/gn/ninja_build_writer.h ('k') | tools/gn/ninja_build_writer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698