Generate VS projects also for target dependencies.
This changes the way the --filters argument to
`gn gen --ide=vs --filters=X;Y;...` works so that
the information for all the dependents of X and Y will be generated
along with the information for X and Y.
This CL is based on tmoniuszko@opera.com's patch from
issue 2027733004 at patchset 1 (http://crrev.com/2027733004#ps1),
just updated w/ the review feedback, so we can land it.
R=brettw@chromium.org, pkasting@chromium.org, tmoniuszko@opera.com
BUG=589099
Review-Url: https://codereview.chromium.org/2060613002
Cr-Original-Commit-Position: refs/heads/master@{#399402}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 4ed6b5594a150bd4de269ab71dfc36d812aa6161
diff --git a/tools/gn/command_gen.cc b/tools/gn/command_gen.cc
index 7bdb6d8..3d44274 100644
--- a/tools/gn/command_gen.cc
+++ b/tools/gn/command_gen.cc
@@ -263,8 +263,8 @@
" --filters=<path_prefixes>\n"
" Semicolon-separated list of label patterns used to limit the set\n"
" of generated projects (see \"gn help label_pattern\"). Only\n"
- " matching targets will be included to the solution. Only used for\n"
- " Visual Studio and Xcode.\n"
+ " matching targets and their dependencies will be included in the\n"
+ " solution. Only used for Visual Studio and Xcode.\n"
"\n"
"Visual Studio Flags\n"
"\n"
diff --git a/tools/gn/docs/reference.md b/tools/gn/docs/reference.md
index c29b24f..4071fd9 100644
--- a/tools/gn/docs/reference.md
+++ b/tools/gn/docs/reference.md
@@ -697,8 +697,8 @@
--filters=<path_prefixes>
Semicolon-separated list of label patterns used to limit the set
of generated projects (see "gn help label_pattern"). Only
- matching targets will be included to the solution. Only used for
- Visual Studio and Xcode.
+ matching targets and their dependencies will be included in the
+ solution. Only used for Visual Studio and Xcode.
```
@@ -864,8 +864,8 @@
```
Finds paths of dependencies between two targets. Each unique path
will be printed in one group, and groups will be separate by newlines.
- The two targets can appear in either order: paths will be found going
- in either direction.
+ The two targets can appear in either order (paths will be found going
+ in either direction).
By default, a single path will be printed. If there is a path with
only public dependencies, the shortest public path will be printed.
@@ -876,13 +876,23 @@
```
+### **Interesting paths**
+
+```
+ In a large project, there can be 100's of millions of unique paths
+ between a very high level and a common low-level target. To make the
+ output more useful (and terminate in a reasonable time), GN will not
+ revisit sub-paths previously known to lead to the target.
+
+```
+
### **Options**
```
--all
- Prints all paths found rather than just the first one. Public paths
- will be printed first in order of increasing length, followed by
- non-public paths in order of increasing length.
+ Prints all "interesting" paths found rather than just the first
+ one. Public paths will be printed first in order of increasing
+ length, followed by non-public paths in order of increasing length.
--public
Considers only public paths. Can't be used with --with-data.
@@ -3611,13 +3621,13 @@
```
This value should be used to indicate the desired architecture for
the primary objects of the build. It will match the cpu architecture
- of the default toolchain.
+ of the default toolchain, but not necessarily the current toolchain.
In many cases, this is the same as "host_cpu", but in the case
- of cross-compiles, this can be set to something different. This
- value is different from "current_cpu" in that it can be referenced
- from inside any toolchain. This value can also be ignored if it is
- not needed or meaningful for a project.
+ of cross-compiles, this can be set to something different. This
+ value is different from "current_cpu" in that it does not change
+ based on the current toolchain. When writing rules, "current_cpu"
+ should be used rather than "target_cpu" most of the time.
This value is not used internally by GN for any purpose, so it
may be set to whatever value is needed for the build.
@@ -5949,8 +5959,8 @@
When a tool produces more than one output, only the first output
is considered. For example, a shared library target may produce a
.dll and a .lib file on Windows. Only the .dll file will be considered
- a runtime dependency. This applies only to linker tools, scripts and
- copy steps with multiple outputs will also get all outputs listed.
+ a runtime dependency. This applies only to linker tools. Scripts and
+ copy steps with multiple outputs will get all outputs listed.
```
diff --git a/tools/gn/visual_studio_writer.cc b/tools/gn/visual_studio_writer.cc
index 7dedd4d..401782f 100644
--- a/tools/gn/visual_studio_writer.cc
+++ b/tools/gn/visual_studio_writer.cc
@@ -8,6 +8,7 @@
#include <iterator>
#include <map>
#include <memory>
+#include <queue>
#include <set>
#include <string>
@@ -18,6 +19,7 @@
#include "tools/gn/commands.h"
#include "tools/gn/config.h"
#include "tools/gn/config_values_extractors.h"
+#include "tools/gn/deps_iterator.h"
#include "tools/gn/filesystem_utils.h"
#include "tools/gn/label_pattern.h"
#include "tools/gn/parse_tree.h"
@@ -163,6 +165,46 @@
return base::StringPiece();
}
+bool FilterTargets(const BuildSettings* build_settings,
+ Builder* builder,
+ const std::string& dir_filters,
+ std::vector<const Target*>* targets,
+ Err* err) {
+ if (dir_filters.empty()) {
+ *targets = builder->GetAllResolvedTargets();
+ return true;
+ }
+
+ std::vector<LabelPattern> filters;
+ if (!commands::FilterPatternsFromString(build_settings, dir_filters, &filters,
+ err))
+ return false;
+
+ commands::FilterTargetsByPatterns(builder->GetAllResolvedTargets(), filters,
+ targets);
+
+ std::set<Label> labels;
+ std::queue<const Target*> to_process;
+ for (const Target* target : *targets) {
+ labels.insert(target->label());
+ to_process.push(target);
+ }
+
+ while (!to_process.empty()) {
+ const Target* target = to_process.front();
+ to_process.pop();
+ for (const auto& pair : target->GetDeps(Target::DEPS_ALL)) {
+ if (labels.find(pair.label) == labels.end()) {
+ targets->push_back(pair.ptr);
+ to_process.push(pair.ptr);
+ labels.insert(pair.label);
+ }
+ }
+ }
+
+ return true;
+}
+
} // namespace
VisualStudioWriter::SolutionEntry::SolutionEntry(const std::string& _name,
@@ -233,18 +275,8 @@
const std::string& dir_filters,
Err* err) {
std::vector<const Target*> targets;
- if (dir_filters.empty()) {
- targets = builder->GetAllResolvedTargets();
- } else {
- std::vector<LabelPattern> filters;
- if (!commands::FilterPatternsFromString(build_settings, dir_filters,
- &filters, err)) {
- return false;
- }
-
- commands::FilterTargetsByPatterns(builder->GetAllResolvedTargets(), filters,
- &targets);
- }
+ if (!FilterTargets(build_settings, builder, dir_filters, &targets, err))
+ return false;
const char* config_platform = "Win32";