| 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 |