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 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |