OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |