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

Unified Diff: tools/gn/ninja_build_writer.cc

Issue 247663006: Add more phony rules to GN build (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tests Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/gn/ninja_build_writer.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/ninja_build_writer.cc
diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc
index 11b36e6b591e74a85753f2998aad2dcfe003dc36..c0fc7fcfedfd9667c26de0984cf2fca47c7f92d1 100644
--- a/tools/gn/ninja_build_writer.cc
+++ b/tools/gn/ninja_build_writer.cc
@@ -11,6 +11,7 @@
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/process/process_handle.h"
+#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "tools/gn/build_settings.h"
@@ -179,30 +180,87 @@ void NinjaBuildWriter::WritePhonyAndAllRules() {
// Write phony rules for all uniquely-named targets in the default toolchain.
// Don't do other toolchains or we'll get naming conflicts, and if the name
- // isn't unique, also skip it.
+ // isn't unique, also skip it. The exception is for the toplevel targets
+ // which we also find.
std::map<std::string, int> small_name_count;
- for (size_t i = 0; i < default_toolchain_targets_.size(); i++)
- small_name_count[default_toolchain_targets_[i]->label().name()]++;
-
+ std::vector<const Target*> toplevel_targets;
for (size_t i = 0; i < default_toolchain_targets_.size(); i++) {
const Target* target = default_toolchain_targets_[i];
+ const Label& label = target->label();
+ small_name_count[label.name()]++;
+
+ // Look for targets with a name of the form
+ // dir = "//foo/", name = "foo"
+ // i.e. where the target name matches the top level directory. We will
+ // always write phony rules for these even if there is another target with
+ // the same short name.
+ const std::string& dir_string = label.dir().value();
+ if (dir_string.size() == label.name().size() + 3 && // Size matches.
+ dir_string[0] == '/' && dir_string[1] == '/' && // "//" at beginning.
+ dir_string[dir_string.size() - 1] == '/' && // "/" at end.
+ dir_string.compare(2, label.name().size(), label.name()) == 0)
+ toplevel_targets.push_back(target);
+ }
+ for (size_t i = 0; i < default_toolchain_targets_.size(); i++) {
+ const Target* target = default_toolchain_targets_[i];
+ const Label& label = target->label();
OutputFile target_file = helper_.GetTargetOutputFile(target);
- if (target_file.value() != target->label().name() &&
- small_name_count[default_toolchain_targets_[i]->label().name()] == 1) {
- out_ << "build " << target->label().name() << ": phony ";
- path_output_.WriteFile(out_, target_file);
- out_ << std::endl;
+
+ // Write the long name "foo/bar:baz" for the target "//foo/bar:baz".
+ std::string long_name = label.GetUserVisibleName(false);
+ base::TrimString(long_name, "/", &long_name);
+ WritePhonyRule(target, target_file, long_name);
+
+ // Write the directory name with no target name if they match
+ // (e.g. "//foo/bar:bar" -> "foo/bar").
+ if (FindLastDirComponent(label.dir()) == label.name()) {
+ std::string medium_name = DirectoryWithNoLastSlash(label.dir());
+ base::TrimString(medium_name, "/", &medium_name);
+ // That may have generated a name the same as the short name of the
+ // target which we already wrote.
+ if (medium_name != label.name())
+ WritePhonyRule(target, target_file, medium_name);
}
+ // Write short names for ones which are unique.
+ if (small_name_count[label.name()] == 1)
+ WritePhonyRule(target, target_file, label.name());
+
if (!all_rules.empty())
all_rules.append(" $\n ");
all_rules.append(target_file.value());
}
+ // Pick up phony rules for the toplevel targets with non-unique names (which
+ // would have been skipped in the above loop).
+ for (size_t i = 0; i < toplevel_targets.size(); i++) {
+ if (small_name_count[toplevel_targets[i]->label().name()] > 1) {
+ const Target* target = toplevel_targets[i];
+ WritePhonyRule(target, helper_.GetTargetOutputFile(target),
+ target->label().name());
+ }
+ }
+
if (!all_rules.empty()) {
out_ << "\nbuild all: phony " << all_rules << std::endl;
out_ << "default all" << std::endl;
}
}
+void NinjaBuildWriter::WritePhonyRule(const Target* target,
+ const OutputFile& target_file,
+ const std::string& phony_name) {
+ if (target_file.value() == phony_name)
+ return; // No need for a phony rule.
+
+ EscapeOptions ninja_escape;
+ ninja_escape.mode = ESCAPE_NINJA;
+
+ // Escape for special chars Ninja will handle.
+ std::string escaped = EscapeString(phony_name, ninja_escape, NULL);
+
+ out_ << "build " << escaped << ": phony ";
+ path_output_.WriteFile(out_, target_file);
+ out_ << std::endl;
+}
« 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