Index: tools/gn/visual_studio_writer.cc |
diff --git a/tools/gn/visual_studio_writer.cc b/tools/gn/visual_studio_writer.cc |
index 7748fbe19df46326e53f19630d2b23ee04b7f568..27fbb8d9d1fedd2e1162dccc53f64c7e8e771f88 100644 |
--- a/tools/gn/visual_studio_writer.cc |
+++ b/tools/gn/visual_studio_writer.cc |
@@ -11,6 +11,7 @@ |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
+#include "base/strings/string_split.h" |
#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "tools/gn/builder.h" |
@@ -214,6 +215,8 @@ VisualStudioWriter::~VisualStudioWriter() { |
bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings, |
Builder* builder, |
Version version, |
+ const std::string& sln_name, |
+ const std::string& dir_filters, |
Err* err) { |
std::vector<const Target*> targets = builder->GetAllResolvedTargets(); |
@@ -221,6 +224,27 @@ bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings, |
writer.projects_.reserve(targets.size()); |
writer.folders_.reserve(targets.size()); |
+ std::vector<std::string> filters; |
+ if (!dir_filters.empty()) { |
+ filters = base::SplitString(dir_filters, ";", base::TRIM_WHITESPACE, |
+ base::SPLIT_WANT_NONEMPTY); |
+ |
+ // Git Bash and other MSYS shells convert POSIX paths before passing them to |
+ // native Windows programs. Leading slash is trimmed in paths like |
+ // "//chrome" or "/c:/foo" making them "/chrome" and "c:/foo". Convert such |
+ // paths back to GN format so filters can be compared to other GN paths. |
+ // See: http://www.mingw.org/wiki/Posix_path_conversion |
+ for (std::string& filter : filters) { |
+ if (filter.size() > 1 && |
+ (filter[0] == '/' && |
brettw
2016/02/24 22:11:26
This seems complicated and isn't something we do a
Tomasz Moniuszko
2016/02/25 13:28:20
Many thanks for this hint. I was thinking about us
|
+ !(filter[1] == '/' || |
+ filter.size() > 2 && base::IsAsciiAlpha(filter[1]) && |
+ filter[2] == ':') || |
+ base::IsAsciiAlpha(filter[0]) && filter[1] == ':')) |
+ filter = '/' + filter; |
+ } |
+ } |
+ |
for (const Target* target : targets) { |
// Skip actions and groups. |
if (target->output_type() == Target::GROUP || |
@@ -230,6 +254,19 @@ bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings, |
continue; |
} |
+ if (!filters.empty()) { |
+ bool exclude = true; |
+ for (const std::string& filter : filters) { |
+ if (base::StartsWith(target->label().dir().value(), filter, |
+ base::CompareCase::SENSITIVE)) { |
+ exclude = false; |
+ break; |
+ } |
+ } |
+ if (exclude) |
+ continue; |
+ } |
+ |
if (!writer.WriteProjectFiles(target, err)) |
return false; |
} |
@@ -247,7 +284,7 @@ bool VisualStudioWriter::RunAndWriteFiles(const BuildSettings* build_settings, |
}); |
writer.ResolveSolutionFolders(); |
- return writer.WriteSolutionFile(err); |
+ return writer.WriteSolutionFile(sln_name, err); |
} |
bool VisualStudioWriter::WriteProjectFiles(const Target* target, Err* err) { |
@@ -579,9 +616,11 @@ void VisualStudioWriter::WriteFiltersFileContents(std::ostream& out, |
project.Text(files_out.str()); |
} |
-bool VisualStudioWriter::WriteSolutionFile(Err* err) { |
+bool VisualStudioWriter::WriteSolutionFile(const std::string& sln_name, |
+ Err* err) { |
+ std::string name = sln_name.empty() ? "all" : sln_name; |
SourceFile sln_file = build_settings_->build_dir().ResolveRelativeFile( |
- Value(nullptr, "all.sln"), err); |
+ Value(nullptr, name + ".sln"), err); |
if (sln_file.is_null()) |
return false; |
@@ -694,7 +733,8 @@ void VisualStudioWriter::ResolveSolutionFolders() { |
else if (root_folder_path_[i] != folder_path[i]) |
break; |
} |
- if (i == max_common_length) |
+ if (i == max_common_length && |
+ (i == folder_path.size() || IsSlash(folder_path[i]))) |
common_prefix_len = max_common_length; |
if (common_prefix_len < root_folder_path_.size()) { |
if (IsSlash(root_folder_path_[common_prefix_len - 1])) |