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

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

Issue 2504133003: Add more gn documentation (Closed)
Patch Set: 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') | tools/gn/target.h » ('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 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 out_ << "subninja "; 334 out_ << "subninja ";
335 path_output_.WriteFile(out_, subninja); 335 path_output_.WriteFile(out_, subninja);
336 out_ << std::endl; 336 out_ << std::endl;
337 previous_subninja = subninja; 337 previous_subninja = subninja;
338 previous_toolchain = pair.second; 338 previous_toolchain = pair.second;
339 } 339 }
340 out_ << std::endl; 340 out_ << std::endl;
341 return true; 341 return true;
342 } 342 }
343 343
344 const char kNinjaRules_Help[] =
345 R"(Ninja build rules
346
347 The "all" and "default" rules
348
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
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
353 default build rule, otherwise the implicit "all" rule will be used.
354
355 Phony rules
356
357 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 so are generated with the following priority:
360
361 1. Actual files generated by the build always take precedence.
362
363 2. Targets in the toplevel //BUILD.gn file.
364
365 3. Targets in toplevel directories matching the names of the directories.
366 So "ninja foo" can be used to compile "//foo:foo". This only applies to
367 the first level of directories since usually these are the most
368 important (so this won't apply to "//foo/bar:bar").
369
370 4. The short names of executables if there is only one executable with that
371 short name. Use "ninja doom_melon" to compile the
372 "//tools/fruit:doom_melon" executable.
373
374 5. The short names of all targets if there is only one target with that
375 short name.
376
377 6. Full label name with no leading slashes. So you can use
378 "ninja tools/fruit:doom_melon" to build "//tools/fruit:doom_melon".
379
380 7. Labels with an implicit name part (when the short names match the
381 directory). So you can use "ninja foo/bar" to compile "//foo/bar:bar".
382
383 These "phony" rules are provided only for running Ninja since this matches
384 people's historical expectations for building. For consistency with the rest
385 of the program, GN introspection commands accept explicit labels.
386
387 To explicitly compile a target in a non-default toolchain, you must give
388 Ninja the exact name of the output file relative to the build directory.
389 )";
390
344 bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) { 391 bool NinjaBuildWriter::WritePhonyAndAllRules(Err* err) {
345 // Track rules as we generate them so we don't accidentally write a phony 392 // Track rules as we generate them so we don't accidentally write a phony
346 // rule that collides with something else. 393 // rule that collides with something else.
347 // GN internally generates an "all" target, so don't duplicate it. 394 // GN internally generates an "all" target, so don't duplicate it.
348 base::hash_set<std::string> written_rules; 395 base::hash_set<std::string> written_rules;
349 written_rules.insert("all"); 396 written_rules.insert("all");
350 397
351 // Set if we encounter a target named "//:default". 398 // Set if we encounter a target named "//:default".
352 bool default_target_exists = false; 399 bool default_target_exists = false;
353 400
354 // Targets in the root build file. 401 // Targets in the root build file.
355 std::vector<const Target*> toplevel_targets; 402 std::vector<const Target*> toplevel_targets;
356 403
357 // Targets with names matching their toplevel directories. For example 404 // Targets with names matching their toplevel directories. For example
358 // "//foo:foo". Expect this is the naming scheme for "big components." 405 // "//foo:foo". Expect this is the naming scheme for "big components."
359 std::vector<const Target*> toplevel_dir_targets; 406 std::vector<const Target*> toplevel_dir_targets;
360 407
361 // Tracks the number of each target with the given short name, as well 408 // Tracks the number of each target with the given short name, as well
362 // as the short names of executables (which will be a subset of short_names). 409 // as the short names of executables (which will be a subset of short_names).
363 std::map<std::string, Counts> short_names; 410 std::map<std::string, Counts> short_names;
364 std::map<std::string, Counts> exes; 411 std::map<std::string, Counts> exes;
365 412
413 // ----------------------------------------------------
414 // If you change this algorithm, update the help above!
415 // ----------------------------------------------------
416
366 for (const Target* target : default_toolchain_targets_) { 417 for (const Target* target : default_toolchain_targets_) {
367 const Label& label = target->label(); 418 const Label& label = target->label();
368 const std::string& short_name = label.name(); 419 const std::string& short_name = label.name();
369 420
370 if (label.dir().value() == "//" && label.name() == "default") 421 if (label.dir().value() == "//" && label.name() == "default")
371 default_target_exists = true; 422 default_target_exists = true;
372 423
373 // Count the number of targets with the given short name. 424 // Count the number of targets with the given short name.
374 Counts& short_names_counts = short_names[short_name]; 425 Counts& short_names_counts = short_names[short_name];
375 short_names_counts.count++; 426 short_names_counts.count++;
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 // (e.g. "//foo/bar:bar" -> "foo/bar"). 515 // (e.g. "//foo/bar:bar" -> "foo/bar").
465 if (FindLastDirComponent(label.dir()) == label.name()) { 516 if (FindLastDirComponent(label.dir()) == label.name()) {
466 std::string medium_name = DirectoryWithNoLastSlash(label.dir()); 517 std::string medium_name = DirectoryWithNoLastSlash(label.dir());
467 base::TrimString(medium_name, "/", &medium_name); 518 base::TrimString(medium_name, "/", &medium_name);
468 // That may have generated a name the same as the short name of the 519 // That may have generated a name the same as the short name of the
469 // target which we already wrote. 520 // target which we already wrote.
470 if (medium_name != label.name() && 521 if (medium_name != label.name() &&
471 written_rules.insert(medium_name).second) 522 written_rules.insert(medium_name).second)
472 WritePhonyRule(target, medium_name); 523 WritePhonyRule(target, medium_name);
473 } 524 }
474
475 // Write the short name if no other target shares that short name and
476 // non of the higher-priority rules above claimed it.
477 if (short_names[label.name()].count == 1 &&
478 written_rules.insert(label.name()).second)
479 WritePhonyRule(target, label.name());
480 } 525 }
481 526
482 // Write the autogenerated "all" rule. 527 // Write the autogenerated "all" rule.
483 if (!default_toolchain_targets_.empty()) { 528 if (!default_toolchain_targets_.empty()) {
484 out_ << "\nbuild all: phony"; 529 out_ << "\nbuild all: phony";
485 530
486 EscapeOptions ninja_escape; 531 EscapeOptions ninja_escape;
487 ninja_escape.mode = ESCAPE_NINJA; 532 ninja_escape.mode = ESCAPE_NINJA;
488 for (const Target* target : default_toolchain_targets_) { 533 for (const Target* target : default_toolchain_targets_) {
489 out_ << " $\n "; 534 out_ << " $\n ";
(...skipping 15 matching lines...) Expand all
505 EscapeOptions ninja_escape; 550 EscapeOptions ninja_escape;
506 ninja_escape.mode = ESCAPE_NINJA; 551 ninja_escape.mode = ESCAPE_NINJA;
507 552
508 // Escape for special chars Ninja will handle. 553 // Escape for special chars Ninja will handle.
509 std::string escaped = EscapeString(phony_name, ninja_escape, nullptr); 554 std::string escaped = EscapeString(phony_name, ninja_escape, nullptr);
510 555
511 out_ << "build " << escaped << ": phony "; 556 out_ << "build " << escaped << ": phony ";
512 path_output_.WriteFile(out_, target->dependency_output_file()); 557 path_output_.WriteFile(out_, target->dependency_output_file());
513 out_ << std::endl; 558 out_ << std::endl;
514 } 559 }
OLDNEW
« no previous file with comments | « tools/gn/ninja_build_writer.h ('k') | tools/gn/target.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698