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

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

Issue 2483713003: gn: Diag on distinct toolchains with the same name. (Closed)
Patch Set: lol msvc 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') | no next file » | 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 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 "Two or more targets generate the same output:\n " + 123 "Two or more targets generate the same output:\n " +
124 bad_output.value() + "\n\n" 124 bad_output.value() + "\n\n"
125 "This is can often be fixed by changing one of the target names, or by \n" 125 "This is can often be fixed by changing one of the target names, or by \n"
126 "setting an output_name on one of them.\n" 126 "setting an output_name on one of them.\n"
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 // Given two toolchains with the same name, generates an error message
134 // that describes the problem.
135 Err GetDuplicateToolchainError(const SourceFile& source_file,
136 const Toolchain* previous_toolchain,
137 const Toolchain* toolchain) {
138 Err result(toolchain->defined_from(), "Duplicate toolchain.",
139 "Two or more toolchains write to the same directory:\n " +
140 source_file.GetDir().value() + "\n\n"
141 "This can be fixed by making sure that distinct toolchains have\n"
142 "distinct names.\n");
143 result.AppendSubErr(
144 Err(previous_toolchain->defined_from(), "Previous toolchain."));
145 return result;
146 }
147
133 } // namespace 148 } // namespace
134 149
135 NinjaBuildWriter::NinjaBuildWriter( 150 NinjaBuildWriter::NinjaBuildWriter(
136 const BuildSettings* build_settings, 151 const BuildSettings* build_settings,
137 const std::unordered_map<const Settings*, const Toolchain*>& 152 const std::unordered_map<const Settings*, const Toolchain*>&
138 used_toolchains, 153 used_toolchains,
139 const Toolchain* default_toolchain, 154 const Toolchain* default_toolchain,
140 const std::vector<const Target*>& default_toolchain_targets, 155 const std::vector<const Target*>& default_toolchain_targets,
141 std::ostream& out, 156 std::ostream& out,
142 std::ostream& dep_out) 157 std::ostream& dep_out)
143 : build_settings_(build_settings), 158 : build_settings_(build_settings),
144 used_toolchains_(used_toolchains), 159 used_toolchains_(used_toolchains),
145 default_toolchain_(default_toolchain), 160 default_toolchain_(default_toolchain),
146 default_toolchain_targets_(default_toolchain_targets), 161 default_toolchain_targets_(default_toolchain_targets),
147 out_(out), 162 out_(out),
148 dep_out_(dep_out), 163 dep_out_(dep_out),
149 path_output_(build_settings->build_dir(), 164 path_output_(build_settings->build_dir(),
150 build_settings->root_path_utf8(), 165 build_settings->root_path_utf8(),
151 ESCAPE_NINJA) {} 166 ESCAPE_NINJA) {}
152 167
153 NinjaBuildWriter::~NinjaBuildWriter() { 168 NinjaBuildWriter::~NinjaBuildWriter() {
154 } 169 }
155 170
156 bool NinjaBuildWriter::Run(Err* err) { 171 bool NinjaBuildWriter::Run(Err* err) {
157 WriteNinjaRules(); 172 WriteNinjaRules();
158 WriteAllPools(); 173 WriteAllPools();
159 WriteSubninjas(); 174 return WriteSubninjas(err) && WritePhonyAndAllRules(err);
160 return WritePhonyAndAllRules(err);
161 } 175 }
162 176
163 // static 177 // static
164 bool NinjaBuildWriter::RunAndWriteFile( 178 bool NinjaBuildWriter::RunAndWriteFile(
165 const BuildSettings* build_settings, 179 const BuildSettings* build_settings,
166 const Builder& builder, 180 const Builder& builder,
167 Err* err) { 181 Err* err) {
168 ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, "build.ninja"); 182 ScopedTrace trace(TraceItem::TRACE_FILE_WRITE, "build.ninja");
169 183
170 std::vector<const Target*> all_targets = builder.GetAllResolvedTargets(); 184 std::vector<const Target*> all_targets = builder.GetAllResolvedTargets();
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 [&pool_name](const Pool* a, const Pool* b) { 294 [&pool_name](const Pool* a, const Pool* b) {
281 return pool_name(a) < pool_name(b); 295 return pool_name(a) < pool_name(b);
282 }); 296 });
283 for (const Pool* pool : sorted_pools) { 297 for (const Pool* pool : sorted_pools) {
284 out_ << "pool " << pool_name(pool) << std::endl 298 out_ << "pool " << pool_name(pool) << std::endl
285 << " depth = " << pool->depth() << std::endl 299 << " depth = " << pool->depth() << std::endl
286 << std::endl; 300 << std::endl;
287 } 301 }
288 } 302 }
289 303
290 void NinjaBuildWriter::WriteSubninjas() { 304 bool NinjaBuildWriter::WriteSubninjas(Err* err) {
291 // Write toolchains sorted by their name, to make output deterministic. 305 // Write toolchains sorted by their name, to make output deterministic.
292 std::vector<std::pair<const Settings*, const Toolchain*>> sorted_settings( 306 std::vector<std::pair<const Settings*, const Toolchain*>> sorted_settings(
293 used_toolchains_.begin(), used_toolchains_.end()); 307 used_toolchains_.begin(), used_toolchains_.end());
294 std::sort(sorted_settings.begin(), sorted_settings.end(), 308 std::sort(sorted_settings.begin(), sorted_settings.end(),
295 [this](const std::pair<const Settings*, const Toolchain*>& a, 309 [this](const std::pair<const Settings*, const Toolchain*>& a,
296 const std::pair<const Settings*, const Toolchain*>& b) { 310 const std::pair<const Settings*, const Toolchain*>& b) {
297 // Always put the default toolchain first. 311 // Always put the default toolchain first.
298 if (b.second == default_toolchain_) 312 if (b.second == default_toolchain_)
299 return false; 313 return false;
300 if (a.second == default_toolchain_) 314 if (a.second == default_toolchain_)
301 return true; 315 return true;
302 return GetNinjaFileForToolchain(a.first) < 316 return GetNinjaFileForToolchain(a.first) <
303 GetNinjaFileForToolchain(b.first); 317 GetNinjaFileForToolchain(b.first);
304 }); 318 });
319
320 SourceFile previous_subninja;
321 const Toolchain* previous_toolchain = nullptr;
322
305 for (const auto& pair : sorted_settings) { 323 for (const auto& pair : sorted_settings) {
324 SourceFile subninja = GetNinjaFileForToolchain(pair.first);
325
326 // Since the toolchains are sorted, comparing to the previous subninja is
327 // enough to find duplicates.
328 if (subninja == previous_subninja) {
329 *err =
330 GetDuplicateToolchainError(subninja, previous_toolchain, pair.second);
331 return false;
332 }
333
306 out_ << "subninja "; 334 out_ << "subninja ";
307 path_output_.WriteFile(out_, GetNinjaFileForToolchain(pair.first)); 335 path_output_.WriteFile(out_, subninja);
308 out_ << std::endl; 336 out_ << std::endl;
337 previous_subninja = subninja;
338 previous_toolchain = pair.second;
309 } 339 }
310 out_ << std::endl; 340 out_ << std::endl;
341 return true;
311 } 342 }
312 343
313 bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) { 344 bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) {
314 // Track rules as we generate them so we don't accidentally write a phony 345 // Track rules as we generate them so we don't accidentally write a phony
315 // rule that collides with something else. 346 // rule that collides with something else.
316 // GN internally generates an "all" target, so don't duplicate it. 347 // GN internally generates an "all" target, so don't duplicate it.
317 base::hash_set<std::string> written_rules; 348 base::hash_set<std::string> written_rules;
318 written_rules.insert("all"); 349 written_rules.insert("all");
319 350
320 // Set if we encounter a target named "//:default". 351 // Set if we encounter a target named "//:default".
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 EscapeOptions ninja_escape; 505 EscapeOptions ninja_escape;
475 ninja_escape.mode = ESCAPE_NINJA; 506 ninja_escape.mode = ESCAPE_NINJA;
476 507
477 // Escape for special chars Ninja will handle. 508 // Escape for special chars Ninja will handle.
478 std::string escaped = EscapeString(phony_name, ninja_escape, nullptr); 509 std::string escaped = EscapeString(phony_name, ninja_escape, nullptr);
479 510
480 out_ << "build " << escaped << ": phony "; 511 out_ << "build " << escaped << ": phony ";
481 path_output_.WriteFile(out_, target->dependency_output_file()); 512 path_output_.WriteFile(out_, target->dependency_output_file());
482 out_ << std::endl; 513 out_ << std::endl;
483 } 514 }
OLDNEW
« no previous file with comments | « tools/gn/ninja_build_writer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698