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

Unified Diff: tools/gn/command_desc.cc

Issue 21114002: Add initial prototype for the GN meta-buildsystem. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add owners and readme Created 7 years, 5 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/build_settings.cc ('k') | tools/gn/command_gen.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/gn/command_desc.cc
diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc
new file mode 100644
index 0000000000000000000000000000000000000000..bf91776c73fd491ca8f784f8a03cc34ce4d15a49
--- /dev/null
+++ b/tools/gn/command_desc.cc
@@ -0,0 +1,201 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+#include <set>
+
+#include "tools/gn/commands.h"
+#include "tools/gn/config.h"
+#include "tools/gn/item.h"
+#include "tools/gn/item_node.h"
+#include "tools/gn/label.h"
+#include "tools/gn/setup.h"
+#include "tools/gn/standard_out.h"
+#include "tools/gn/target.h"
+
+namespace {
+
+struct CompareTargetLabel {
+ bool operator()(const Target* a, const Target* b) const {
+ return a->label() < b->label();
+ }
+};
+
+const Target* GetTargetForDesc(const std::vector<std::string>& args) {
+ // Deliberately leaked to avoid expensive process teardown.
+ Setup* setup = new Setup;
+ if (!setup->DoSetup())
+ return NULL;
+
+ // FIXME(brettw): set the output dir to be a sandbox one to avoid polluting
+ // the real output dir with files written by the build scripts.
+
+ // Do the actual load. This will also write out the target ninja files.
+ if (!setup->Run())
+ return NULL;
+
+ // Need to resolve the label after we know the default toolchain.
+ // TODO(brettw) find the current directory and resolve the input label
+ // relative to that.
+ Label default_toolchain = setup->build_settings().toolchain_manager()
+ .GetDefaultToolchainUnlocked();
+ Value arg_value(NULL, args[0]);
+ Err err;
+ Label label = Label::Resolve(SourceDir(), default_toolchain, arg_value, &err);
+ if (err.has_error()) {
+ err.PrintToStdout();
+ return NULL;
+ }
+
+ ItemNode* node;
+ {
+ base::AutoLock lock(setup->build_settings().item_tree().lock());
+ node = setup->build_settings().item_tree().GetExistingNodeLocked(label);
+ }
+ if (!node) {
+ Err(Location(), "",
+ "I don't know about this \"" + label.GetUserVisibleName(false) +
+ "\"").PrintToStdout();
+ return NULL;
+ }
+
+ const Target* target = node->item()->AsTarget();
+ if (!target) {
+ Err(Location(), "Not a target.",
+ "The \"" + label.GetUserVisibleName(false) + "\" thing\n"
+ "is not a target. Somebody should probably implement this command for "
+ "other\nitem types.");
+ return NULL;
+ }
+
+ return target;
+}
+
+void RecursiveCollectDeps(const Target* target, std::set<Label>* result) {
+ if (result->find(target->label()) != result->end())
+ return; // Already did this target.
+ result->insert(target->label());
+
+ const std::vector<const Target*>& deps = target->deps();
+ for (size_t i = 0; i < deps.size(); i++)
+ RecursiveCollectDeps(deps[i], result);
+}
+
+// Prints dependencies of the given target (not the target itself).
+void RecursivePrintDeps(const Target* target,
+ const Label& default_toolchain,
+ int indent_level) {
+ std::vector<const Target*> sorted_deps = target->deps();
+ std::sort(sorted_deps.begin(), sorted_deps.end(), CompareTargetLabel());
+
+ std::string indent(indent_level * 2, ' ');
+ for (size_t i = 0; i < sorted_deps.size(); i++) {
+ OutputString(indent +
+ sorted_deps[i]->label().GetUserVisibleName(default_toolchain) + "\n");
+ RecursivePrintDeps(sorted_deps[i], default_toolchain, indent_level + 1);
+ }
+}
+
+} // namespace
+
+int RunDescCommand(const std::vector<std::string>& args) {
+ if (args.size() != 1) {
+ Err(Location(), "You're holding it wrong.",
+ "Usage: \"gn desc <target_name>\"").PrintToStdout();
+ return NULL;
+ }
+
+ const Target* target = GetTargetForDesc(args);
+ if (!target)
+ return 1;
+
+ // Generally we only want to display toolchains on labels when the toolchain
+ // is different than the default one for this target (which we always print
+ // in the header).
+ Label target_toolchain = target->label().GetToolchainLabel();
+
+ // Header.
+ std::string title_target =
+ "Target: " + target->label().GetUserVisibleName(false);
+ std::string title_toolchain =
+ "Toolchain: " + target_toolchain.GetUserVisibleName(false);
+ OutputString(title_target + "\n", DECORATION_YELLOW);
+ OutputString(title_toolchain + "\n", DECORATION_YELLOW);
+ OutputString(std::string(
+ std::max(title_target.size(), title_toolchain.size()), '=') + "\n");
+
+ OutputString("Sources:\n");
+ const Target::FileList& sources = target->sources();
+ for (size_t i = 0; i < sources.size(); i++)
+ OutputString(" " + sources[i].value() + "\n");
+
+ // Configs (don't sort since the order determines how things are processed).
+ OutputString("\nConfigs:\n");
+ const std::vector<const Config*>& configs = target->configs();
+ for (size_t i = 0; i < configs.size(); i++) {
+ OutputString(" " +
+ configs[i]->label().GetUserVisibleName(target_toolchain) + "\n");
+ }
+
+ // Deps. Sorted for convenience. Sort the labels rather than the strings so
+ // that "//foo:bar" comes before "//foo/third_party:bar".
+ OutputString("\nDirect dependencies:\n"
+ "(Use \"gn deps\" or \"gn tree\" to display recursive deps.)\n");
+ const std::vector<const Target*>& deps = target->deps();
+ std::vector<Label> sorted_deps;
+ for (size_t i = 0; i < deps.size(); i++)
+ sorted_deps.push_back(deps[i]->label());
+ std::sort(sorted_deps.begin(), sorted_deps.end());
+ for (size_t i = 0; i < sorted_deps.size(); i++) {
+ OutputString(" " + sorted_deps[i].GetUserVisibleName(target_toolchain) +
+ "\n");
+ }
+ return 0;
+}
+
+int RunDepsCommand(const std::vector<std::string>& args) {
+ if (args.size() != 1) {
+ Err(Location(), "You're holding it wrong.",
+ "Usage: \"gn deps <target_name>\"").PrintToStdout();
+ return NULL;
+ }
+
+ const Target* target = GetTargetForDesc(args);
+ if (!target)
+ return 1;
+
+ // Generally we only want to display toolchains on labels when the toolchain
+ // is different than the default one for this target (which we always print
+ // in the header).
+ Label target_toolchain = target->label().GetToolchainLabel();
+
+ std::set<Label> all_deps;
+ RecursiveCollectDeps(target, &all_deps);
+
+ OutputString("Recursive dependencies of " +
+ target->label().GetUserVisibleName(true) + "\n",
+ DECORATION_YELLOW);
+
+ for (std::set<Label>::iterator i = all_deps.begin();
+ i != all_deps.end(); ++i)
+ OutputString(" " + i->GetUserVisibleName(target_toolchain) + "\n");
+ return 0;
+}
+
+int RunTreeCommand(const std::vector<std::string>& args) {
+ if (args.size() != 1) {
+ Err(Location(), "You're holding it wrong.",
+ "Usage: \"gn tree <target_name>\"").PrintToStdout();
+ return NULL;
+ }
+
+ const Target* target = GetTargetForDesc(args);
+ if (!target)
+ return 1;
+
+ OutputString(target->label().GetUserVisibleName(false) + "\n");
+ RecursivePrintDeps(target, target->label().GetToolchainLabel(), 1);
+
+ return 0;
+}
« no previous file with comments | « tools/gn/build_settings.cc ('k') | tools/gn/command_gen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698