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