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

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

Issue 2824153002: Use $root:default as a "default" rule (Closed)
Patch Set: Code review feedback Created 3 years, 8 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/docs/reference.md ('k') | tools/gn/setup.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 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 } 342 }
343 343
344 const char kNinjaRules_Help[] = 344 const char kNinjaRules_Help[] =
345 R"(Ninja build rules 345 R"(Ninja build rules
346 346
347 The "all" and "default" rules 347 The "all" and "default" rules
348 348
349 All generated targets (see "gn help execution") will be added to an implicit 349 All generated targets (see "gn help execution") will be added to an implicit
350 build rule called "all" so "ninja all" will always compile everything. The 350 build rule called "all" so "ninja all" will always compile everything. The
351 default rule will be used by Ninja if no specific target is specified (just 351 default rule will be used by Ninja if no specific target is specified (just
352 typing "ninja"). If there is a target named "//:default" it will be the 352 typing "ninja"). If there is a target named "default" in the root build file,
353 default build rule, otherwise the implicit "all" rule will be used. 353 it will be the default build rule, otherwise the implicit "all" rule will be
354 used.
354 355
355 Phony rules 356 Phony rules
356 357
357 GN generates Ninja "phony" rules for targets in the default toolchain. The 358 GN generates Ninja "phony" rules for targets in the default toolchain. The
358 phony rules can collide with each other and with the names of generated files 359 phony rules can collide with each other and with the names of generated files
359 so are generated with the following priority: 360 so are generated with the following priority:
360 361
361 1. Actual files generated by the build always take precedence. 362 1. Actual files generated by the build always take precedence.
362 363
363 2. Targets in the toplevel //BUILD.gn file. 364 2. Targets in the toplevel //BUILD.gn file.
(...skipping 25 matching lines...) Expand all
389 )"; 390 )";
390 391
391 bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) { 392 bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) {
392 // Track rules as we generate them so we don't accidentally write a phony 393 // Track rules as we generate them so we don't accidentally write a phony
393 // rule that collides with something else. 394 // rule that collides with something else.
394 // GN internally generates an "all" target, so don't duplicate it. 395 // GN internally generates an "all" target, so don't duplicate it.
395 base::hash_set<std::string> written_rules; 396 base::hash_set<std::string> written_rules;
396 written_rules.insert("all"); 397 written_rules.insert("all");
397 398
398 // Set if we encounter a target named "//:default". 399 // Set if we encounter a target named "//:default".
399 bool default_target_exists = false; 400 const Target* default_target = nullptr;
400 401
401 // Targets in the root build file. 402 // Targets in the root build file.
402 std::vector<const Target*> toplevel_targets; 403 std::vector<const Target*> toplevel_targets;
403 404
404 // Targets with names matching their toplevel directories. For example 405 // Targets with names matching their toplevel directories. For example
405 // "//foo:foo". Expect this is the naming scheme for "big components." 406 // "//foo:foo". Expect this is the naming scheme for "big components."
406 std::vector<const Target*> toplevel_dir_targets; 407 std::vector<const Target*> toplevel_dir_targets;
407 408
408 // Tracks the number of each target with the given short name, as well 409 // Tracks the number of each target with the given short name, as well
409 // as the short names of executables (which will be a subset of short_names). 410 // as the short names of executables (which will be a subset of short_names).
410 std::map<std::string, Counts> short_names; 411 std::map<std::string, Counts> short_names;
411 std::map<std::string, Counts> exes; 412 std::map<std::string, Counts> exes;
412 413
413 // ---------------------------------------------------- 414 // ----------------------------------------------------
414 // If you change this algorithm, update the help above! 415 // If you change this algorithm, update the help above!
415 // ---------------------------------------------------- 416 // ----------------------------------------------------
416 417
417 for (const Target* target : default_toolchain_targets_) { 418 for (const Target* target : default_toolchain_targets_) {
418 const Label& label = target->label(); 419 const Label& label = target->label();
419 const std::string& short_name = label.name(); 420 const std::string& short_name = label.name();
420 421
421 if (label.dir().value() == "//" && label.name() == "default") 422 if (label.dir() == build_settings_->root_target_label().dir() &&
422 default_target_exists = true; 423 short_name == "default")
424 default_target = target;
423 425
424 // Count the number of targets with the given short name. 426 // Count the number of targets with the given short name.
425 Counts& short_names_counts = short_names[short_name]; 427 Counts& short_names_counts = short_names[short_name];
426 short_names_counts.count++; 428 short_names_counts.count++;
427 short_names_counts.last_seen = target; 429 short_names_counts.last_seen = target;
428 430
429 // Count executables with the given short name. 431 // Count executables with the given short name.
430 if (target->output_type() == Target::EXECUTABLE) { 432 if (target->output_type() == Target::EXECUTABLE) {
431 Counts& exes_counts = exes[short_name]; 433 Counts& exes_counts = exes[short_name];
432 exes_counts.count++; 434 exes_counts.count++;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 532
531 EscapeOptions ninja_escape; 533 EscapeOptions ninja_escape;
532 ninja_escape.mode = ESCAPE_NINJA; 534 ninja_escape.mode = ESCAPE_NINJA;
533 for (const Target* target : default_toolchain_targets_) { 535 for (const Target* target : default_toolchain_targets_) {
534 out_ << " $\n "; 536 out_ << " $\n ";
535 path_output_.WriteFile(out_, target->dependency_output_file()); 537 path_output_.WriteFile(out_, target->dependency_output_file());
536 } 538 }
537 } 539 }
538 out_ << std::endl; 540 out_ << std::endl;
539 541
540 if (default_target_exists) 542 if (default_target) {
541 out_ << "\ndefault default" << std::endl; 543 // Use the short name when available
542 else if (!default_toolchain_targets_.empty()) 544 if (written_rules.find("default") != written_rules.end()) {
545 out_ << "\ndefault default" << std::endl;
546 } else {
547 out_ << "\ndefault ";
548 path_output_.WriteFile(out_, default_target->dependency_output_file());
549 out_ << std::endl;
550 }
551 } else if (!default_toolchain_targets_.empty()) {
543 out_ << "\ndefault all" << std::endl; 552 out_ << "\ndefault all" << std::endl;
553 }
544 554
545 return true; 555 return true;
546 } 556 }
547 557
548 void NinjaBuildWriter::WritePhonyRule(const Target* target, 558 void NinjaBuildWriter::WritePhonyRule(const Target* target,
549 const std::string& phony_name) { 559 const std::string& phony_name) {
550 EscapeOptions ninja_escape; 560 EscapeOptions ninja_escape;
551 ninja_escape.mode = ESCAPE_NINJA; 561 ninja_escape.mode = ESCAPE_NINJA;
552 562
553 // Escape for special chars Ninja will handle. 563 // Escape for special chars Ninja will handle.
554 std::string escaped = EscapeString(phony_name, ninja_escape, nullptr); 564 std::string escaped = EscapeString(phony_name, ninja_escape, nullptr);
555 565
556 out_ << "build " << escaped << ": phony "; 566 out_ << "build " << escaped << ": phony ";
557 path_output_.WriteFile(out_, target->dependency_output_file()); 567 path_output_.WriteFile(out_, target->dependency_output_file());
558 out_ << std::endl; 568 out_ << std::endl;
559 } 569 }
OLDNEW
« no previous file with comments | « tools/gn/docs/reference.md ('k') | tools/gn/setup.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698