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

Side by Side 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, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/gn/build_settings.cc ('k') | tools/gn/command_gen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include <algorithm>
6 #include <set>
7
8 #include "tools/gn/commands.h"
9 #include "tools/gn/config.h"
10 #include "tools/gn/item.h"
11 #include "tools/gn/item_node.h"
12 #include "tools/gn/label.h"
13 #include "tools/gn/setup.h"
14 #include "tools/gn/standard_out.h"
15 #include "tools/gn/target.h"
16
17 namespace {
18
19 struct CompareTargetLabel {
20 bool operator()(const Target* a, const Target* b) const {
21 return a->label() < b->label();
22 }
23 };
24
25 const Target* GetTargetForDesc(const std::vector<std::string>& args) {
26 // Deliberately leaked to avoid expensive process teardown.
27 Setup* setup = new Setup;
28 if (!setup->DoSetup())
29 return NULL;
30
31 // FIXME(brettw): set the output dir to be a sandbox one to avoid polluting
32 // the real output dir with files written by the build scripts.
33
34 // Do the actual load. This will also write out the target ninja files.
35 if (!setup->Run())
36 return NULL;
37
38 // Need to resolve the label after we know the default toolchain.
39 // TODO(brettw) find the current directory and resolve the input label
40 // relative to that.
41 Label default_toolchain = setup->build_settings().toolchain_manager()
42 .GetDefaultToolchainUnlocked();
43 Value arg_value(NULL, args[0]);
44 Err err;
45 Label label = Label::Resolve(SourceDir(), default_toolchain, arg_value, &err);
46 if (err.has_error()) {
47 err.PrintToStdout();
48 return NULL;
49 }
50
51 ItemNode* node;
52 {
53 base::AutoLock lock(setup->build_settings().item_tree().lock());
54 node = setup->build_settings().item_tree().GetExistingNodeLocked(label);
55 }
56 if (!node) {
57 Err(Location(), "",
58 "I don't know about this \"" + label.GetUserVisibleName(false) +
59 "\"").PrintToStdout();
60 return NULL;
61 }
62
63 const Target* target = node->item()->AsTarget();
64 if (!target) {
65 Err(Location(), "Not a target.",
66 "The \"" + label.GetUserVisibleName(false) + "\" thing\n"
67 "is not a target. Somebody should probably implement this command for "
68 "other\nitem types.");
69 return NULL;
70 }
71
72 return target;
73 }
74
75 void RecursiveCollectDeps(const Target* target, std::set<Label>* result) {
76 if (result->find(target->label()) != result->end())
77 return; // Already did this target.
78 result->insert(target->label());
79
80 const std::vector<const Target*>& deps = target->deps();
81 for (size_t i = 0; i < deps.size(); i++)
82 RecursiveCollectDeps(deps[i], result);
83 }
84
85 // Prints dependencies of the given target (not the target itself).
86 void RecursivePrintDeps(const Target* target,
87 const Label& default_toolchain,
88 int indent_level) {
89 std::vector<const Target*> sorted_deps = target->deps();
90 std::sort(sorted_deps.begin(), sorted_deps.end(), CompareTargetLabel());
91
92 std::string indent(indent_level * 2, ' ');
93 for (size_t i = 0; i < sorted_deps.size(); i++) {
94 OutputString(indent +
95 sorted_deps[i]->label().GetUserVisibleName(default_toolchain) + "\n");
96 RecursivePrintDeps(sorted_deps[i], default_toolchain, indent_level + 1);
97 }
98 }
99
100 } // namespace
101
102 int RunDescCommand(const std::vector<std::string>& args) {
103 if (args.size() != 1) {
104 Err(Location(), "You're holding it wrong.",
105 "Usage: \"gn desc <target_name>\"").PrintToStdout();
106 return NULL;
107 }
108
109 const Target* target = GetTargetForDesc(args);
110 if (!target)
111 return 1;
112
113 // Generally we only want to display toolchains on labels when the toolchain
114 // is different than the default one for this target (which we always print
115 // in the header).
116 Label target_toolchain = target->label().GetToolchainLabel();
117
118 // Header.
119 std::string title_target =
120 "Target: " + target->label().GetUserVisibleName(false);
121 std::string title_toolchain =
122 "Toolchain: " + target_toolchain.GetUserVisibleName(false);
123 OutputString(title_target + "\n", DECORATION_YELLOW);
124 OutputString(title_toolchain + "\n", DECORATION_YELLOW);
125 OutputString(std::string(
126 std::max(title_target.size(), title_toolchain.size()), '=') + "\n");
127
128 OutputString("Sources:\n");
129 const Target::FileList& sources = target->sources();
130 for (size_t i = 0; i < sources.size(); i++)
131 OutputString(" " + sources[i].value() + "\n");
132
133 // Configs (don't sort since the order determines how things are processed).
134 OutputString("\nConfigs:\n");
135 const std::vector<const Config*>& configs = target->configs();
136 for (size_t i = 0; i < configs.size(); i++) {
137 OutputString(" " +
138 configs[i]->label().GetUserVisibleName(target_toolchain) + "\n");
139 }
140
141 // Deps. Sorted for convenience. Sort the labels rather than the strings so
142 // that "//foo:bar" comes before "//foo/third_party:bar".
143 OutputString("\nDirect dependencies:\n"
144 "(Use \"gn deps\" or \"gn tree\" to display recursive deps.)\n");
145 const std::vector<const Target*>& deps = target->deps();
146 std::vector<Label> sorted_deps;
147 for (size_t i = 0; i < deps.size(); i++)
148 sorted_deps.push_back(deps[i]->label());
149 std::sort(sorted_deps.begin(), sorted_deps.end());
150 for (size_t i = 0; i < sorted_deps.size(); i++) {
151 OutputString(" " + sorted_deps[i].GetUserVisibleName(target_toolchain) +
152 "\n");
153 }
154 return 0;
155 }
156
157 int RunDepsCommand(const std::vector<std::string>& args) {
158 if (args.size() != 1) {
159 Err(Location(), "You're holding it wrong.",
160 "Usage: \"gn deps <target_name>\"").PrintToStdout();
161 return NULL;
162 }
163
164 const Target* target = GetTargetForDesc(args);
165 if (!target)
166 return 1;
167
168 // Generally we only want to display toolchains on labels when the toolchain
169 // is different than the default one for this target (which we always print
170 // in the header).
171 Label target_toolchain = target->label().GetToolchainLabel();
172
173 std::set<Label> all_deps;
174 RecursiveCollectDeps(target, &all_deps);
175
176 OutputString("Recursive dependencies of " +
177 target->label().GetUserVisibleName(true) + "\n",
178 DECORATION_YELLOW);
179
180 for (std::set<Label>::iterator i = all_deps.begin();
181 i != all_deps.end(); ++i)
182 OutputString(" " + i->GetUserVisibleName(target_toolchain) + "\n");
183 return 0;
184 }
185
186 int RunTreeCommand(const std::vector<std::string>& args) {
187 if (args.size() != 1) {
188 Err(Location(), "You're holding it wrong.",
189 "Usage: \"gn tree <target_name>\"").PrintToStdout();
190 return NULL;
191 }
192
193 const Target* target = GetTargetForDesc(args);
194 if (!target)
195 return 1;
196
197 OutputString(target->label().GetUserVisibleName(false) + "\n");
198 RecursivePrintDeps(target, target->label().GetToolchainLabel(), 1);
199
200 return 0;
201 }
OLDNEW
« 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